diff --git a/examples/c++/solid_mechanics_cohesive_model/cohesive_damage_extrinsic/cohesive_damage_extrinsic.cc b/examples/c++/solid_mechanics_cohesive_model/cohesive_damage_extrinsic/cohesive_damage_extrinsic.cc
index c21fe8761..4dfaa7ae2 100644
--- a/examples/c++/solid_mechanics_cohesive_model/cohesive_damage_extrinsic/cohesive_damage_extrinsic.cc
+++ b/examples/c++/solid_mechanics_cohesive_model/cohesive_damage_extrinsic/cohesive_damage_extrinsic.cc
@@ -1,112 +1,113 @@
 /**
  * Copyright (©) 2012-2023 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * This file is part of Akantu
  *
  * Akantu is free software: you can redistribute it and/or modify it under the
  * terms of the GNU Lesser General Public License as published by the Free
  * Software Foundation, either version 3 of the License, or (at your option) any
  * later version.
  *
  * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
  * details.
  *
  * You should have received a copy of the GNU Lesser General Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  */
 
 /* -------------------------------------------------------------------------- */
 #include "element_group.hh"
 #include "mesh_iterators.hh"
 #include "non_linear_solver.hh"
-#include "solid_mechanics_model_cohesive.hh"
+#include "solid_mechanics_model_cohesive_damage.hh"
 /* -------------------------------------------------------------------------- */
 #include <iostream>
 /* -------------------------------------------------------------------------- */
 
 using namespace akantu;
 
 /* -------------------------------------------------------------------------- */
 int main(int argc, char * argv[]) {
   initialize("material.dat", argc, argv);
 
   const Int spatial_dimension = 2;
   const Int max_steps = 1;
 
   Real L = 0.4;
   Real eps0 = 1e-1;
 
   Mesh mesh(spatial_dimension);
   mesh.read("triangle.msh");
 
-  SolidMechanicsModelCohesive model(mesh);
+  SolidMechanicsModelCohesiveDamage model(mesh);
 
   /// model initialization
   model.initFull(_analysis_method = _explicit_lumped_mass
                  ,_is_extrinsic = true);
 
   Real time_step = model.getStableTimeStep() * 0.05;
   model.setTimeStep(time_step);
   std::cout << "Time step: " << time_step << std::endl;
 
   model.getElementInserter().setLimit(_x, 0.5*L-0.1, 0.5*L+0.1);
   model.updateAutomaticInsertion();
 
 
 
   model.applyBC(BC::Dirichlet::FixedValue(0., _x), "left");
   model.applyBC(BC::Dirichlet::FixedValue(0., _y), "point");
 
   Int nb_nodes = mesh.getNbNodes();
 
   Array<Real> & position = mesh.getNodes();
   Array<Real> & velocity = model.getVelocity();
 
   for (Int n = 0; n < nb_nodes; ++n) {
     velocity(n,0) = eps0*position(n,0);
   }
 
   model.setBaseName("cohesive");
   model.addDumpFieldVector("displacement");
 //  model.addDumpField("velocity");
 //  model.addDumpField("acceleration");
   model.addDumpField("stress");
   model.addDumpField("grad_u");
   model.addDumpField("external_force");
   model.addDumpField("internal_force");
   model.dump();
 
   /// Main loop
   for (Int s = 1; s <= max_steps; ++s) {
     model.applyBC(BC::Dirichlet::IncrementValue(time_step*eps0*L, _x), "right");
     // debug::setDebugLevel(dblDump);
     debug::setDebugLevel(dblInfo);
     model.checkCohesiveInsertion(); /// TODO : replace by a function which does not interpolate stress
     model.solveStep();
     model.computeLagrangeMultiplier();
+    model.computeDamage();
     model.checkCohesiveStress();
     debug::setDebugLevel(dblWarning);
 
     if (s % 1 == 0) {
       model.dump();
       std::cout << "passing step " << s << "/" << max_steps << std::endl;
     }
   }
 
   Real E = model.getEnergy("potential");
 
   std::cout << "Elastic energy : " << E << std::endl;
 
 //  if (Ed < Edt * 0.999 || Ed > Edt * 1.001 || std::isnan(Ed)) {
 //    std::cout << "The dissipated energy is incorrect" << std::endl;
 //    return EXIT_FAILURE;
 //  }
 
   finalize();
 
   return EXIT_SUCCESS;
 }
 
diff --git a/examples/c++/solid_mechanics_cohesive_model/cohesive_damage_extrinsic/cohesive_damage_extrinsic.py b/examples/c++/solid_mechanics_cohesive_model/cohesive_damage_extrinsic/cohesive_damage_extrinsic.py
index f23324eb0..4ef34df3d 100644
--- a/examples/c++/solid_mechanics_cohesive_model/cohesive_damage_extrinsic/cohesive_damage_extrinsic.py
+++ b/examples/c++/solid_mechanics_cohesive_model/cohesive_damage_extrinsic/cohesive_damage_extrinsic.py
@@ -1,203 +1,204 @@
 #!/usr/bin/env python3
 __copyright__ = (
     "Copyright (©) 2019-2023 EPFL (Ecole Polytechnique Fédérale de Lausanne)"
     "Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)"
 )
 __license__ = "LGPLv3"
 
 
 import sys
 sys.path.insert(0,"/home/ble/developpement/akantu/build/buildCZMDamageDebug/python")
 print(sys.path)
 
 import akantu as aka
 import numpy as np
 import matplotlib.pyplot as plt
 
 from czm_damage import *
 					
 def set_dumpers(model):
     model.setBaseName("cohesive")
     model.addDumpFieldVector("displacement")
     model.addDumpFieldVector("external_force")
     model.addDumpField("strain")
     model.addDumpField("stress")
     model.addDumpField("blocked_dofs")
 
     model.setBaseNameToDumper("cohesive elements", "cohesive")
     model.addDumpFieldVectorToDumper("cohesive elements", "displacement")
     model.addDumpFieldToDumper("cohesive elements", "damage")
     model.addDumpFieldVectorToDumper("cohesive elements", "tractions")
     model.addDumpFieldVectorToDumper("cohesive elements", "opening")
 
 
 class FixedDisplacement (aka.DirichletFunctor):
     '''
         Fix the displacement at its current value
     '''
 
     def __init__(self, axis, vel):
         super().__init__(axis)
         self.axis = axis
         self.time = 0
         self.vel = vel
 
     def set_time(self, t):
         self.time = t
 
     def get_imposed_disp(self):
         return self.vel*self.time
         
     def __call__(self, node, flags, disp, coord):
         # sets the blocked dofs vector to true in the desired axis
         flags[int(self.axis)] = True
         disp[int(self.axis)] = self.get_imposed_disp()
         
 def solve(material_file, mesh_file):
     aka.parseInput(material_file)
     spatial_dimension = 2
     L = 0.4
     
     # -------------------------------------------------------------------------
     # Initialization
     # -------------------------------------------------------------------------
     mesh = aka.Mesh(spatial_dimension)
     mesh.read(mesh_file)
 
-    model = aka.SolidMechanicsModelCohesive(mesh)
+    model = aka.SolidMechanicsModelCohesiveDamage(mesh)
     model.getElementInserter().setLimit(aka._x, 0.5*L-0.1, 0.5*L+0.1);
 
     model.initFull(_analysis_method=aka._static, _is_extrinsic=True)
     
     # Initilize a new solver (explicit Newmark with lumped mass)
     model.initNewSolver(aka._explicit_lumped_mass)
     # Dynamic insertion of cohesive elements
     model.updateAutomaticInsertion()
                        
     set_dumpers(model)
 
 
     E = model.getMaterial("steel").getReal("E")
     Gc = model.getMaterial("cohesive").getReal("G_c")
     sigc = model.getMaterial("cohesive").getReal("sigma_c")
     wc = 2.*Gc/sigc
     w0 = (sigc/E)*L
     k = model.getMaterial("cohesive").getReal("k")
     g = degradation_function_linear_czm()
     h = softening_function_linear_czm(k,sigc,Gc)
     updater = damage_updater(Gc,sigc,k,g,h)
 
     imposed_disp = [0.]
     reaction_force = [0.]
     E_pot = []
     E_kin = []
     E_dis = []
     E_rev = []
     E_con = []
 
     U = 0.
     F = 0.
         
     # -------------------------------------------------------------------------
     # Initial and boundary conditions
     # -------------------------------------------------------------------------
     eps0dot = 5e-1
     tc = w0/(eps0dot*L)
     functor_r = FixedDisplacement(aka._x, L*eps0dot)
     functor_r.set_time(tc)
     model.applyBC(functor_r, 'right')
 
     model.applyBC(aka.FixedValue(0.0, aka._x), "left")
     model.applyBC(aka.FixedValue(0.0, aka._y), "point")
     
     nodes = model.getMesh().getNodes()
     disp_field = np.zeros(nodes.shape)
     disp_field[:, 0] = nodes[:, 0]*(w0/L)
     model.getDisplacement()[:] = disp_field
     vel_field = np.zeros(nodes.shape)
     vel_field[:, 0] = nodes[:, 0]*eps0dot
     model.getVelocity()[:] = vel_field
     
     model.getExternalForce()[:] = 0
     model.assembleInternalForces()                           
                                                   
     d = model.getMaterial("cohesive").getInternalReal("czm_damage")(aka._segment_2)
     lda = model.getMaterial("cohesive").getInternalReal("lambda")(aka._segment_2)
     Fint = model.getInternalForce() 
 
     nodes_right = mesh.getElementGroup("right").getNodeGroup().getNodes()    
     
     U = functor_r.get_imposed_disp()
     imposed_disp.append(U)    
     F = -np.sum(Fint[nodes_right,0])
     reaction_force.append(F)
     
     Ep = model.getEnergy("potential")
     Ek = model.getEnergy("kinetic")
     Ed = model.getEnergy("dissipated")
     Er = model.getEnergy("reversible")
     
     E_pot.append(Ep)
     E_kin.append(Ek)
     E_dis.append(Ed)
     E_rev.append(Er)
     
     model.dump()
     #model.dump("cohesive elements")
             
-    maxsteps = 2
+    maxsteps = 1
     dt = model.getStableTimeStep()*0.1
     # choose the timestep
     model.setTimeStep(dt)
 
     time = tc
     for i in range(0, maxsteps):
         print("---- step {0}/{1}".format(i, maxsteps))
         time+=dt
         functor_r.set_time(time)
         # fix displacements of the right boundary
         model.applyBC(functor_r, 'right')
         d_previous = model.getMaterial("cohesive").getInternalReal("czm_damage")(aka._segment_2).copy()        
         #print("lda = ",lda)
         model.solveStep('explicit_lumped')
         model.computeLagrangeMultiplier()
-        d[:] = updater.update_d(d_previous,lda)
-        #print("d = ",d)
+        #d[:] = updater.update_d(d_previous,lda)
+        model.computeDamage()
+        # print("d = ",d)
 
         model.checkCohesiveInsertion()
         
         U = functor_r.get_imposed_disp()
         imposed_disp.append(U)    
         F = -np.sum(Fint[nodes_right,0])
         reaction_force.append(F)
 
         Ep = model.getEnergy("potential")
         Ek = model.getEnergy("kinetic")
         Ed = model.getEnergy("dissipated")
         Er = model.getEnergy("reversible")
     
         E_pot.append(Ep)
         E_kin.append(Ek)
         E_dis.append(Ed)
         E_rev.append(Er)
         
         model.dump()
         #model.dump("cohesive elements")
 
     plt.plot(imposed_disp,reaction_force,'-o')
     plt.plot([0., w0, wc], [0., sigc*L, 0.], 'k-o')
     plt.show()
 
 
 # -----------------------------------------------------------------------------
 # main
 # -----------------------------------------------------------------------------
 def main():
     mesh_file = "triangle.msh"
     material_file = "material.dat"
     solve(material_file, mesh_file)
 
 
 # -----------------------------------------------------------------------------
 if __name__ == "__main__":
     main()
diff --git a/packages/cohesive_element.cmake b/packages/cohesive_element.cmake
index 2f21f8004..f498a5601 100644
--- a/packages/cohesive_element.cmake
+++ b/packages/cohesive_element.cmake
@@ -1,86 +1,90 @@
-#===============================================================================
+	#===============================================================================
 # Copyright (©) 2012-2023 EPFL (Ecole Polytechnique Fédérale de Lausanne)
 # Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
 #
 # This file is part of Akantu
 # 
 # Akantu is free software: you can redistribute it and/or modify it under the
 # terms of the GNU Lesser General Public License as published by the Free
 # Software Foundation, either version 3 of the License, or (at your option) any
 # later version.
 # 
 # Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
 # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
 # A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
 # details.
 # 
 # You should have received a copy of the GNU Lesser General Public License along
 # with Akantu. If not, see <http://www.gnu.org/licenses/>.
 #
 #===============================================================================
 
 
 package_declare(cohesive_element DEFAULT ON
   DESCRIPTION "Use cohesive_element package of Akantu"
   DEPENDS solid_mechanics)
 
 package_declare_sources(cohesive_element
   fe_engine/cohesive_element.hh
   fe_engine/fe_engine_template_cohesive.cc
   fe_engine/shape_cohesive.hh
   fe_engine/shape_cohesive_inline_impl.hh
 
   mesh_utils/cohesive_element_inserter.cc
   mesh_utils/cohesive_element_inserter.hh
   mesh_utils/cohesive_element_inserter_inline_impl.hh
   mesh_utils/cohesive_element_inserter_parallel.cc
   mesh_utils/cohesive_element_inserter_helper.cc
   mesh_utils/cohesive_element_inserter_helper.hh
 
   model/solid_mechanics/solid_mechanics_model_cohesive/fragment_manager.cc
   model/solid_mechanics/solid_mechanics_model_cohesive/fragment_manager.hh
   model/solid_mechanics/solid_mechanics_model_cohesive/material_selector_cohesive.cc
   model/solid_mechanics/solid_mechanics_model_cohesive/material_selector_cohesive.hh
   model/solid_mechanics/solid_mechanics_model_cohesive/materials/cohesive_internal_field.hh
   model/solid_mechanics/solid_mechanics_model_cohesive/materials/cohesive_internal_field_tmpl.hh
 
   model/solid_mechanics/solid_mechanics_model_cohesive/materials/constitutive_laws/material_cohesive_bilinear.cc
   model/solid_mechanics/solid_mechanics_model_cohesive/materials/constitutive_laws/material_cohesive_bilinear.hh
   model/solid_mechanics/solid_mechanics_model_cohesive/materials/constitutive_laws/material_cohesive_exponential.cc
   model/solid_mechanics/solid_mechanics_model_cohesive/materials/constitutive_laws/material_cohesive_exponential.hh
   model/solid_mechanics/solid_mechanics_model_cohesive/materials/constitutive_laws/material_cohesive_linear.cc
   model/solid_mechanics/solid_mechanics_model_cohesive/materials/constitutive_laws/material_cohesive_linear.hh
   model/solid_mechanics/solid_mechanics_model_cohesive/materials/constitutive_laws/material_cohesive_linear_fatigue.cc
   model/solid_mechanics/solid_mechanics_model_cohesive/materials/constitutive_laws/material_cohesive_linear_fatigue.hh
   model/solid_mechanics/solid_mechanics_model_cohesive/materials/constitutive_laws/material_cohesive_linear_friction.cc
   model/solid_mechanics/solid_mechanics_model_cohesive/materials/constitutive_laws/material_cohesive_linear_friction.hh
   model/solid_mechanics/solid_mechanics_model_cohesive/materials/constitutive_laws/material_cohesive_linear_inline_impl.hh
   model/solid_mechanics/solid_mechanics_model_cohesive/materials/constitutive_laws/material_cohesive_linear_uncoupled.cc
   model/solid_mechanics/solid_mechanics_model_cohesive/materials/constitutive_laws/material_cohesive_linear_uncoupled.hh
 
   model/solid_mechanics/solid_mechanics_model_cohesive/materials/material_cohesive.cc
   model/solid_mechanics/solid_mechanics_model_cohesive/materials/material_cohesive.hh
   model/solid_mechanics/solid_mechanics_model_cohesive/materials/material_cohesive_inline_impl.hh
 
   model/solid_mechanics/solid_mechanics_model_cohesive/materials/material_cohesive_damage.cc
   model/solid_mechanics/solid_mechanics_model_cohesive/materials/material_cohesive_damage.hh
   model/solid_mechanics/solid_mechanics_model_cohesive/materials/material_cohesive_damage_inline_impl.hh
   model/solid_mechanics/solid_mechanics_model_cohesive/materials/material_cohesive_damage_intrinsic.cc
   model/solid_mechanics/solid_mechanics_model_cohesive/materials/material_cohesive_damage_intrinsic.hh  
   model/solid_mechanics/solid_mechanics_model_cohesive/materials/material_cohesive_damage_intrinsic_inline_impl.hh
   model/solid_mechanics/solid_mechanics_model_cohesive/materials/material_cohesive_damage_extrinsic.cc
   model/solid_mechanics/solid_mechanics_model_cohesive/materials/material_cohesive_damage_extrinsic.hh 
   model/solid_mechanics/solid_mechanics_model_cohesive/materials/material_cohesive_damage_extrinsic_inline_impl.hh
   model/solid_mechanics/solid_mechanics_model_cohesive/materials/material_bulk_damage.cc
   model/solid_mechanics/solid_mechanics_model_cohesive/materials/material_bulk_damage.hh
   model/solid_mechanics/solid_mechanics_model_cohesive/materials/material_bulk_damage_inline_impl.hh
   model/solid_mechanics/solid_mechanics_model_cohesive/materials/material_clip.cc
   model/solid_mechanics/solid_mechanics_model_cohesive/materials/material_clip.hh
-  model/solid_mechanics/solid_mechanics_model_cohesive/materials/material_clip_inline_impl.hh
+  #model/solid_mechanics/solid_mechanics_model_cohesive/materials/material_clip_inline_impl.hh
         
   model/solid_mechanics/solid_mechanics_model_cohesive/solid_mechanics_model_cohesive.cc
   model/solid_mechanics/solid_mechanics_model_cohesive/solid_mechanics_model_cohesive.hh
   model/solid_mechanics/solid_mechanics_model_cohesive/solid_mechanics_model_cohesive_inline_impl.hh
   model/solid_mechanics/solid_mechanics_model_cohesive/solid_mechanics_model_cohesive_parallel.cc
+  
+  model/solid_mechanics/solid_mechanics_model_cohesive/solid_mechanics_model_cohesive_damage.cc
+  model/solid_mechanics/solid_mechanics_model_cohesive/solid_mechanics_model_cohesive_damage.hh
+  
   )
 
diff --git a/python/CMakeLists.txt b/python/CMakeLists.txt
index 603658d7a..e32b27a2b 100644
--- a/python/CMakeLists.txt
+++ b/python/CMakeLists.txt
@@ -1,139 +1,140 @@
 #===============================================================================
 # Copyright (©) 2014-2023 EPFL (Ecole Polytechnique Fédérale de Lausanne)
 # Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
 #
 # This file is part of Akantu
 # 
 # Akantu is free software: you can redistribute it and/or modify it under the
 # terms of the GNU Lesser General Public License as published by the Free
 # Software Foundation, either version 3 of the License, or (at your option) any
 # later version.
 # 
 # Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
 # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
 # A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
 # details.
 # 
 # You should have received a copy of the GNU Lesser General Public License along
 # with Akantu. If not, see <http://www.gnu.org/licenses/>.
 #
 #===============================================================================
 
 
 if(NOT SKBUILD)
   package_get_all_include_directories(
     AKANTU_LIBRARY_INCLUDE_DIRS
     )
 
   package_get_all_external_informations(
     PRIVATE_INCLUDE AKANTU_PRIVATE_EXTERNAL_INCLUDE_DIR
     INTERFACE_INCLUDE AKANTU_INTERFACE_EXTERNAL_INCLUDE_DIR
     LIBRARIES AKANTU_EXTERNAL_LIBRARIES
     )
 endif()
 
 set(PYAKANTU_SRCS
   py_aka_common.cc
   py_aka_error.cc
   py_akantu.cc
   py_boundary_conditions.cc
   py_constitutive_law.cc
   py_constitutive_law_selector.cc
   py_dof_manager.cc
   py_dumpable.cc
   py_fe_engine.cc
   py_group_manager.cc
   py_integration_scheme.cc
   py_mesh.cc
   py_model.cc
   py_parser.cc
   py_solver.cc
   )
 
 package_is_activated(solid_mechanics _is_activated)
 if (_is_activated)
   list(APPEND PYAKANTU_SRCS
     py_solid_mechanics_model.cc
     py_material.cc
     )
 endif()
 
 package_is_activated(cohesive_element _is_activated)
 if (_is_activated)
   list(APPEND PYAKANTU_SRCS
     py_solid_mechanics_model_cohesive.cc
+    py_solid_mechanics_model_cohesive_damage.cc
     py_fragment_manager.cc
     )
 endif()
 
 package_is_activated(diffusion _is_activated)
 if (_is_activated)
   list(APPEND PYAKANTU_SRCS
     py_heat_transfer_model.cc
     )
 endif()
 
 
 package_is_activated(contact_mechanics _is_activated)
 if(_is_activated)
   list(APPEND PYAKANTU_SRCS
     py_contact_mechanics_model.cc
     py_model_couplers.cc
     )
 endif()
 
 package_is_activated(phase_field _is_activated)
 if (_is_activated)
   list(APPEND PYAKANTU_SRCS
     py_phase_field_model.cc
     )
 endif()
 
 package_is_activated(structural_mechanics _is_activated)
 if (_is_activated)
   list(APPEND PYAKANTU_SRCS
     py_structural_mechanics_model.cc
     )
 endif()
 
 pybind11_add_module(py11_akantu ${PYAKANTU_SRCS})
 
 # to avoid compilation warnings from pybind11
 target_include_directories(py11_akantu
   SYSTEM BEFORE
   PRIVATE ${PYBIND11_INCLUDE_DIR}
   PRIVATE ${pybind11_INCLUDE_DIR}
   PRIVATE ${Python_INCLUDE_DIRS})
 
 target_link_libraries(py11_akantu PUBLIC akantu)
 set_target_properties(py11_akantu PROPERTIES
   DEBUG_POSTFIX ""
   LIBRARY_OUTPUT_DIRECTORY akantu)
 
 if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
   target_compile_options(py11_akantu PUBLIC -fsized-deallocation)
 endif()
 
 
 file(COPY akantu DESTINATION ${CMAKE_CURRENT_BINARY_DIR})
 
 if(NOT Python_MAJOR)
   set(Python_VERSION_MAJOR ${PYTHON_VERSION_MAJOR})
   set(Python_VERSION_MINOR ${PYTHON_VERSION_MINOR})
 endif()
 
 if(NOT SKBUILD)
   set(_python_install_dir
     ${CMAKE_INSTALL_LIBDIR}/python${Python_VERSION_MAJOR}.${Python_VERSION_MINOR}/site-packages/akantu)
 else()
   set(_python_install_dir python/akantu)
 endif()
 
 install(TARGETS py11_akantu
   LIBRARY DESTINATION ${_python_install_dir})
 
 if(NOT SKBUILD)
   install(DIRECTORY akantu
     DESTINATION ${_python_install_dir}
     FILES_MATCHING PATTERN "*.py")
 endif()
diff --git a/python/py_akantu.cc b/python/py_akantu.cc
index 245d02bd6..0d11240ac 100644
--- a/python/py_akantu.cc
+++ b/python/py_akantu.cc
@@ -1,169 +1,171 @@
 /**
  * Copyright (©) 2018-2023 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * This file is part of Akantu
  *
  * Akantu is free software: you can redistribute it and/or modify it under the
  * terms of the GNU Lesser General Public License as published by the Free
  * Software Foundation, either version 3 of the License, or (at your option) any
  * later version.
  *
  * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
  * details.
  *
  * You should have received a copy of the GNU Lesser General Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  */
 
 /* -------------------------------------------------------------------------- */
 #include "aka_config.hh"
 // for NLSNotConvergedException
 #include "non_linear_solver.hh"
 /* -------------------------------------------------------------------------- */
 #include "py_aka_common.hh"
 #include "py_aka_error.hh"
 #include "py_boundary_conditions.hh"
 #include "py_constitutive_law.hh"
 #include "py_constitutive_law_selector.hh"
 #include "py_dof_manager.hh"
 #include "py_dumpable.hh"
 #include "py_fe_engine.hh"
 #include "py_group_manager.hh"
 #include "py_integration_scheme.hh"
 #include "py_mesh.hh"
 #include "py_model.hh"
 #include "py_parser.hh"
 #include "py_solver.hh"
 
 #if defined(AKANTU_SOLID_MECHANICS)
 #include "py_material.hh"
 #include "py_solid_mechanics_model.hh"
 #endif
 
 #if defined(AKANTU_DIFFUSION)
 #include "py_heat_transfer_model.hh"
 #endif
 
 #if defined(AKANTU_COHESIVE_ELEMENT)
 #include "py_fragment_manager.hh"
 #include "py_solid_mechanics_model_cohesive.hh"
+#include "py_solid_mechanics_model_cohesive_damage.hh"
 #endif
 
 #if defined(AKANTU_CONTACT_MECHANICS)
 #include "py_contact_mechanics_model.hh"
 #include "py_model_couplers.hh"
 #endif
 
 #if defined(AKANTU_PHASE_FIELD)
 #include "py_phase_field_model.hh"
 #endif
 
 #if defined(AKANTU_STRUCTURAL_MECHANICS)
 #include "py_structural_mechanics_model.hh"
 #endif
 
 /* -------------------------------------------------------------------------- */
 #include <aka_error.hh>
 /* -------------------------------------------------------------------------- */
 #include <pybind11/pybind11.h>
 /* -------------------------------------------------------------------------- */
 #include <iostream>
 /* -------------------------------------------------------------------------- */
 
 namespace py = pybind11;
 
 namespace akantu {
 void register_all(pybind11::module & mod) {
   register_initialize(mod);
   register_enums(mod);
   register_error(mod);
   register_functions(mod);
   register_parser(mod);
   register_solvers(mod);
 
   register_dumpable(mod);
   register_group_manager(mod);
   register_mesh(mod);
 
   register_fe_engine(mod);
 
   register_integration_schemes(mod);
   register_dof_manager(mod);
 
   register_boundary_conditions(mod);
   register_model(mod);
   register_constitutive_law_selector(mod);
   register_constitutive_law_internal_handler(mod);
 
 #if defined(AKANTU_DIFFUSION)
   register_heat_transfer_model(mod);
 #endif
 
 #if defined(AKANTU_SOLID_MECHANICS)
   register_solid_mechanics_model(mod);
   register_material(mod);
 #endif
 
 #if defined(AKANTU_COHESIVE_ELEMENT)
   register_solid_mechanics_model_cohesive(mod);
+  register_solid_mechanics_model_cohesive_damage(mod);
   register_fragment_manager(mod);
 #endif
 
 #if defined(AKANTU_STRUCTURAL_MECHANICS)
   register_structural_mechanics_model(mod);
 #endif
 
 #if defined(AKANTU_CONTACT_MECHANICS)
   register_contact_mechanics_model(mod);
   register_model_couplers(mod);
 #endif
 
 #if defined(AKANTU_PHASE_FIELD)
   register_phase_field_model(mod);
   register_phase_field_coupler(mod);
 #endif
 }
 } // namespace akantu
 
 /* -------------------------------------------------------------------------- */
 /* -------------------------------------------------------------------------- */
 PYBIND11_MODULE(py11_akantu, mod) {
   mod.doc() = "Akantu python interface";
 
   static py::exception<akantu::debug::Exception> akantu_exception(mod,
                                                                   "Exception");
 
   static py::exception<akantu::debug::NLSNotConvergedException>
       akantu_exception_nls_not_converged(mod, "NLSNotConvergedException");
 
   py::register_exception_translator([](std::exception_ptr ptr) {
     try {
       if (ptr) {
         std::rethrow_exception(ptr);
       }
     } catch (akantu::debug::NLSNotConvergedException & e) {
       akantu_exception_nls_not_converged(e.info().c_str());
     } catch (akantu::debug::Exception & e) {
       if (akantu::debug::debugger.printBacktrace()) {
         akantu::debug::printBacktrace();
       }
       akantu_exception(e.info().c_str());
     }
   });
 
   akantu::register_all(mod);
 
   mod.def("has_mpi",
           []() {
 #if defined(AKANTU_USE_MPI)
             return true;
 #else
             return false;
 #endif
           })
       .def("getVersion", &akantu::getVersion);
 
 } // Module akantu
diff --git a/python/py_solid_mechanics_model_cohesive.cc b/python/py_solid_mechanics_model_cohesive.cc
index 17ddf99a6..68293f042 100644
--- a/python/py_solid_mechanics_model_cohesive.cc
+++ b/python/py_solid_mechanics_model_cohesive.cc
@@ -1,126 +1,119 @@
 /**
  * Copyright (©) 2020-2023 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * This file is part of Akantu
  *
  * Akantu is free software: you can redistribute it and/or modify it under the
  * terms of the GNU Lesser General Public License as published by the Free
  * Software Foundation, either version 3 of the License, or (at your option) any
  * later version.
  *
  * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
  * details.
  *
  * You should have received a copy of the GNU Lesser General Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  */
 
 /* -------------------------------------------------------------------------- */
 #include "py_aka_array.hh"
 /* -------------------------------------------------------------------------- */
 #include <element_synchronizer.hh>
 #include <non_linear_solver.hh>
 #include <solid_mechanics_model_cohesive.hh>
 /* -------------------------------------------------------------------------- */
 #include <pybind11/pybind11.h>
 /* -------------------------------------------------------------------------- */
 namespace py = pybind11;
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 
 #define def_function_nocopy(func_name)                                         \
   def(                                                                         \
       #func_name,                                                              \
       [](SolidMechanicsModelCohesive & self) -> decltype(auto) {                       \
         return self.func_name();                                               \
       },                                                                       \
       py::return_value_policy::reference)
 
 #define def_function(func_name)                                                \
   def(#func_name, [](SolidMechanicsModelCohesive & self) -> decltype(auto) {           \
     return self.func_name();                                                   \
   })
 
 void register_solid_mechanics_model_cohesive(py::module & mod) {
   py::class_<CohesiveElementInserter>(mod, "CohesiveElementInserter")
       .def("setLimit", &CohesiveElementInserter::setLimit)
       .def(
           "getCheckFacets",
           [](CohesiveElementInserter & self) -> decltype(auto) {
             return self.getCheckFacets();
           },
           py::return_value_policy::reference)
       .def(
           "getCheckFacets",
           [](CohesiveElementInserter & self, ElementType type,
              GhostType ghost_type) -> decltype(auto) {
             return self.getCheckFacets(type, ghost_type);
           },
           py::arg("type"), py::arg("ghost_type") = _not_ghost,
           py::return_value_policy::reference)
       .def(
           "getInsertionFacets",
           [](CohesiveElementInserter & self) -> decltype(auto) {
             return self.getInsertionFacetsByElement();
           },
           py::return_value_policy::reference)
       .def(
           "getInsertionFacets",
           [](CohesiveElementInserter & self, ElementType type,
              GhostType ghost_type) -> decltype(auto) {
             return self.getInsertionFacets(type, ghost_type);
           },
           py::arg("type"), py::arg("ghost_type") = _not_ghost,
           py::return_value_policy::reference)
 
       .def("addPhysicalSurface", &CohesiveElementInserter::addPhysicalSurface)
       .def("addPhysicalVolume", &CohesiveElementInserter::addPhysicalVolume);
 
   py::class_<SolidMechanicsModelCohesiveOptions, SolidMechanicsModelOptions>(
       mod, "SolidMechanicsModelCohesiveOptions")
       .def(py::init<AnalysisMethod, bool>(),
            py::arg("analysis_method") = _explicit_lumped_mass,
            py::arg("is_extrinsic") = false);
 
   py::class_<SolidMechanicsModelCohesive, SolidMechanicsModel>(
       mod, "SolidMechanicsModelCohesive")
       .def(py::init<Mesh &, Int, const ID &>(), py::arg("mesh"),
            py::arg("spatial_dimension") = _all_dimensions,
            py::arg("id") = "solid_mechanics_model")
       .def(
           "initFull",
           [](SolidMechanicsModel & self, const AnalysisMethod & analysis_method,
              bool is_extrinsic) {
             self.initFull(_analysis_method = analysis_method,
                           _is_extrinsic = is_extrinsic);
           },
           py::arg("_analysis_method") = _explicit_lumped_mass,
           py::arg("_is_extrinsic") = false)
 
       .def("checkCohesiveStress",
            &SolidMechanicsModelCohesive::checkCohesiveStress)
-      .def("checkCohesiveInsertion",
-           &SolidMechanicsModelCohesive::checkCohesiveInsertion)
-      .def("computeLagrangeMultiplier",
-           &SolidMechanicsModelCohesive::computeLagrangeMultiplier)
-      .def("computeDamage",
-           &SolidMechanicsModelCohesive::computeDamage)
       .def("getElementInserter",
            &SolidMechanicsModelCohesive::getElementInserter,
            py::return_value_policy::reference)
       .def("getStressOnFacets", &SolidMechanicsModelCohesive::getStressOnFacets,
            py::arg("type"), py::arg("ghost_type") = _not_ghost,
            py::return_value_policy::reference)
       .def("getTangents", &SolidMechanicsModelCohesive::getTangents,
            py::arg("type"), py::arg("ghost_type") = _not_ghost,
            py::return_value_policy::reference)
-      .def_function_nocopy(getLambda)
       .def("updateAutomaticInsertion",
            &SolidMechanicsModelCohesive::updateAutomaticInsertion);
 }
 
 } // namespace akantu
diff --git a/python/py_solid_mechanics_model_cohesive.cc b/python/py_solid_mechanics_model_cohesive_damage.cc
similarity index 54%
copy from python/py_solid_mechanics_model_cohesive.cc
copy to python/py_solid_mechanics_model_cohesive_damage.cc
index 17ddf99a6..8fab3c850 100644
--- a/python/py_solid_mechanics_model_cohesive.cc
+++ b/python/py_solid_mechanics_model_cohesive_damage.cc
@@ -1,126 +1,87 @@
 /**
  * Copyright (©) 2020-2023 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * This file is part of Akantu
  *
  * Akantu is free software: you can redistribute it and/or modify it under the
  * terms of the GNU Lesser General Public License as published by the Free
  * Software Foundation, either version 3 of the License, or (at your option) any
  * later version.
  *
  * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
  * details.
  *
  * You should have received a copy of the GNU Lesser General Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  */
 
 /* -------------------------------------------------------------------------- */
 #include "py_aka_array.hh"
 /* -------------------------------------------------------------------------- */
 #include <element_synchronizer.hh>
 #include <non_linear_solver.hh>
-#include <solid_mechanics_model_cohesive.hh>
+#include <solid_mechanics_model_cohesive_damage.hh>
 /* -------------------------------------------------------------------------- */
 #include <pybind11/pybind11.h>
 /* -------------------------------------------------------------------------- */
 namespace py = pybind11;
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 
 #define def_function_nocopy(func_name)                                         \
   def(                                                                         \
       #func_name,                                                              \
-      [](SolidMechanicsModelCohesive & self) -> decltype(auto) {                       \
+      [](SolidMechanicsModelCohesiveDamage & self) -> decltype(auto) {                       \
         return self.func_name();                                               \
       },                                                                       \
       py::return_value_policy::reference)
 
 #define def_function(func_name)                                                \
-  def(#func_name, [](SolidMechanicsModelCohesive & self) -> decltype(auto) {           \
+  def(#func_name, [](SolidMechanicsModelCohesiveDamage & self) -> decltype(auto) {           \
     return self.func_name();                                                   \
   })
 
-void register_solid_mechanics_model_cohesive(py::module & mod) {
-  py::class_<CohesiveElementInserter>(mod, "CohesiveElementInserter")
-      .def("setLimit", &CohesiveElementInserter::setLimit)
-      .def(
-          "getCheckFacets",
-          [](CohesiveElementInserter & self) -> decltype(auto) {
-            return self.getCheckFacets();
-          },
-          py::return_value_policy::reference)
-      .def(
-          "getCheckFacets",
-          [](CohesiveElementInserter & self, ElementType type,
-             GhostType ghost_type) -> decltype(auto) {
-            return self.getCheckFacets(type, ghost_type);
-          },
-          py::arg("type"), py::arg("ghost_type") = _not_ghost,
-          py::return_value_policy::reference)
-      .def(
-          "getInsertionFacets",
-          [](CohesiveElementInserter & self) -> decltype(auto) {
-            return self.getInsertionFacetsByElement();
-          },
-          py::return_value_policy::reference)
-      .def(
-          "getInsertionFacets",
-          [](CohesiveElementInserter & self, ElementType type,
-             GhostType ghost_type) -> decltype(auto) {
-            return self.getInsertionFacets(type, ghost_type);
-          },
-          py::arg("type"), py::arg("ghost_type") = _not_ghost,
-          py::return_value_policy::reference)
-
-      .def("addPhysicalSurface", &CohesiveElementInserter::addPhysicalSurface)
-      .def("addPhysicalVolume", &CohesiveElementInserter::addPhysicalVolume);
-
-  py::class_<SolidMechanicsModelCohesiveOptions, SolidMechanicsModelOptions>(
-      mod, "SolidMechanicsModelCohesiveOptions")
-      .def(py::init<AnalysisMethod, bool>(),
-           py::arg("analysis_method") = _explicit_lumped_mass,
-           py::arg("is_extrinsic") = false);
-
-  py::class_<SolidMechanicsModelCohesive, SolidMechanicsModel>(
-      mod, "SolidMechanicsModelCohesive")
+void register_solid_mechanics_model_cohesive_damage(py::module & mod) {
+     
+  py::class_<SolidMechanicsModelCohesiveDamage, SolidMechanicsModel>(
+      mod, "SolidMechanicsModelCohesiveDamage")
       .def(py::init<Mesh &, Int, const ID &>(), py::arg("mesh"),
            py::arg("spatial_dimension") = _all_dimensions,
            py::arg("id") = "solid_mechanics_model")
       .def(
           "initFull",
           [](SolidMechanicsModel & self, const AnalysisMethod & analysis_method,
              bool is_extrinsic) {
             self.initFull(_analysis_method = analysis_method,
                           _is_extrinsic = is_extrinsic);
           },
           py::arg("_analysis_method") = _explicit_lumped_mass,
           py::arg("_is_extrinsic") = false)
 
       .def("checkCohesiveStress",
-           &SolidMechanicsModelCohesive::checkCohesiveStress)
+           &SolidMechanicsModelCohesiveDamage::checkCohesiveStress)
       .def("checkCohesiveInsertion",
-           &SolidMechanicsModelCohesive::checkCohesiveInsertion)
+           &SolidMechanicsModelCohesiveDamage::checkCohesiveInsertion)
       .def("computeLagrangeMultiplier",
-           &SolidMechanicsModelCohesive::computeLagrangeMultiplier)
+           &SolidMechanicsModelCohesiveDamage::computeLagrangeMultiplier)
       .def("computeDamage",
-           &SolidMechanicsModelCohesive::computeDamage)
+           &SolidMechanicsModelCohesiveDamage::computeDamage)
       .def("getElementInserter",
-           &SolidMechanicsModelCohesive::getElementInserter,
+           &SolidMechanicsModelCohesiveDamage::getElementInserter,
            py::return_value_policy::reference)
-      .def("getStressOnFacets", &SolidMechanicsModelCohesive::getStressOnFacets,
+      .def("getStressOnFacets", &SolidMechanicsModelCohesiveDamage::getStressOnFacets,
            py::arg("type"), py::arg("ghost_type") = _not_ghost,
            py::return_value_policy::reference)
-      .def("getTangents", &SolidMechanicsModelCohesive::getTangents,
+      .def("getTangents", &SolidMechanicsModelCohesiveDamage::getTangents,
            py::arg("type"), py::arg("ghost_type") = _not_ghost,
            py::return_value_policy::reference)
       .def_function_nocopy(getLambda)
       .def("updateAutomaticInsertion",
-           &SolidMechanicsModelCohesive::updateAutomaticInsertion);
+           &SolidMechanicsModelCohesiveDamage::updateAutomaticInsertion);
 }
 
 } // namespace akantu
diff --git a/python/py_solid_mechanics_model_cohesive_damage.hh b/python/py_solid_mechanics_model_cohesive_damage.hh
new file mode 100644
index 000000000..83436997f
--- /dev/null
+++ b/python/py_solid_mechanics_model_cohesive_damage.hh
@@ -0,0 +1,33 @@
+/**
+ * Copyright (©) 2020-2023 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ *
+ * This file is part of Akantu
+ *
+ * Akantu is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation, either version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/* -------------------------------------------------------------------------- */
+#include <pybind11/pybind11.h>
+
+#ifndef AKANTU_PY_SOLID_MECHANICS_MODEL_COHESIVE_DAMAGE_HH_
+#define AKANTU_PY_SOLID_MECHANICS_MODEL_COHESIVE_DAMAGE_HH_
+
+namespace akantu {
+
+void register_solid_mechanics_model_cohesive_damage(pybind11::module & mod);
+
+} // namespace akantu
+
+#endif // AKANTU_PY_SOLID_MECHANICS_MODEL_COHESIVE_DAMAGE_HH_
diff --git a/src/model/solid_mechanics/solid_mechanics_model_cohesive/materials/material_cohesive_damage_extrinsic.cc b/src/model/solid_mechanics/solid_mechanics_model_cohesive/materials/material_cohesive_damage_extrinsic.cc
index 6b18b7e9d..6097e6bbf 100644
--- a/src/model/solid_mechanics/solid_mechanics_model_cohesive/materials/material_cohesive_damage_extrinsic.cc
+++ b/src/model/solid_mechanics/solid_mechanics_model_cohesive/materials/material_cohesive_damage_extrinsic.cc
@@ -1,332 +1,333 @@
 /**
  * Copyright (©) 2012-2023 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * This file is part of Akantu
  *
  * Akantu is free software: you can redistribute it and/or modify it under the
  * terms of the GNU Lesser General Public License as published by the Free
  * Software Foundation, either version 3 of the License, or (at your option) any
  * later version.
  *
  * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
  * details.
  *
  * You should have received a copy of the GNU Lesser General Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  */
 
 /* -------------------------------------------------------------------------- */
 #include "material_cohesive_damage_extrinsic.hh"
 #include "dof_synchronizer.hh"
 #include "fe_engine_template.hh"
 #include "integrator_gauss.hh"
 #include "shape_cohesive.hh"
-#include "solid_mechanics_model_cohesive.hh"
+#include "solid_mechanics_model_cohesive_damage.hh"
 #include "sparse_matrix.hh"
 /* -------------------------------------------------------------------------- */
 #include <algorithm>
 #include <numeric>
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 template <Int dim>
 MaterialCohesiveDamageExtrinsic<dim>::MaterialCohesiveDamageExtrinsic(SolidMechanicsModel & model,
                                                     const ID & id)
     : MaterialCohesiveDamage(model, id),
       lambda(registerInternal<Real, FacetInternalField>("lambda",
                                                            spatial_dimension)),
       czm_damage(
           registerInternal<Real, FacetInternalField>("czm_damage", 1)),
       insertion_stress(registerInternal<Real, CohesiveInternalField>(
           "insertion_stress", dim)),
       is_new_crack(registerInternal<Real, CohesiveInternalField>(
           "is_new_crack", 1))
 {
     if(not this->model->getIsExtrinsic())
     {
         AKANTU_EXCEPTION(
             "MaterialCohesiveDamageExtrinsic can be used only with extrinsic cohesive elements");
     }
 //    czm_damage.setDefaultValue(0.1);
     is_new_crack.setDefaultValue(0.);
 }
 
 /* -------------------------------------------------------------------------- */
 template <Int dim> // NOLINTNEXTLINE(readability-function-cognitive-complexity)
 void MaterialCohesiveDamageExtrinsic<dim>::checkInsertion(bool check_only) {
   AKANTU_DEBUG_IN();
 
   const auto & mesh_facets = model->getMeshFacets();
   auto & inserter = model->getElementInserter();
 
   for (const auto & type_facet : mesh_facets.elementTypes(dim - 1)) {
     auto type_cohesive = FEEngine::getCohesiveElementType(type_facet);
     auto & f_insertion = inserter.getInsertionFacets(type_facet);
     auto & lambda = this->lambda(type_facet);
     auto & damage = this->czm_damage(type_facet);
     auto & ins_stress = insertion_stress(type_cohesive);
     auto & is_new_crack = this->is_new_crack(type_cohesive);
     Int old_nb_quad_points = is_new_crack.size();
     Int new_nb_quad_points = 0;
 
     const auto & facets_check = inserter.getCheckFacets(type_facet);
     const auto & facet_filter_array = getFacetFilter(type_facet);
 
     auto nb_quad_facet =
         model->getFEEngine("FacetsFEEngine").getNbIntegrationPoints(type_facet);
 
 #ifndef AKANTU_NDEBUG
     auto nb_quad_cohesive = model->getFEEngine("CohesiveFEEngine")
                                 .getNbIntegrationPoints(type_cohesive);
 
     AKANTU_DEBUG_ASSERT(nb_quad_cohesive == nb_quad_facet,
                         "The cohesive element and the corresponding facet do "
                         "not have the same numbers of integration points");
 #endif
 
     auto damage_begin = damage.begin();
     auto lambda_begin = make_view<dim>(lambda).begin();
 
     std::vector<Vector<Real>> new_normal_traction;
 
     // loop over each facet belonging to this material
     for (auto && facet : facet_filter_array) {
       // skip facets where check shouldn't be realized
       if (!facets_check(facet)) {
         continue;
       }
 
       // compute the effective norm on each quadrature point of the facet
       Real d(0.);
       for (Int q = 0; q < nb_quad_facet; ++q) {
         auto current_quad = facet * nb_quad_facet + q;
         d+=damage_begin[current_quad];
       }
       d/=nb_quad_facet;
 
       // verify if the effective stress overcomes the threshold
       if (not Math::are_float_equal(d, 0.)) {
         f_insertion(facet) = true;
         if (check_only) {
           continue;
         }
         for (Int q = 0; q < nb_quad_facet; ++q) {
            auto current_quad = facet * nb_quad_facet + q;
            new_normal_traction.emplace_back(lambda_begin[current_quad]);
            new_nb_quad_points++;
         }
       }
     }
     // update material data for the new elements
     ins_stress.resize(old_nb_quad_points + new_nb_quad_points);
     is_new_crack.resize(old_nb_quad_points + new_nb_quad_points);
     for (Int q = 0; q < new_nb_quad_points; ++q) {
       is_new_crack(old_nb_quad_points + q) = 1;
       for (Int d = 0; d < dim; ++d) {
         ins_stress(old_nb_quad_points + q, d) = new_normal_traction[q](d);
       }
     }
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <Int dim>
 void MaterialCohesiveDamageExtrinsic<dim>::computeLambdaOnQuad(ElementType type,
                                                       GhostType ghost_type) {
+  SolidMechanicsModelCohesiveDamage * model_lambda = &aka::as_type<SolidMechanicsModelCohesiveDamage>(*model);
   auto & fem_lambda = model->getFEEngine("LambdaFEEngine");
-  const auto & lambda = model->getLambda();
+  const auto & lambda = model_lambda->getLambda();
   auto & lambda_on_quad = this->lambda(type, ghost_type);
 
   auto underlying_type = Mesh::getFacetType(type);
   fem_lambda.interpolateOnIntegrationPoints(
       lambda, lambda_on_quad, dim, underlying_type, ghost_type,
       this->getElementFilter(type, ghost_type));
 }
 
 /* -------------------------------------------------------------------------- */
 template <Int dim>
 void MaterialCohesiveDamageExtrinsic<dim>::computeTraction(ElementType el_type,
                                                   GhostType ghost_type) {
 
     std::cout << " In MaterialCohesiveDamageExtrinsic<dim>::computeTraction " << std::endl ;
 
   const auto & mesh_facets = model->getMeshFacets();
   for (const auto & type : getElementFilter().elementTypes(
            spatial_dimension, ghost_type, _ek_cohesive)) {
     auto type_facet = Mesh::getFacetType(type);
 
     auto nb_quad_facet =
         model->getFEEngine("FacetsFEEngine").getNbIntegrationPoints(type_facet);
 
 #ifndef AKANTU_NDEBUG
     auto nb_quad_cohesive = model->getFEEngine("CohesiveFEEngine")
                                 .getNbIntegrationPoints(type);
 
     AKANTU_DEBUG_ASSERT(nb_quad_cohesive == nb_quad_facet,
                         "The cohesive element and the corresponding facet do "
                         "not have the same numbers of integration points");
 #endif
 
     auto & elem_filter = this->getElementFilter(type, ghost_type);
 
     auto nb_element = elem_filter.size();
     if (nb_element == 0) {
       continue;
     }
 
     const auto & element_to_facet =
         mesh_facets.getSubelementToElement(el_type,ghost_type);
 
     auto insertion_stress_begin = make_view<dim>(insertion_stress(el_type,ghost_type)).begin();
     auto is_new_crack_begin = is_new_crack(el_type,ghost_type).begin();
 
     auto damage_begin = czm_damage(type_facet,ghost_type).begin();
     auto opening_begin = make_view<dim>(opening(el_type,ghost_type)).begin();
     auto traction_begin = make_view<dim>(tractions(el_type,ghost_type)).begin();
 
     for (auto && elem : elem_filter) {
 
       auto && facet = -1;
       auto && facet_1 = element_to_facet(elem,0);
       auto && facet_2 = element_to_facet(elem,1);
       facet = facet_1<facet_2?facet_1.element:facet_2.element;
       for (Int q = 0; q < nb_quad_facet; ++q) {
         auto current_quad = elem * nb_quad_facet + q;
         auto && is_new = is_new_crack_begin[current_quad];
         auto && t = traction_begin[current_quad];
         if(is_new > 0)
         {
           t = insertion_stress_begin[current_quad];
           is_new = 0;
         }
         else
         {
           auto current_facet_quad = facet * nb_quad_facet + q;
           auto && w = opening_begin[current_quad];
           auto && d = damage_begin[current_facet_quad];
           std::cout << "facet = " << facet << std::endl ;
           std::cout << " w = " << w << std::endl ;
           std::cout << " d = " << d << std::endl;
           t = k*stiffness(d)*w;
           std::cout << " t = " << t << std::endl;
         }
       }
     }
   }
 }
 
 /* -------------------------------------------------------------------------- */
 template <Int dim>
 void MaterialCohesiveDamageExtrinsic<dim>::computeLambda(GhostType ghost_type)
 {
   std::cout << " In MaterialCohesiveDamageExtrinsic<dim>::computeLambda " << std::endl ;
   const auto & mesh_facets = model->getMeshFacets();
   for (const auto & type_facet : mesh_facets.elementTypes(dim - 1)) {
     auto type_cohesive = FEEngine::getCohesiveElementType(type_facet);
     auto nb_quad_facet =
         model->getFEEngine("FacetsFEEngine").getNbIntegrationPoints(type_facet);
 
     #ifndef AKANTU_NDEBUG
     auto nb_quad_cohesive = model->getFEEngine("CohesiveFEEngine")
                                 .getNbIntegrationPoints(type_cohesive);
 
     AKANTU_DEBUG_ASSERT(nb_quad_cohesive == nb_quad_facet,
                         "The cohesive element and the corresponding facet do "
                         "not have the same numbers of integration points");
     #endif
 
     const auto & element_to_subelement =
             mesh_facets.getElementToSubelement(type_facet, ghost_type);
 
     const auto & normals = model->getFEEngine("FacetsFEEngine")
                                .getNormalsOnIntegrationPoints(type_facet);
     const auto & f_stress = model->getStressOnFacets(type_facet);
 
     auto facet_stress_begin = make_view(f_stress, dim, dim, 2).begin();
     auto normal_begin = make_view<dim>(normals).begin();
 
     auto damage_begin = czm_damage(type_facet,ghost_type).begin();
     auto opening_begin = make_view<dim>(opening(type_cohesive,ghost_type)).begin();
 
     for (auto data :
          enumerate(make_view(lambda(type_facet), dim,nb_quad_facet))) {
       auto && f = std::get<0>(data);
       auto && lda = std::get<1>(data);
       auto && elem = element_to_subelement(f);
 
       auto && e = -1;
       for(auto ec : elem)
       {
         if(ec!=ElementNull)
         {
           if(ec.kind() == _ek_cohesive)
           {
               e = ec.element;
               continue;
           }
         }
       }
 
       if(e < 0)
       {
         for (Int q = 0; q < nb_quad_facet; ++q) {
           auto current_quad = f * nb_quad_facet + q;
           auto && normal = normal_begin[current_quad];
           auto && facet_stress = facet_stress_begin[current_quad];
 
           auto && stress_1 = facet_stress(0);
           auto && stress_2 = facet_stress(1);
 
           auto && stress_avg = (stress_1 + stress_2) / 2.;
           lda(q) = stress_avg*normal;
         }
       }
       else
       {
         for (Int q = 0; q < nb_quad_facet; ++q) {
           auto current_quad = f * nb_quad_facet + q;
           auto current_elem_quad = e * nb_quad_facet + q;
           auto && w = opening_begin[current_elem_quad];
           auto && d = damage_begin[current_quad];
           lda(q) = k*augmented_stiffness(d)*w;
           std::cout << "f = " << f << std::endl ;
           std::cout << " w = " << w << std::endl ;
           std::cout << " d = " << d << std::endl ;
           std::cout << " lda = " << lda(q) << std::endl ;
         }
       }
     }
   }
 }
 
 /* -------------------------------------------------------------------------- */
 template <Int dim>
 void MaterialCohesiveDamageExtrinsic<dim>::computeDamage(GhostType ghost_type)
 {
     const auto & mesh_facets = model->getMeshFacets();
     for (const auto & type : mesh_facets.elementTypes(dim - 1)) {
     auto & elem_filter = getFacetFilter(type);
     auto nb_element = elem_filter.size();
     if (nb_element == 0) {
       continue;
     }
     for (auto && args : getArguments(type, ghost_type)) {
       computeDamageOnQuad(args);
     }
   }
 }
 /* -------------------------------------------------------------------------- */
 template class MaterialCohesiveDamageExtrinsic<1>;
 template class MaterialCohesiveDamageExtrinsic<2>;
 template class MaterialCohesiveDamageExtrinsic<3>;
 const bool material_is_alocated_cohesive_damage [[maybe_unused]] =
     instantiateMaterial<MaterialCohesiveDamageExtrinsic>("cohesive_damage_extrinsic");
 
 } // namespace akantu
diff --git a/src/model/solid_mechanics/solid_mechanics_model_cohesive/materials/material_cohesive_damage_intrinsic.cc b/src/model/solid_mechanics/solid_mechanics_model_cohesive/materials/material_cohesive_damage_intrinsic.cc
index a1a62f154..7fe1fc28e 100644
--- a/src/model/solid_mechanics/solid_mechanics_model_cohesive/materials/material_cohesive_damage_intrinsic.cc
+++ b/src/model/solid_mechanics/solid_mechanics_model_cohesive/materials/material_cohesive_damage_intrinsic.cc
@@ -1,488 +1,490 @@
 /**
  * Copyright (©) 2012-2023 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * This file is part of Akantu
  *
  * Akantu is free software: you can redistribute it and/or modify it under the
  * terms of the GNU Lesser General Public License as published by the Free
  * Software Foundation, either version 3 of the License, or (at your option) any
  * later version.
  *
  * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
  * details.
  *
  * You should have received a copy of the GNU Lesser General Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  */
 
 /* -------------------------------------------------------------------------- */
 #include "material_cohesive_damage_intrinsic.hh"
 #include "dof_synchronizer.hh"
 #include "fe_engine_template.hh"
 #include "integrator_gauss.hh"
 #include "shape_cohesive.hh"
-#include "solid_mechanics_model_cohesive.hh"
+#include "solid_mechanics_model_cohesive_damage.hh"
 #include "sparse_matrix.hh"
 /* -------------------------------------------------------------------------- */
 #include <algorithm>
 #include <numeric>
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 template <Int dim>
 MaterialCohesiveDamageIntrinsic<dim>::MaterialCohesiveDamageIntrinsic(SolidMechanicsModel & model,
                                                     const ID & id)
     : MaterialCohesiveDamage(model, id),
       lambda(registerInternal<Real, CohesiveInternalField>("lambda",
                                                            spatial_dimension)),
       err_openings(registerInternal<Real, CohesiveInternalField>(
           "err_openings", spatial_dimension)),
       czm_damage(
           registerInternal<Real, CohesiveInternalField>("czm_damage", 1)) {
     if(this->model->getIsExtrinsic())
     {
         AKANTU_EXCEPTION(
             "MaterialCohesiveDamageIntrinsic can be used only with intrinsic cohesive elements");
     }
 }
 
 /* -------------------------------------------------------------------------- */
 template <Int dim>
 void MaterialCohesiveDamageIntrinsic<dim>::assembleInternalForces(GhostType ghost_type) {
   AKANTU_DEBUG_IN();
 
   auto & internal_force = const_cast<Array<Real> &>(model->getInternalForce());
 
   for (auto type : getElementFilter().elementTypes(spatial_dimension,
                                                    ghost_type, _ek_cohesive)) {
     auto & elem_filter = getElementFilter(type, ghost_type);
     auto nb_element = elem_filter.size();
     if (nb_element == 0) {
       continue;
     }
 
     const auto & shapes = fem_cohesive.getShapes(type, ghost_type);
     auto & traction = tractions(type, ghost_type);
     auto & err_opening = err_openings(type, ghost_type);
 
     auto size_of_shapes = shapes.getNbComponent();
     auto nb_nodes_per_element = Mesh::getNbNodesPerElement(type);
     auto nb_quadrature_points =
         fem_cohesive.getNbIntegrationPoints(type, ghost_type);
 
     /// compute @f$t_i N_a@f$
 
     auto traction_cpy = std::make_shared<Array<Real>>(
         nb_element * nb_quadrature_points, spatial_dimension * size_of_shapes);
 
     auto err_opening_cpy = std::make_shared<Array<Real>>(
         nb_element * nb_quadrature_points, spatial_dimension * size_of_shapes);
 
     auto traction_it = traction.begin(spatial_dimension, 1);
     auto err_opening_it = err_opening.begin(spatial_dimension, 1);
 
     auto shapes_filtered_begin = shapes.begin(1, size_of_shapes);
     auto traction_cpy_it =
         traction_cpy->begin(spatial_dimension, size_of_shapes);
     auto err_opening_cpy_it =
         err_opening_cpy->begin(spatial_dimension, size_of_shapes);
 
     for (Int el = 0; el < nb_element; ++el) {
       auto current_quad = elem_filter(el) * nb_quadrature_points;
 
       for (Int q = 0; q < nb_quadrature_points; ++q, ++traction_it,
                ++err_opening_it, ++current_quad, ++traction_cpy_it,
                ++err_opening_cpy_it) {
 
         auto && shapes_filtered = shapes_filtered_begin[current_quad];
 
         *traction_cpy_it = (*traction_it) * shapes_filtered;
         *err_opening_cpy_it = (*err_opening_it) * shapes_filtered;
       }
     }
 
     /**
      * compute @f$\int t \cdot N\, dS@f$ by  @f$ \sum_q \mathbf{N}^t
      * \mathbf{t}_q \overline w_q J_q@f$
      */
     auto partial_int_t_N = std::make_shared<Array<Real>>(
         nb_element, spatial_dimension * size_of_shapes, "int_t_N");
 
     fem_cohesive.integrate(*traction_cpy, *partial_int_t_N,
                            spatial_dimension * size_of_shapes, type, ghost_type,
                            elem_filter);
 
     auto int_t_N = std::make_shared<Array<Real>>(
         nb_element, 2 * spatial_dimension * size_of_shapes, "int_t_N");
 
     auto * int_t_N_val = int_t_N->data();
     auto * partial_int_t_N_val = partial_int_t_N->data();
     for (Int el = 0; el < nb_element; ++el) {
       std::copy_n(partial_int_t_N_val, size_of_shapes * spatial_dimension,
                   int_t_N_val);
       std::copy_n(partial_int_t_N_val, size_of_shapes * spatial_dimension,
                   int_t_N_val + size_of_shapes * spatial_dimension);
 
       for (Int n = 0; n < size_of_shapes * spatial_dimension; ++n) {
         int_t_N_val[n] *= -1.;
       }
 
       int_t_N_val += nb_nodes_per_element * spatial_dimension;
       partial_int_t_N_val += size_of_shapes * spatial_dimension;
     }
 
     /**
      * compute @f$\int err \cdot N\, dS@f$ by  @f$ \sum_q \mathbf{N}^t
      * \mathbf{err}_q \overline w_q J_q@f$
      */
     auto int_err_N = std::make_shared<Array<Real>>(
         nb_element, spatial_dimension * size_of_shapes, "int_err_N");
 
     fem_cohesive.integrate(*err_opening_cpy, *int_err_N,
                            spatial_dimension * size_of_shapes, type, ghost_type,
                            elem_filter);
 
     /// assemble
     model->getDOFManager().assembleElementalArrayLocalArray(
         "displacement", *int_t_N, internal_force, type, ghost_type, 1,
         elem_filter);
 
     //    auto lambda_connectivity = lambda_connectivities(type, ghost_type);
     auto underlying_type = Mesh::getFacetType(type);
     model->getDOFManager().assembleElementalArrayToResidual(
         "lambda", *int_err_N, underlying_type, ghost_type, 1., elem_filter);
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <Int dim>
 void MaterialCohesiveDamageIntrinsic<dim>::assembleStiffnessMatrix(
     GhostType ghost_type) {
   AKANTU_DEBUG_IN();
 
   // auto & lambda_connectivities =
   //     model->getMesh().getElementalData<Idx>("lambda_connectivities");
 
   for (auto type : getElementFilter().elementTypes(spatial_dimension,
                                                    ghost_type, _ek_cohesive)) {
     auto nb_quadrature_points =
         fem_cohesive.getNbIntegrationPoints(type, ghost_type);
     auto nb_nodes_per_element = Mesh::getNbNodesPerElement(type);
 
     const auto & elem_filter = getElementFilter(type, ghost_type);
     auto nb_element = elem_filter.size();
 
     if (nb_element == 0U) {
       continue;
     }
 
     const auto & shapes = fem_cohesive.getShapes(type, ghost_type);
     auto size_of_shapes = shapes.getNbComponent();
 
     auto shapes_filtered = std::make_shared<Array<Real>>(
         nb_element * nb_quadrature_points, size_of_shapes, "filtered shapes");
 
     for (auto && data :
          zip(filter(elem_filter,
                     make_view(shapes, size_of_shapes, nb_quadrature_points)),
              make_view(*shapes_filtered, size_of_shapes,
                        nb_quadrature_points))) {
       std::get<1>(data) = std::get<0>(data);
     }
 
     Matrix<Real> A(spatial_dimension * size_of_shapes,
                    spatial_dimension * nb_nodes_per_element);
     A.zero();
     for (Int i = 0; i < spatial_dimension * size_of_shapes; ++i) {
       A(i, i) = 1;
       A(i, i + spatial_dimension * size_of_shapes) = -1;
     }
 
     /// get the tangent matrix @f$\frac{\partial{(t/\delta)}}{\partial{\delta}}
     /// @f$
     /// TODO : optimisation not to reassemble uu term, which does not change
     /// during computation
     auto tangent_stiffness_matrix_uu = std::make_unique<Array<Real>>(
         nb_element * nb_quadrature_points,
         spatial_dimension * spatial_dimension, "tangent_stiffness_matrix_uu");
 
     auto tangent_stiffness_matrix_ll = std::make_unique<Array<Real>>(
         nb_element * nb_quadrature_points,
         spatial_dimension * spatial_dimension, "tangent_stiffness_matrix_ll");
 
     computeNormal(model->getCurrentPosition(), normals(type, ghost_type), type,
                   ghost_type);
 
     /// compute openings @f$\mathbf{\delta}@f$
     // computeOpening(model->getDisplacement(), opening(type, ghost_type), type,
     // ghost_type);
 
     tangent_stiffness_matrix_uu->zero();
     tangent_stiffness_matrix_ll->zero();
 
     computeTangentTraction(type, *tangent_stiffness_matrix_uu,
                            *tangent_stiffness_matrix_ll, ghost_type);
 
     UInt size_at_nt_duu_n_a = spatial_dimension * nb_nodes_per_element *
                               spatial_dimension * nb_nodes_per_element;
     auto at_nt_duu_n_a =
         std::make_unique<Array<Real>>(nb_element * nb_quadrature_points,
                                       size_at_nt_duu_n_a, "A^t*N^t*Duu*N*A");
 
     UInt size_nt_dll_n =
         spatial_dimension * size_of_shapes * spatial_dimension * size_of_shapes;
     auto nt_dll_n = std::make_unique<Array<Real>>(
         nb_element * nb_quadrature_points, size_nt_dll_n, "N^t*Dll*N");
 
     UInt size_at_nt_dul_n = spatial_dimension * nb_nodes_per_element *
                             spatial_dimension * size_of_shapes;
     auto at_nt_dul_n = std::make_unique<Array<Real>>(
         nb_element * nb_quadrature_points, size_at_nt_dul_n, "A^t*N^t*Dul*N");
 
     Matrix<Real> N(spatial_dimension, spatial_dimension * size_of_shapes);
 
     for (auto && [At_Nt_Duu_N_A, Duu, Nt_Dll_N, Dll, At_Nt_Dul_N, shapes] :
          zip(make_view(*at_nt_duu_n_a, spatial_dimension * nb_nodes_per_element,
                        spatial_dimension * nb_nodes_per_element),
              make_view(*tangent_stiffness_matrix_uu, spatial_dimension,
                        spatial_dimension),
              make_view(*nt_dll_n, spatial_dimension * size_of_shapes,
                        spatial_dimension * size_of_shapes),
              make_view(*tangent_stiffness_matrix_ll, spatial_dimension,
                        spatial_dimension),
              make_view(*at_nt_dul_n, spatial_dimension * nb_nodes_per_element,
                        spatial_dimension * size_of_shapes),
              make_view(*shapes_filtered, size_of_shapes))) {
       N.zero();
       /**
        * store  the   shapes  in  voigt   notations  matrix  @f$\mathbf{N}  =
        * \begin{array}{cccccc} N_0(\xi) & 0 & N_1(\xi)  &0 & N_2(\xi) & 0 \\
        * 0 & * N_0(\xi)& 0 &N_1(\xi)& 0 & N_2(\xi) \end{array} @f$
        **/
       for (Int i = 0; i < spatial_dimension; ++i) {
         for (Int n = 0; n < size_of_shapes; ++n) {
           N(i, i + spatial_dimension * n) = shapes(n);
         }
       }
 
       /**
        * compute stiffness matrix  @f$   \mathbf{K}    =    \delta
        *\mathbf{U}^T \int_{\Gamma_c}    {\mathbf{P}^t
        *\frac{\partial{\mathbf{t}}}
        *{\partial{\delta}}
        * \mathbf{P} d\Gamma \Delta \mathbf{U}}  @f$
        **/
       auto && NA = N * A;
       At_Nt_Duu_N_A = (Duu * NA).transpose() * NA;
       Nt_Dll_N = (Dll * N).transpose() * N;
       At_Nt_Dul_N = NA.transpose() * N;
     }
 
     auto Kuu_e =
         std::make_unique<Array<Real>>(nb_element, size_at_nt_duu_n_a, "Kuu_e");
 
     fem_cohesive.integrate(*at_nt_duu_n_a, *Kuu_e, size_at_nt_duu_n_a, type,
                            ghost_type, elem_filter);
 
     auto Kll_e =
         std::make_unique<Array<Real>>(nb_element, size_nt_dll_n, "Kll_e");
 
     fem_cohesive.integrate(*nt_dll_n, *Kll_e, size_nt_dll_n, type, ghost_type,
                            elem_filter);
 
     auto Kul_e =
         std::make_unique<Array<Real>>(nb_element, size_at_nt_dul_n, "Kul_e");
 
     fem_cohesive.integrate(*at_nt_dul_n, *Kul_e, size_at_nt_dul_n, type,
                            ghost_type, elem_filter);
 
     model->getDOFManager().assembleElementalMatricesToMatrix(
         "K", "displacement", *Kuu_e, type, ghost_type, _symmetric, elem_filter);
 
     auto underlying_type = Mesh::getFacetType(type);
     model->getDOFManager().assembleElementalMatricesToMatrix(
         "K", "lambda", *Kll_e, underlying_type, ghost_type, _symmetric,
         elem_filter);
 
     auto connectivity = model->getMesh().getConnectivity(type, ghost_type);
     auto conn = make_view(connectivity, connectivity.getNbComponent()).begin();
 
+    SolidMechanicsModelCohesiveDamage * model_lambda = &aka::as_type<SolidMechanicsModelCohesiveDamage>(*model);
     auto lambda_connectivity =
-        model->getLambdaMesh().getConnectivity(underlying_type, ghost_type);
+        model_lambda->getLambdaMesh().getConnectivity(underlying_type, ghost_type);
     auto lambda_conn =
         make_view(lambda_connectivity, lambda_connectivity.getNbComponent())
             .begin();
 
     /// Assemble Kll_e
     // TermsToAssemble term_ll("lambda", "lambda");
     // auto el_mat_it_ll = Kll_e->begin(spatial_dimension * size_of_shapes,
     //                                  spatial_dimension * size_of_shapes);
 
     // auto compute_ll = [&](const auto & el) {
     //   auto kll_e = *el_mat_it_ll;
     //   auto && lda_conn_el = lambda_conn[el];
     //   auto N = lda_conn_el.rows();
     //   for (Int m = 0; m < N; ++m) {
     //     auto ldai = lda_conn_el(m);
     //     for (Int n = m; n < N; ++n) {
     //       auto ldaj = lda_conn_el(n);
     //       for (Int k = 0; k < spatial_dimension; ++k) {
     //         for (Int l = 0; l < spatial_dimension; ++l) {
     //           auto && term_ll_ij = term_ll(ldai * spatial_dimension + k,
     //                                        ldaj * spatial_dimension + l);
     //           term_ll_ij =
     //               kll_e(m * spatial_dimension + k, n * spatial_dimension +
     //               l);
     //         }
     //       }
     //     }
     //   }
     //   ++el_mat_it_ll;
     // };
     // for_each_element(nb_element, elem_filter, compute_ll);
 
     // model->getDOFManager().assemblePreassembledMatrix("K", term_ll);
     // model->getDOFManager().getMatrix("K").saveMatrix("Kuu_terms.mtx");
 
     /// Assemble Klu_e
     TermsToAssemble term_ul("displacement", "lambda");
     auto el_mat_it_ul = Kul_e->begin(spatial_dimension * nb_nodes_per_element,
                                      spatial_dimension * size_of_shapes);
 
     auto compute_ul = [&](const auto & el) {
       auto kul_e = *el_mat_it_ul;
       auto && u_conn_el = conn[el];
       auto && lda_conn_el = lambda_conn[el];
       auto M = u_conn_el.rows();
       auto N = lda_conn_el.rows();
       for (Int m = 0; m < M; ++m) {
         for (Int n = 0; n < N; ++n) {
           auto u = u_conn_el(m);
           auto lda = lda_conn_el(n);
           for (Int k = 0; k < spatial_dimension; ++k) {
             for (Int l = 0; l < spatial_dimension; ++l) {
               auto && term_ul_ij = term_ul(u * spatial_dimension + k,
                                            lda * spatial_dimension + l);
               term_ul_ij =
                   kul_e(m * spatial_dimension + k, n * spatial_dimension + l);
             }
           }
         }
       }
       ++el_mat_it_ul;
     };
     for_each_element(nb_element, elem_filter, compute_ul);
 
     model->getDOFManager().assemblePreassembledMatrix("K", term_ul);
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <Int dim>
 void MaterialCohesiveDamageIntrinsic<dim>::computeDamage(GhostType ghost_type)
 {
     for (const auto & type : getElementFilter().elementTypes(
            spatial_dimension, ghost_type, _ek_cohesive)) {
     auto & elem_filter = getElementFilter(type, ghost_type);
     auto nb_element = elem_filter.size();
     if (nb_element == 0) {
       continue;
     }
     for (auto && args : getArguments(type, ghost_type)) {
       computeDamageOnQuad(args);
     }
   }
 }
 
 /* -------------------------------------------------------------------------- */
 template <Int dim>
 void MaterialCohesiveDamageIntrinsic<dim>::computeLambdaOnQuad(ElementType type,
                                                       GhostType ghost_type) {
+  SolidMechanicsModelCohesiveDamage * model_lambda = &aka::as_type<SolidMechanicsModelCohesiveDamage>(*model);
   auto & fem_lambda = model->getFEEngine("LambdaFEEngine");
-  const auto & lambda = model->getLambda();
+  const auto & lambda = model_lambda->getLambda();
   auto & lambda_on_quad = this->lambda(type, ghost_type);
 
 //  std::cout << "lambda in : MaterialCohesiveDamageIntrinsic<dim>::computeLambdaOnQuad " << std::endl;
 //  lambda.printself(std::cout << std::endl);
 //  ArrayPrintHelper<true>::print_content(lambda,std::cout,0);
 
 
   auto underlying_type = Mesh::getFacetType(type);
   fem_lambda.interpolateOnIntegrationPoints(
       lambda, lambda_on_quad, dim, underlying_type, ghost_type,
       this->getElementFilter(type, ghost_type));
 
 //  std::cout << "lambda_on_quad in : MaterialCohesiveDamageIntrinsic<dim>::computeLambdaOnQuad " << std::endl;
 //  lambda_on_quad.printself(std::cout << std::endl);
 //  ArrayPrintHelper<true>::print_content(lambda_on_quad,std::cout,0);
 
 //  std::cout << "shapes_lambda in : MaterialCohesiveDamageIntrinsic<dim>::computeLambdaOnQuad " << std::endl;
 //  auto shapes_lambda = fem_lambda.getShapes(underlying_type,ghost_type,0);
 //  ArrayPrintHelper<true>::print_content(shapes_lambda,std::cout,0);
 
 //  std::cout << "shapes_cohesive in : MaterialCohesiveDamageIntrinsic<dim>::computeLambdaOnQuad " << std::endl;
 //  auto & fem_cohesive =
 //      model->getFEEngineClass<MyFEEngineCohesiveType>("CohesiveFEEngine");
 //  auto shapes_cohesive = fem_cohesive.getShapes(type,ghost_type,0);
 //  ArrayPrintHelper<true>::print_content(shapes_cohesive,std::cout,0);
 }
 
 /* -------------------------------------------------------------------------- */
 template <Int dim>
 void MaterialCohesiveDamageIntrinsic<dim>::computeTraction(ElementType el_type,
                                                   GhostType ghost_type) {
 
   auto & elem_filter = getElementFilter(el_type, ghost_type);
   auto nb_element = elem_filter.size();
   if (nb_element > 0) {
     computeLambdaOnQuad(el_type, ghost_type);
 
 //    auto & traction = tractions(type, ghost_type);
 //    std::cout << "traction in : MaterialCohesiveDamageIntrinsic<dim>::computeTraction " << std::endl;
 //    ArrayPrintHelper<true>::print_content(traction,std::cout,0);
 
 //    auto & lambda_ = lambda(type, ghost_type);
 //    std::cout << "lambda in : MaterialCohesiveDamageIntrinsic<dim>::computeTraction " << std::endl;
 //    ArrayPrintHelper<true>::print_content(lambda_,std::cout,0);
 //    lambda.printself(std::cout);
 
     for (auto && args : getArguments(el_type, ghost_type)) {
       computeTractionOnQuad(args);
     }
   }
 }
 
 /* -------------------------------------------------------------------------- */
 template <Int dim>
 void MaterialCohesiveDamageIntrinsic<dim>::computeTangentTraction(
     ElementType el_type, Array<Real> & tangent_matrix_uu,
     Array<Real> & tangent_matrix_ll, GhostType ghost_type) {
   AKANTU_DEBUG_IN();
 
   for (auto && [args, tangent_uu, tangent_ll] :
        zip(getArguments(el_type, ghost_type),
            make_view<dim, dim>(tangent_matrix_uu),
            make_view<dim, dim>(tangent_matrix_ll))) {
     computeTangentTractionOnQuad(tangent_uu, tangent_ll, args);
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template class MaterialCohesiveDamageIntrinsic<1>;
 template class MaterialCohesiveDamageIntrinsic<2>;
 template class MaterialCohesiveDamageIntrinsic<3>;
 const bool material_is_alocated_cohesive_damage [[maybe_unused]] =
     instantiateMaterial<MaterialCohesiveDamageIntrinsic>("cohesive_damage_intrinsic");
 
 } // namespace akantu
diff --git a/src/model/solid_mechanics/solid_mechanics_model_cohesive/solid_mechanics_model_cohesive.cc b/src/model/solid_mechanics/solid_mechanics_model_cohesive/solid_mechanics_model_cohesive.cc
index b45a736ba..a2f304e7d 100644
--- a/src/model/solid_mechanics/solid_mechanics_model_cohesive/solid_mechanics_model_cohesive.cc
+++ b/src/model/solid_mechanics/solid_mechanics_model_cohesive/solid_mechanics_model_cohesive.cc
@@ -1,935 +1,623 @@
 /**
  * Copyright (©) 2012-2023 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * This file is part of Akantu
  *
  * Akantu is free software: you can redistribute it and/or modify it under the
  * terms of the GNU Lesser General Public License as published by the Free
  * Software Foundation, either version 3 of the License, or (at your option) any
  * later version.
  *
  * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
  * details.
  *
  * You should have received a copy of the GNU Lesser General Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  */
 
 /* -------------------------------------------------------------------------- */
 #include "solid_mechanics_model_cohesive.hh"
 #include "aka_iterators.hh"
 #include "cohesive_element_inserter.hh"
 #include "element_synchronizer.hh"
 #include "facet_synchronizer.hh"
 #include "fe_engine_template.hh"
 #include "global_ids_updater.hh"
 #include "integrator_gauss.hh"
-#include "material_cohesive_damage.hh"
+#include "material_cohesive.hh"
 #include "mesh_accessor.hh"
 #include "mesh_global_data_updater.hh"
 #include "parser.hh"
 #include "shape_cohesive.hh"
 /* -------------------------------------------------------------------------- */
 #include "dumper_iohelper_paraview.hh"
 /* -------------------------------------------------------------------------- */
 #include <algorithm>
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 
 class CohesiveMeshGlobalDataUpdater : public MeshGlobalDataUpdater {
 public:
   CohesiveMeshGlobalDataUpdater(SolidMechanicsModelCohesive & model)
       : model(model), mesh(model.getMesh()),
         global_ids_updater(model.getMesh(), model.cohesive_synchronizer.get()) {
   }
 
   /* ------------------------------------------------------------------------ */
   std::tuple<UInt, UInt>
   updateData(NewNodesEvent & nodes_event,
              NewElementsEvent & elements_event) override {
     auto * cohesive_nodes_event =
         dynamic_cast<CohesiveNewNodesEvent *>(&nodes_event);
     if (cohesive_nodes_event == nullptr) {
       return std::make_tuple(nodes_event.getList().size(),
                              elements_event.getList().size());
     }
 
     /// update nodes type
     auto & new_nodes = cohesive_nodes_event->getList();
     auto & old_nodes = cohesive_nodes_event->getOldNodesList();
 
     auto local_nb_new_nodes = new_nodes.size();
     auto nb_new_nodes = local_nb_new_nodes;
 
     if (mesh.isDistributed()) {
       MeshAccessor mesh_accessor(mesh);
       auto & nodes_flags = mesh_accessor.getNodesFlags();
       auto nb_old_nodes = nodes_flags.size();
       nodes_flags.resize(nb_old_nodes + local_nb_new_nodes);
 
       for (auto && [old_node, new_node] : zip(old_nodes, new_nodes)) {
         nodes_flags(new_node) = nodes_flags(old_node);
       }
 
       model.updateCohesiveSynchronizers(elements_event);
       nb_new_nodes = global_ids_updater.updateGlobalIDs(new_nodes.size());
     }
 
     auto nb_new_elements = elements_event.getList().size();
     const auto & comm = mesh.getCommunicator();
     comm.allReduce(nb_new_elements, SynchronizerOperation::_sum);
 
     if (nb_new_elements > 0) {
       mesh.sendEvent(elements_event);
     }
 
     if (nb_new_nodes > 0) {
       mesh.sendEvent(nodes_event);
     }
 
     return std::make_tuple(nb_new_nodes, nb_new_elements);
   }
 
 private:
   SolidMechanicsModelCohesive & model;
   Mesh & mesh;
   GlobalIdsUpdater global_ids_updater;
 };
 
 /* -------------------------------------------------------------------------- */
 SolidMechanicsModelCohesive::SolidMechanicsModelCohesive(
     Mesh & mesh, Int dim, const ID & id,
     const std::shared_ptr<DOFManager> & dof_manager)
     : SolidMechanicsModel(mesh, dim, id, dof_manager,
                           ModelType::_solid_mechanics_model_cohesive),
       tangents("tangents", id), facet_stress("facet_stress", id),
       facet_material("facet_material", id) {
   AKANTU_DEBUG_IN();
 
   registerFEEngineObject<MyFEEngineCohesiveType>("CohesiveFEEngine", mesh,
                                                  Model::spatial_dimension);
 
   auto && tmp_material_selector =
       std::make_shared<DefaultMaterialCohesiveSelector>(*this);
 
   tmp_material_selector->setFallback(this->getConstitutiveLawSelector());
   this->setConstitutiveLawSelector(tmp_material_selector);
 
   this->mesh.registerDumper<DumperParaview>("cohesive elements", id);
   this->mesh.addDumpMeshToDumper("cohesive elements", mesh,
                                  Model::spatial_dimension, _not_ghost,
                                  _ek_cohesive);
 
   if (this->mesh.isDistributed()) {
     /// create the distributed synchronizer for cohesive elements
     this->cohesive_synchronizer = std::make_unique<ElementSynchronizer>(
         mesh, "cohesive_distributed_synchronizer");
 
     auto & synchronizer = mesh.getElementSynchronizer();
     this->cohesive_synchronizer->split(synchronizer, [](auto && el) {
       return Mesh::getKind(el.type) == _ek_cohesive;
     });
 
     this->registerSynchronizer(*cohesive_synchronizer,
                                SynchronizationTag::_constitutive_law_id);
     this->registerSynchronizer(*cohesive_synchronizer,
                                SynchronizationTag::_smm_stress);
     this->registerSynchronizer(*cohesive_synchronizer,
                                SynchronizationTag::_smm_boundary);
   }
 
   this->inserter = std::make_unique<CohesiveElementInserter>(
       this->mesh, id + ":cohesive_element_inserter");
 
   registerFEEngineObject<MyFEEngineFacetType>(
       "FacetsFEEngine", mesh.getMeshFacets(), Model::spatial_dimension - 1);
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void SolidMechanicsModelCohesive::setTimeStep(Real time_step,
                                               const ID & solver_id) {
   SolidMechanicsModel::setTimeStep(time_step, solver_id);
   this->mesh.getDumper("cohesive elements").setTimeStep(time_step);
 }
 
 /* -------------------------------------------------------------------------- */
 void SolidMechanicsModelCohesive::initFullImpl(const ModelOptions & options) {
   AKANTU_DEBUG_IN();
 
   const auto & smmc_options =
       aka::as_type<SolidMechanicsModelCohesiveOptions>(options);
 
   this->is_extrinsic = smmc_options.is_extrinsic;
 
   inserter->setIsExtrinsic(is_extrinsic);
 
   if (mesh.isDistributed()) {
     auto & mesh_facets = inserter->getMeshFacets();
     auto & synchronizer =
         aka::as_type<FacetSynchronizer>(mesh_facets.getElementSynchronizer());
 
     // synchronizeGhostFacetsConnectivity();
 
     /// create the facet synchronizer for extrinsic simulations
     if (is_extrinsic) {
       facet_stress_synchronizer = std::make_unique<ElementSynchronizer>(
           synchronizer, id + ":facet_stress_synchronizer");
       facet_stress_synchronizer->swapSendRecv();
       this->registerSynchronizer(*facet_stress_synchronizer,
                                  SynchronizationTag::_smmc_facets_stress);
     }
   }
 
   MeshAccessor mesh_accessor(mesh);
   mesh_accessor.registerGlobalDataUpdater(
       std::make_unique<CohesiveMeshGlobalDataUpdater>(*this));
 
   auto && [section, is_empty] = this->getParserSection();
 
   if (not is_empty) {
     auto inserter_section =
         section.getSubSections(ParserType::_cohesive_inserter);
     if (inserter_section.begin() != inserter_section.end()) {
       inserter->parseSection(*inserter_section.begin());
     }
   }
 
   SolidMechanicsModel::initFullImpl(options);
 
   AKANTU_DEBUG_OUT();
 } // namespace akantu
 
 /* -------------------------------------------------------------------------- */
 void SolidMechanicsModelCohesive::initConstitutiveLaws() {
   AKANTU_DEBUG_IN();
 
   // make sure the material are instantiated
   instantiateMaterials();
 
   auto & material_selector = this->getConstitutiveLawSelector();
 
   // set the facet information in the material in case of dynamic insertion
   // to know what material to call for stress checks
   const Mesh & mesh_facets = inserter->getMeshFacets();
   facet_material.initialize(
       mesh_facets, _spatial_dimension = spatial_dimension - 1,
       _with_nb_element = true,
       _default_value =
           DefaultMaterialCohesiveSelector::getDefaultCohesiveMaterial(*this));
 
   for_each_element(
       mesh_facets,
       [&](auto && element) {
         auto mat_index = material_selector(element);
         if (not mat_index) {
           return;
         }
         auto & mat =
             aka::as_type<MaterialCohesive>(this->getConstitutiveLaw(mat_index));
 
         facet_material(element) = mat_index;
         if (is_extrinsic) {
           mat.addFacet(element);
         }
       },
       _spatial_dimension = spatial_dimension - 1, _ghost_type = _not_ghost);
 
   SolidMechanicsModel::initConstitutiveLaws();
 
-  auto & initial_nodes = mesh.getNodalData<Idx>("initial_nodes_match");
-  initial_nodes.resize(mesh.getNbNodes());
-  for (auto && [node, init_node] : enumerate(initial_nodes)) {
-    init_node = node;
-  }
-
-  auto need_lambda = false;
-
-  this->for_each_constitutive_law([&need_lambda](auto && material) {
-    if (aka::is_of_type<MaterialCohesive>(material)) {
-      need_lambda |= aka::as_type<MaterialCohesive>(material).needLambda();
-    }
-  });
-
-  if (need_lambda) {
-    lambda =
-        std::make_unique<Array<Real>>(0, spatial_dimension, "cohesive lambda");
-    previous_lambda =
-        std::make_unique<Array<Real>>(0, spatial_dimension, "previous lambda");
-    lambda_increment =
-        std::make_unique<Array<Real>>(0, spatial_dimension, "lambda increment");
-    lambda_blocked_dofs = std::make_unique<Array<bool>>(0, spatial_dimension,
-                                                        "lambda_blocked_dofs");
-
-    lambda_mesh = std::make_unique<Mesh>(spatial_dimension,
-                                         mesh.getCommunicator(), "lambda_mesh");
-    registerFEEngineObject<MyFEEngineLambdaType>("LambdaFEEngine", *lambda_mesh,
-                                                 Model::spatial_dimension - 1);
-
-    auto & nodes_to_lambda = mesh.getNodalData<Idx>("nodes_to_lambda");
-    nodes_to_lambda.resize(mesh.getNbNodes(), -1);
-  }
-
   if (is_extrinsic) {
     this->initAutomaticInsertion();
   } else {
     this->insertIntrinsicElements();
   }
 
-  if (lambda) {
-    auto & dof_manager = this->getDOFManager();
-    if (!dof_manager.hasDOFs("lambda")) {
-      dof_manager.registerDOFs("lambda", *this->lambda, *lambda_mesh);
-      dof_manager.registerDOFsIncrement("lambda", *this->lambda_increment);
-      dof_manager.registerDOFsPrevious("lambda", *this->previous_lambda);
-      dof_manager.registerBlockedDOFs("lambda", *this->lambda_blocked_dofs);
-    }
-  }
-
   AKANTU_DEBUG_OUT();
 } // namespace akantu
 
 /* -------------------------------------------------------------------------- */
 /**
  * Initialize the model,basically it  pre-compute the shapes, shapes derivatives
  * and jacobian
  */
 void SolidMechanicsModelCohesive::initModel() {
   AKANTU_DEBUG_IN();
 
   SolidMechanicsModel::initModel();
 
   /// add cohesive type connectivity
   ElementType type = _not_defined;
   for (auto && type_ghost : ghost_types) {
     for (const auto & tmp_type :
          mesh.elementTypes(spatial_dimension, type_ghost)) {
       const auto & connectivity = mesh.getConnectivity(tmp_type, type_ghost);
       if (connectivity.empty()) {
         continue;
       }
 
       type = tmp_type;
       auto type_facet = Mesh::getFacetType(type);
       auto type_cohesive = FEEngine::getCohesiveElementType(type_facet);
       AKANTU_DEBUG_ASSERT(Mesh::getKind(type_cohesive) == _ek_cohesive,
                           "The element type " << type_cohesive
                                               << " is not a cohesive type");
       mesh.addConnectivityType(type_cohesive, type_ghost);
     }
   }
   AKANTU_DEBUG_ASSERT(type != _not_defined, "No elements in the mesh");
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void SolidMechanicsModelCohesive::insertIntrinsicElements() {
   AKANTU_DEBUG_IN();
   inserter->insertIntrinsicElements();
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void SolidMechanicsModelCohesive::initAutomaticInsertion() {
   AKANTU_DEBUG_IN();
 
   this->inserter->limitCheckFacets();
   this->updateFacetStressSynchronizer();
   this->resizeFacetStress();
 
   /// compute normals on facets
   this->computeNormals();
 
   this->initStressInterpolation();
 }
 
 /* -------------------------------------------------------------------------- */
 void SolidMechanicsModelCohesive::updateAutomaticInsertion() {
   AKANTU_DEBUG_IN();
 
   this->inserter->limitCheckFacets();
   this->updateFacetStressSynchronizer();
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void SolidMechanicsModelCohesive::initStressInterpolation() {
   Mesh & mesh_facets = inserter->getMeshFacets();
 
   /// compute quadrature points coordinates on facets
   Array<Real> & position = mesh.getNodes();
 
   ElementTypeMapArray<Real> quad_facets("quad_facets", id);
   quad_facets.initialize(mesh_facets, _nb_component = Model::spatial_dimension,
                          _spatial_dimension = Model::spatial_dimension - 1);
 
   getFEEngine("FacetsFEEngine")
       .interpolateOnIntegrationPoints(position, quad_facets);
 
   /// compute elements quadrature point positions and build
   /// element-facet quadrature points data structure
   ElementTypeMapArray<Real> elements_quad_facets("elements_quad_facets", id);
 
   elements_quad_facets.initialize(
       mesh, _nb_component = Model::spatial_dimension,
       _spatial_dimension = Model::spatial_dimension);
 
   for (auto elem_gt : ghost_types) {
     for (const auto & type :
          mesh.elementTypes(Model::spatial_dimension, elem_gt)) {
       auto nb_element = mesh.getNbElement(type, elem_gt);
       if (nb_element == 0) {
         continue;
       }
 
       /// compute elements' quadrature points and list of facet
       /// quadrature points positions by element
       const auto & facet_to_element =
           mesh_facets.getSubelementToElement(type, elem_gt);
       auto & el_q_facet = elements_quad_facets(type, elem_gt);
 
       auto facet_type = Mesh::getFacetType(type);
       auto nb_quad_per_facet =
           getFEEngine("FacetsFEEngine").getNbIntegrationPoints(facet_type);
       auto nb_facet_per_elem = facet_to_element.getNbComponent();
 
       // small hack in the loop to skip boundary elements, they are silently
       // initialized to NaN to see if this causes problems
       el_q_facet.resize(nb_element * nb_facet_per_elem * nb_quad_per_facet,
                         std::numeric_limits<Real>::quiet_NaN());
 
       for (auto && data :
            zip(make_view(facet_to_element),
                make_view(el_q_facet, spatial_dimension, nb_quad_per_facet))) {
         const auto & global_facet = std::get<0>(data);
         auto & el_q = std::get<1>(data);
 
         if (global_facet == ElementNull) {
           continue;
         }
 
         auto && quad_f =
             make_view(quad_facets(global_facet.type, global_facet.ghost_type),
                       spatial_dimension, nb_quad_per_facet)
                 .begin()[global_facet.element];
 
         el_q = quad_f;
       }
     }
   }
 
   /// loop over non cohesive materials
   this->for_each_constitutive_law([&](auto && material) {
     if (aka::is_of_type<MaterialCohesive>(material)) {
       return;
     }
     /// initialize the interpolation function
     material.initElementalFieldInterpolation(elements_quad_facets);
   });
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void SolidMechanicsModelCohesive::assembleInternalForces() {
   AKANTU_DEBUG_IN();
 
   // f_int += f_int_cohe
   this->for_each_constitutive_law([&](auto && material) {
     try {
       auto & mat = aka::as_type<MaterialCohesive>(material);
       mat.computeTraction(_not_ghost);
     } catch (std::bad_cast & bce) {
     }
   });
 
-  //  ArrayPrintHelper<true>::ArrayPrintHelper::print_content<bool>(*(this->blocked_dofs),std::cout,0);
   SolidMechanicsModel::assembleInternalForces();
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void SolidMechanicsModelCohesive::computeNormals() {
   AKANTU_DEBUG_IN();
 
   Mesh & mesh_facets = this->inserter->getMeshFacets();
   this->getFEEngine("FacetsFEEngine")
       .computeNormalsOnIntegrationPoints(_not_ghost);
 
   /**
    *  @todo store tangents while computing normals instead of
    *  recomputing them as follows:
    */
   /* ------------------------------------------------------------------------ */
   UInt tangent_components =
       Model::spatial_dimension * (Model::spatial_dimension - 1);
 
   tangents.initialize(mesh_facets, _nb_component = tangent_components,
                       _spatial_dimension = Model::spatial_dimension - 1);
 
   for (auto facet_type :
        mesh_facets.elementTypes(Model::spatial_dimension - 1)) {
     const Array<Real> & normals =
         this->getFEEngine("FacetsFEEngine")
             .getNormalsOnIntegrationPoints(facet_type);
 
     Array<Real> & tangents = this->tangents(facet_type);
 
     Math::compute_tangents(normals, tangents);
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void SolidMechanicsModelCohesive::interpolateStress() {
   ElementTypeMapArray<Real> by_elem_result("temporary_stress_by_facets", id);
 
   this->for_each_constitutive_law([&](auto && material) {
     if (not aka::is_of_type<MaterialCohesive>(material)) {
       /// interpolate stress on facet quadrature points positions
       material.interpolateStressOnFacets(facet_stress, by_elem_result);
     }
   });
 
   this->synchronize(SynchronizationTag::_smmc_facets_stress);
 }
 
 /* -------------------------------------------------------------------------- */
 UInt SolidMechanicsModelCohesive::checkCohesiveStress() {
   AKANTU_DEBUG_IN();
 
   if (not is_extrinsic) {
     AKANTU_EXCEPTION(
         "This function can only be used for extrinsic cohesive elements");
   }
 
   interpolateStress();
 
   this->for_each_constitutive_law([&](auto && material) {
     if (aka::is_of_type<MaterialCohesive>(material)) {
       /// check which not ghost cohesive elements are to be created
       auto & mat_cohesive = aka::as_type<MaterialCohesive>(material);
       mat_cohesive.checkInsertion();
     }
   });
 
   /// insert cohesive elements
   auto nb_new_elements = inserter->insertElements();
 
   AKANTU_DEBUG_OUT();
 
   return nb_new_elements;
 }
 
-/* -------------------------------------------------------------------------- */
-UInt SolidMechanicsModelCohesive::checkCohesiveInsertion() {
-  AKANTU_DEBUG_IN();
-
-  if (not is_extrinsic) {
-    AKANTU_EXCEPTION(
-        "This function can only be used for extrinsic cohesive elements");
-  }
-
-  this->for_each_constitutive_law([&](auto && material) {
-    if (aka::is_of_type<MaterialCohesive>(material)) {
-      /// check which not ghost cohesive elements are to be created
-      auto & mat_cohesive = aka::as_type<MaterialCohesive>(material);
-      mat_cohesive.checkInsertion();
-    }
-  });
-
-  /// insert cohesive elements
-  auto nb_new_elements = inserter->insertElements();
-
-  AKANTU_DEBUG_OUT();
-
-  return nb_new_elements;
-}
-
-/* -------------------------------------------------------------------------- */
-void SolidMechanicsModelCohesive::computeLagrangeMultiplier() {
-  AKANTU_DEBUG_IN();
-
-  if (not is_extrinsic) {
-    AKANTU_EXCEPTION(
-        "This function can only be used for extrinsic cohesive elements");
-  }
-
-  interpolateStress();
-
-  this->for_each_constitutive_law([&](auto && material) {
-    if (aka::is_of_type<MaterialCohesive>(material)) {
-      /// check which not ghost cohesive elements are to be created
-      auto & mat_cohesive = aka::as_type<MaterialCohesive>(material);
-      mat_cohesive.computeLambda();
-    }
-  });
-
-  AKANTU_DEBUG_OUT();
-}
-
-/* -------------------------------------------------------------------------- */
-void SolidMechanicsModelCohesive::computeDamage() {
-  AKANTU_DEBUG_IN();
-
-  this->for_each_constitutive_law([&](auto && material) {
-    if (aka::is_of_type<MaterialCohesiveDamage>(material)) {
-      /// check which not ghost cohesive elements are to be created
-      auto & mat_cohesive = aka::as_type<MaterialCohesiveDamage>(material);
-      mat_cohesive.computeDamage();
-    }
-  });
-
-  AKANTU_DEBUG_OUT();
-}
-
-/* -------------------------------------------------------------------------- */
-void SolidMechanicsModelCohesive::updateLambdaMesh() {
-//    std::cout << " SolidMechanicsModelCohesive::updateLambdaMesh " << std::endl;
-
-  const auto & connectivities = mesh.getConnectivities();
-  const auto & initial_nodes = mesh.getNodalData<Idx>("initial_nodes_match");
-  auto & nodes_to_lambda = mesh.getNodalData<Idx>("nodes_to_lambda");
-  nodes_to_lambda.resize(mesh.getNbNodes(), -1);
-
-  auto & lambda_connectivities = MeshAccessor(*lambda_mesh).getConnectivities();
-
-  auto lambda_id = lambda->size();
-
-  std::vector<Idx> new_nodes;
-
-  NewNodesEvent node_event(*lambda_mesh, AKANTU_CURRENT_FUNCTION);
-  auto & node_list = node_event.getList();
-//  std::cout << "node_list before = " << std::endl ;
-//  ArrayPrintHelper<true>::print_content(node_list,std::cout,0);
-
-  NewElementsEvent element_event(*lambda_mesh, AKANTU_CURRENT_FUNCTION);
-  auto & element_list = element_event.getList();
-//  std::cout << "element_list before = " << std::endl ;
-//  ArrayPrintHelper<true>::print_content(element_list,std::cout,0);
-
-  for (auto ghost_type : ghost_types) {
-    for (auto type : connectivities.elementTypes(_element_kind = _ek_cohesive,
-                     _ghost_type = ghost_type)) {
-      auto underlying_type = Mesh::getFacetType(type);
-
-      auto & connectivity = connectivities(type, ghost_type);
-      auto & lambda_connectivity =
-          lambda_connectivities(underlying_type, ghost_type);
-
-//      std::cout << "connectivity = " << std::endl ;
-//      ArrayPrintHelper<true>::print_content(connectivity,std::cout,0);
-
-//      std::cout << "lambda_connectivity = " << std::endl ;
-//      ArrayPrintHelper<true>::print_content(lambda_connectivity,std::cout,0);
-
-
-      auto nb_new_elements = connectivity.size() - lambda_connectivity.size();
-      auto nb_old_elements = lambda_connectivity.size();
-
-      lambda_connectivity.resize(connectivity.size());
-
-      auto && view_iconn =
-          make_view(connectivity, connectivity.getNbComponent());
-      auto && view_conn =
-          make_view(lambda_connectivity, lambda_connectivity.getNbComponent());
-
-//      std::cout << " connectivity.getNbComponent() " << connectivity.getNbComponent() << std::endl  ;
-//      std::cout << " lambda_connectivity.getNbComponent() " << lambda_connectivity.getNbComponent() << std::endl  ;
-
-//      for (auto && [conn, lambda_conn] :
-//           zip(range(view_iconn.begin() + nb_old_elements, view_iconn.end()),
-//               range(view_conn.begin() + nb_old_elements, view_conn.end()))) {
-//          std::cout << "conn = " << conn << std::endl ;
-//          std::cout << "lambda_conn = " << lambda_conn << std::endl ;
-
-//        for (auto && [n, lambda_node] : enumerate(lambda_conn)) {
-//            std::cout << "n = " << n << std::endl ;
-//          auto node = conn[n];
-//          std::cout << "node conn= " << node << std::endl ;
-
-//          node = initial_nodes(node);
-//          std::cout << "node initial_nodes = " << node << std::endl ;
-
-//          auto & ntl = nodes_to_lambda(node);
-//          std::cout << "ntl = " << ntl << std::endl ;
-
-//          if (ntl == -1) {
-//            ntl = lambda_id;
-//            new_nodes.push_back(node);
-//            node_list.push_back(lambda_id);
-//            ++lambda_id;
-//          }
-
-//          lambda_node = ntl;
-//        }
-//      }
-
-      for (auto && [conn, lambda_conn] :
-           zip(range(view_iconn.begin() + nb_old_elements, view_iconn.end()),
-               range(view_conn.begin() + nb_old_elements, view_conn.end()))) {
-//          std::cout << "conn = " << conn << std::endl ;
-//          std::cout << "lambda_conn = " << lambda_conn << std::endl ;
-
-        for (auto && [n, lambda_node] : enumerate(lambda_conn)) {
-//            std::cout << "n = " << n << std::endl ;
-          auto node = conn[n];
-//          std::cout << "node conn= " << node << std::endl ;
-
-          node = initial_nodes(node);
-//          std::cout << "node initial_nodes = " << node << std::endl ;
-
-          auto & ntl = nodes_to_lambda(node);
-//          std::cout << "ntl = " << ntl << std::endl ;
-
-//          if (ntl == -1) {
-            ntl = lambda_id;
-            new_nodes.push_back(node);
-            node_list.push_back(lambda_id);
-            ++lambda_id;
-//          }
-
-          lambda_node = ntl;
-        }
-      }
-
-      for (auto && el : arange(nb_old_elements, nb_new_elements)) {
-//          std::cout << "el = " << el << std::endl ;
-        element_list.push_back({underlying_type, el, ghost_type});
-      }
-    }
-  }
-
-//  std::cout << "node_list after = " << std::endl ;
-//  ArrayPrintHelper<true>::print_content(node_list,std::cout,0);
-
-//  std::cout << "element_list after = " << std::endl ;
-//  ArrayPrintHelper<true>::print_content(element_list,std::cout,0);
-
-  lambda_mesh->copyNodes(mesh, new_nodes);
-
-  lambda->resize(lambda_id, 0.);
-  lambda_increment->resize(lambda_id, 0.);
-  previous_lambda->resize(lambda_id, 0.);
-
-  lambda_mesh->sendEvent(element_event);
-  lambda_mesh->sendEvent(node_event);
-}
-
 /* -------------------------------------------------------------------------- */
 void SolidMechanicsModelCohesive::onElementsAdded(
     const Array<Element> & element_list, const NewElementsEvent & event) {
   AKANTU_DEBUG_IN();
-
-//  std::cout << " SolidMechanicsModelCohesive::onElementsAdded " << std::endl;
-
   SolidMechanicsModel::onElementsAdded(element_list, event);
 
-  if (lambda) {
-    auto & lambda_connectivities =
-        MeshAccessor(*lambda_mesh).getConnectivities();
-
-    for (auto ghost_type : ghost_types) {
-      for (auto type : mesh.elementTypes(_element_kind = _ek_cohesive,
-                       _ghost_type = ghost_type)) {
-        auto underlying_type = Mesh::getFacetType(type);
-        if (not lambda_connectivities.exists(underlying_type, ghost_type)) {
-          auto nb_nodes_per_element =
-              Mesh::getNbNodesPerElement(underlying_type);
-          lambda_connectivities.alloc(0, nb_nodes_per_element, underlying_type,
-                                      ghost_type, -1);
-        }
-      }
-    }
-  }
-
   if (is_extrinsic) {
     resizeFacetStress();
   }
 
   AKANTU_DEBUG_OUT();
 }
 
+/* -------------------------------------------------------------------------- */
 /* -------------------------------------------------------------------------- */
 void SolidMechanicsModelCohesive::onNodesAdded(const Array<Idx> & new_nodes,
                                                const NewNodesEvent & event) {
-  SolidMechanicsModel::onNodesAdded(new_nodes, event);
-
-  auto & initial_nodes = mesh.getNodalData<Idx>("initial_nodes_match");
+  AKANTU_DEBUG_IN();
 
-  auto old_max_nodes = initial_nodes.size();
-  initial_nodes.resize(mesh.getNbNodes(), -1);
+  SolidMechanicsModel::onNodesAdded(new_nodes, event);
 
   const auto * cohesive_event =
       dynamic_cast<const CohesiveNewNodesEvent *>(&event);
   if (cohesive_event == nullptr) {
-    for (auto && node : new_nodes) {
-      initial_nodes(node) = node;
-    }
     return;
   }
 
-  auto old_nodes = cohesive_event->getOldNodesList();
+  const auto & old_nodes = cohesive_event->getOldNodesList();
 
-  // getting a corrected old_nodes for multiple doubling
-  for (auto & onode : old_nodes) {
-    while (onode >= old_max_nodes) {
-      auto nnode = new_nodes.find(onode);
-      AKANTU_DEBUG_ASSERT(nnode != -1,
-                          "If the old node is bigger than old_max_nodes it "
-                          "should also be a new node");
-      onode = nnode;
-    }
-  }
-
-  auto copy = [&new_nodes, &old_nodes](auto & arr) {
-    auto it = make_view(arr, arr.getNbComponent()).begin();
+  auto copy = [this, &new_nodes, &old_nodes](auto & arr) {
+    auto it = make_view(arr, spatial_dimension).begin();
     for (auto [new_node, old_node] : zip(new_nodes, old_nodes)) {
       it[new_node] = it[old_node];
     }
   };
 
-  for (auto && ptr : {displacement.get(), velocity.get(), acceleration.get(),
-                      current_position.get(), previous_displacement.get(),
-                      displacement_increment.get()}) {
-    if (ptr != nullptr) {
-      copy(*ptr);
-    }
+  copy(*displacement);
+  copy(*blocked_dofs);
+
+  if (velocity) {
+    copy(*velocity);
   }
 
-  copy(*blocked_dofs);
-  copy(getDOFManager().getSolution("displacement"));
-  copy(initial_nodes);
+  if (acceleration) {
+    copy(*acceleration);
+  }
+
+  if (current_position) {
+    copy(*current_position);
+  }
+
+  if (previous_displacement) {
+    copy(*previous_displacement);
+  }
 
-  // correct connectivities
-  if (lambda) {
-    lambda_blocked_dofs->resize(mesh.getNbNodes(), false);
-    copy(*lambda_blocked_dofs);
-    updateLambdaMesh();
+  if (displacement_increment) {
+    copy(*displacement_increment);
   }
+
+  copy(getDOFManager().getSolution("displacement"));
+
+  AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void SolidMechanicsModelCohesive::afterSolveStep(bool converged) {
   /*
    * This is required because the Cauchy stress is the stress measure that
    * is used to check the insertion of cohesive elements
    */
   if (converged) {
     this->for_each_constitutive_law([](auto && mat) {
       if (mat.isFiniteDeformation()) {
         mat.computeAllCauchyStresses(_not_ghost);
       }
     });
   }
 
   SolidMechanicsModel::afterSolveStep(converged);
 }
 
-/* -------------------------------------------------------------------------- */
-ModelSolverOptions SolidMechanicsModelCohesive::getDefaultSolverOptions(
-    const TimeStepSolverType & type) const {
-  ModelSolverOptions options =
-      SolidMechanicsModel::getDefaultSolverOptions(type);
-
-    if (lambda) {
-//  if (true) {
-    switch (type) {
-    case TimeStepSolverType::_dynamic_lumped: {
-      options.non_linear_solver_type = NonLinearSolverType::_lumped;
-      options.integration_scheme_type["lambda"] =
-          IntegrationSchemeType::_central_difference;
-      options.solution_type["lambda"] = IntegrationScheme::_acceleration;
-      break;
-    }
-    case TimeStepSolverType::_static: {
-      options.non_linear_solver_type = NonLinearSolverType::_newton_raphson;
-      options.integration_scheme_type["lambda"] =
-          IntegrationSchemeType::_pseudo_time;
-      options.solution_type["lambda"] = IntegrationScheme::_not_defined;
-      break;
-    }
-    case TimeStepSolverType::_dynamic: {
-      if (this->method == _explicit_consistent_mass) {
-        options.non_linear_solver_type = NonLinearSolverType::_newton_raphson;
-        options.integration_scheme_type["lambda"] =
-            IntegrationSchemeType::_central_difference;
-        options.solution_type["lambda"] = IntegrationScheme::_acceleration;
-      } else {
-        options.non_linear_solver_type = NonLinearSolverType::_newton_raphson;
-        options.integration_scheme_type["lambda"] =
-            IntegrationSchemeType::_trapezoidal_rule_2;
-        options.solution_type["lambda"] = IntegrationScheme::_displacement;
-      }
-      break;
-    }
-    default:
-      AKANTU_EXCEPTION(type << " is not a valid time step solver type");
-    }
-  }
-  return options;
-}
-
 /* -------------------------------------------------------------------------- */
 void SolidMechanicsModelCohesive::printself(std::ostream & stream,
                                             int indent) const {
   std::string space(indent, AKANTU_INDENT);
 
   stream << space << "SolidMechanicsModelCohesive ["
          << "\n";
   SolidMechanicsModel::printself(stream, indent + 2);
   stream << space << "]\n";
 }
 
 /* -------------------------------------------------------------------------- */
 void SolidMechanicsModelCohesive::resizeFacetStress() {
   AKANTU_DEBUG_IN();
 
   this->facet_stress.initialize(getFEEngine("FacetsFEEngine"),
                                 _nb_component =
                                     2 * spatial_dimension * spatial_dimension,
                                 _spatial_dimension = spatial_dimension - 1);
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void SolidMechanicsModelCohesive::addDumpGroupFieldToDumper(
     const std::string & dumper_name, const std::string & field_id,
     const std::string & group_name, ElementKind element_kind,
     bool padding_flag) {
   AKANTU_DEBUG_IN();
 
   Int spatial_dimension = Model::spatial_dimension;
   ElementKind _element_kind = element_kind;
   if (dumper_name == "cohesive elements") {
     _element_kind = _ek_cohesive;
   } else if (dumper_name == "facets") {
     spatial_dimension = Model::spatial_dimension - 1;
   }
 
   SolidMechanicsModel::addDumpGroupFieldToDumper(dumper_name, field_id,
                                                  group_name, spatial_dimension,
                                                  _element_kind, padding_flag);
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void SolidMechanicsModelCohesive::onDump() {
   this->flattenAllRegisteredInternals(_ek_cohesive);
   SolidMechanicsModel::onDump();
 }
 
 /* -------------------------------------------------------------------------- */
 
 } // namespace akantu
diff --git a/src/model/solid_mechanics/solid_mechanics_model_cohesive/solid_mechanics_model_cohesive.hh b/src/model/solid_mechanics/solid_mechanics_model_cohesive/solid_mechanics_model_cohesive.hh
index fadac8a49..59bb582da 100644
--- a/src/model/solid_mechanics/solid_mechanics_model_cohesive/solid_mechanics_model_cohesive.hh
+++ b/src/model/solid_mechanics/solid_mechanics_model_cohesive/solid_mechanics_model_cohesive.hh
@@ -1,357 +1,292 @@
 /**
  * Copyright (©) 2012-2023 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * This file is part of Akantu
  *
  * Akantu is free software: you can redistribute it and/or modify it under the
  * terms of the GNU Lesser General Public License as published by the Free
  * Software Foundation, either version 3 of the License, or (at your option) any
  * later version.
  *
  * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
  * details.
  *
  * You should have received a copy of the GNU Lesser General Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  */
 
 /* -------------------------------------------------------------------------- */
 #include "cohesive_element_inserter.hh"
 #include "material_selector_cohesive.hh"
 #include "random_internal_field.hh" // included to have the specialization of
                                     // ParameterTyped::operator Real()
 #include "solid_mechanics_model.hh"
 /* -------------------------------------------------------------------------- */
 
 #ifndef AKANTU_SOLID_MECHANICS_MODEL_COHESIVE_HH_
 #define AKANTU_SOLID_MECHANICS_MODEL_COHESIVE_HH_
 
 /* -------------------------------------------------------------------------- */
 namespace akantu {
 class FacetSynchronizer;
 class FacetStressSynchronizer;
 class ElementSynchronizer;
 } // namespace akantu
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 struct FacetsCohesiveIntegrationOrderFunctor {
   template <ElementType type, ElementType cohesive_type =
                                   CohesiveFacetProperty<type>::cohesive_type>
   struct _helper {
     static constexpr int get() {
 //      return 1;
         return ElementClassProperty<cohesive_type>::polynomial_degree;
     }
   };
 
   template <ElementType type> struct _helper<type, _not_defined> {
     static constexpr int get() {
         //      return 1;
         return ElementClassProperty<type>::polynomial_degree;    }
   };
 
   template <ElementType type> static inline constexpr int getOrder() {
     return _helper<type>::get();
   }
 };
 
-/* -------------------------------------------------------------------------- */
-struct CohesiveIntegrationOrderFunctor {
-  template <ElementType type, ElementType cohesive_type =
-                                  CohesiveFacetProperty<type>::cohesive_type>
-  struct _helper {
-    static constexpr int get() {
-        //      return 1;
-        return ElementClassProperty<cohesive_type>::polynomial_degree;    }
-  };
-
-  template <ElementType type> struct _helper<type, _not_defined> {
-    static constexpr int get() {
-        //      return 1;
-        return ElementClassProperty<type>::polynomial_degree;    }
-  };
-
-  template <ElementType type> static inline constexpr int getOrder() {
-    return _helper<type>::get();
-  }
-};
-
 /* -------------------------------------------------------------------------- */
 /* Solid Mechanics Model for Cohesive elements                                */
 /* -------------------------------------------------------------------------- */
 class SolidMechanicsModelCohesive : public SolidMechanicsModel,
                                     public SolidMechanicsModelEventHandler {
   /* ------------------------------------------------------------------------ */
   /* Constructors/Destructors                                                 */
   /* ------------------------------------------------------------------------ */
 public:
   class NewCohesiveNodesEvent : public NewNodesEvent {
   public:
     AKANTU_GET_MACRO_NOT_CONST(OldNodesList, old_nodes, Array<UInt> &);
     AKANTU_GET_MACRO(OldNodesList, old_nodes, const Array<UInt> &);
 
   protected:
     Array<UInt> old_nodes;
   };
 
   using MyFEEngineCohesiveType =
       FEEngineTemplate<IntegratorGauss, ShapeLagrange, _ek_cohesive>;
   using MyFEEngineFacetType =
       FEEngineTemplate<IntegratorGauss, ShapeLagrange, _ek_regular,
                        FacetsCohesiveIntegrationOrderFunctor>;
-  using MyFEEngineLambdaType =
-      FEEngineTemplate<IntegratorGauss, ShapeLagrange, _ek_regular,
-                       FacetsCohesiveIntegrationOrderFunctor>;
 
   SolidMechanicsModelCohesive(
       Mesh & mesh, Int dim = _all_dimensions,
       const ID & id = "solid_mechanics_model_cohesive",
       const std::shared_ptr<DOFManager> & dof_manager = nullptr);
 
   /* ------------------------------------------------------------------------ */
   /* Methods                                                                  */
   /* ------------------------------------------------------------------------ */
 protected:
   /// initialize the cohesive model
   void initFullImpl(const ModelOptions & options) override;
 
 public:
   /// set the value of the time step
   void setTimeStep(Real time_step, const ID & solver_id = "") override;
 
   /// assemble the residual for the explicit scheme
   void assembleInternalForces() override;
 
   /// function to perform a stress check on each facet and insert
   /// cohesive elements if needed (returns the number of new cohesive
   /// elements)
   UInt checkCohesiveStress();
 
-  /// function to perform an insertion check on each facet and insert
-  /// cohesive elements if needed (returns the number of new cohesive
-  /// elements)
-  UInt checkCohesiveInsertion();
-
   /// interpolate stress on facets
   void interpolateStress();
 
   /// update automatic insertion after a change in the element inserter
   void updateAutomaticInsertion();
 
   /// insert intrinsic cohesive elements
   void insertIntrinsicElements();
 
-  /// compute Lagrange multiplier
-  void computeLagrangeMultiplier();
-
-  /// compute damage variable
-  void computeDamage();
-
   // template <SolveConvergenceMethod cmethod, SolveConvergenceCriteria
   // criteria> bool solveStepCohesive(Real tolerance, Real & error, UInt
   // max_iteration = 100,
   //                        bool load_reduction = false,
   //                        Real tol_increase_factor = 1.0,
   //                        bool do_not_factorize = false);
 
 protected:
   /// initialize stress interpolation
   void initStressInterpolation();
 
   /// initialize the model
   void initModel() override;
 
   /// initialize cohesive material
   void initConstitutiveLaws() override;
 
   /// init facet filters for cohesive materials
   void initFacetFilter();
 
   /// function to print the contain of the class
   void printself(std::ostream & stream, int indent = 0) const override;
 
-private:
+protected:
   /// insert cohesive elements along a given physical surface of the mesh
   void insertElementsFromMeshData(const std::string & physical_name);
 
   /// initialize completely the model for extrinsic elements
   void initAutomaticInsertion();
 
   /// compute facets' normals
   void computeNormals();
 
   /// resize facet stress
   void resizeFacetStress();
 
   /// init facets_check array
   void initFacetsCheck();
 
   /* ------------------------------------------------------------------------ */
   /* Mesh Event Handler inherited members                                     */
   /* ------------------------------------------------------------------------ */
 
 protected:
   void onNodesAdded(const Array<Idx> & new_nodes,
                     const NewNodesEvent & event) override;
   void onElementsAdded(const Array<Element> & element_list,
                        const NewElementsEvent & event) override;
 
   /* ------------------------------------------------------------------------ */
   /* SolidMechanicsModelEventHandler inherited members                        */
   /* ------------------------------------------------------------------------ */
 public:
   void afterSolveStep(bool converged = true) override;
 
-  [[nodiscard]] ModelSolverOptions
-  getDefaultSolverOptions(const TimeStepSolverType & type) const override;
-
   /* ------------------------------------------------------------------------ */
   /* Dumpable interface                                                       */
   /* ------------------------------------------------------------------------ */
 public:
   void onDump() override;
 
   void addDumpGroupFieldToDumper(const std::string & dumper_name,
                                  const std::string & field_id,
                                  const std::string & group_name,
                                  ElementKind element_kind,
                                  bool padding_flag) override;
 
 protected:
+  // void synchronizeGhostFacetsConnectivity();
+
   void updateCohesiveSynchronizers(NewElementsEvent & elements_event);
   void updateFacetStressSynchronizer();
 
   friend class CohesiveElementInserter;
 
   /* ------------------------------------------------------------------------ */
   /* Data Accessor inherited members                                          */
   /* ------------------------------------------------------------------------ */
 public:
   [[nodiscard]] Int getNbData(const Array<Element> & elements,
                               const SynchronizationTag & tag) const override;
 
   void packData(CommunicationBuffer & buffer, const Array<Element> & elements,
                 const SynchronizationTag & tag) const override;
 
   void unpackData(CommunicationBuffer & buffer, const Array<Element> & elements,
                   const SynchronizationTag & tag) override;
 
 protected:
   [[nodiscard]] Int
   getNbQuadsForFacetCheck(const Array<Element> & elements) const;
 
   template <typename T>
   void packFacetStressDataHelper(const ElementTypeMapArray<T> & data_to_pack,
                                  CommunicationBuffer & buffer,
                                  const Array<Element> & elements) const;
 
   template <typename T>
   void unpackFacetStressDataHelper(ElementTypeMapArray<T> & data_to_unpack,
                                    CommunicationBuffer & buffer,
                                    const Array<Element> & elements) const;
 
   template <typename T, bool pack_helper>
   void packUnpackFacetStressDataHelper(
       std::conditional_t<pack_helper, const ElementTypeMapArray<T>,
                          ElementTypeMapArray<T>> & data_to_pack,
       CommunicationBuffer & buffer, const Array<Element> & element) const;
 
-  void updateLambdaMesh();
-
   /* ------------------------------------------------------------------------ */
   /* Accessors                                                                */
   /* ------------------------------------------------------------------------ */
 public:
   /// get facet mesh
   AKANTU_GET_MACRO_AUTO(MeshFacets, mesh.getMeshFacets());
 
   /// get stress on facets vector
   AKANTU_GET_MACRO_BY_ELEMENT_TYPE_CONST(StressOnFacets, facet_stress, Real);
 
   /// get facet material
   AKANTU_GET_MACRO_BY_ELEMENT_TYPE(FacetMaterial, facet_material, Idx);
 
   /// get facet material
   AKANTU_GET_MACRO_BY_ELEMENT_TYPE_CONST(FacetMaterial, facet_material, Idx);
 
   /// get facet material
   AKANTU_GET_MACRO_AUTO(FacetMaterial, facet_material);
 
   /// @todo THIS HAS TO BE CHANGED
   AKANTU_GET_MACRO_BY_ELEMENT_TYPE_CONST(Tangents, tangents, Real);
 
   /// get element inserter
   AKANTU_GET_MACRO_NOT_CONST(ElementInserter, *inserter,
                              CohesiveElementInserter &);
 
   /// get is_extrinsic boolean
   AKANTU_GET_MACRO(IsExtrinsic, is_extrinsic, bool);
 
   /// get cohesive elements synchronizer
   AKANTU_GET_MACRO_NOT_CONST(CohesiveSynchronizer, *cohesive_synchronizer,
                              ElementSynchronizer &);
 
-  /// get the SolidMechanicsModel::lambda array
-  AKANTU_GET_MACRO_DEREF_PTR_NOT_CONST(Lambda, lambda);
-  /// get the SolidMechanicsModel::displacement array
-  AKANTU_GET_MACRO_DEREF_PTR(Lambda, lambda);
-
-  /// get lambda mesh
-  const Mesh & getLambdaMesh() {
-    if (not lambda_mesh) {
-      AKANTU_EXCEPTION("This model does not have a lambda mesh");
-    }
-    return *lambda_mesh;
-  }
-
   /* ------------------------------------------------------------------------ */
   /* Class Members                                                            */
   /* ------------------------------------------------------------------------ */
-private:
+protected:
   friend class CohesiveMeshGlobalDataUpdater;
 
-  /// lambda array
-  std::unique_ptr<Array<Real>> lambda;
-
-  /// lambda array at the previous time step
-  std::unique_ptr<Array<Real>> previous_lambda;
-
-  /// increment of lambda
-  std::unique_ptr<Array<Real>> lambda_increment;
-
-  /// array specifing if a lambda degree of freedom is blocked or not
-  std::unique_ptr<Array<bool>> lambda_blocked_dofs;
-
   /// @todo store tangents when normals are computed:
   ElementTypeMapArray<Real> tangents;
 
   /// stress on facets on the two sides by quadrature point
   ElementTypeMapArray<Real> facet_stress;
 
   /// material to use if a cohesive element is created on a facet
   ElementTypeMapArray<Idx> facet_material;
 
   bool is_extrinsic{false};
 
   /// cohesive element inserter
   std::unique_ptr<CohesiveElementInserter> inserter;
 
   /// facet stress synchronizer
   std::unique_ptr<ElementSynchronizer> facet_stress_synchronizer;
 
   /// cohesive elements synchronizer
   std::unique_ptr<ElementSynchronizer> cohesive_synchronizer;
-
-  std::unique_ptr<Mesh> lambda_mesh;
 };
 
 } // namespace akantu
 
 #include "solid_mechanics_model_cohesive_inline_impl.hh"
 
 #endif /* AKANTU_SOLID_MECHANICS_MODEL_COHESIVE_HH_ */
diff --git a/src/model/solid_mechanics/solid_mechanics_model_cohesive/solid_mechanics_model_cohesive_damage.cc b/src/model/solid_mechanics/solid_mechanics_model_cohesive/solid_mechanics_model_cohesive_damage.cc
new file mode 100644
index 000000000..dc465e0aa
--- /dev/null
+++ b/src/model/solid_mechanics/solid_mechanics_model_cohesive/solid_mechanics_model_cohesive_damage.cc
@@ -0,0 +1,505 @@
+/**
+ * Copyright (©) 2012-2023 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ *
+ * This file is part of Akantu
+ *
+ * Akantu is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation, either version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/* -------------------------------------------------------------------------- */
+#include "solid_mechanics_model_cohesive_damage.hh"
+#include "aka_iterators.hh"
+#include "cohesive_element_inserter.hh"
+#include "element_synchronizer.hh"
+#include "facet_synchronizer.hh"
+#include "fe_engine_template.hh"
+#include "global_ids_updater.hh"
+#include "integrator_gauss.hh"
+#include "material_cohesive_damage.hh"
+#include "mesh_accessor.hh"
+#include "mesh_global_data_updater.hh"
+#include "parser.hh"
+#include "shape_cohesive.hh"
+/* -------------------------------------------------------------------------- */
+#include "dumper_iohelper_paraview.hh"
+/* -------------------------------------------------------------------------- */
+#include <algorithm>
+/* -------------------------------------------------------------------------- */
+
+namespace akantu {
+
+/* -------------------------------------------------------------------------- */
+SolidMechanicsModelCohesiveDamage::SolidMechanicsModelCohesiveDamage(
+    Mesh & mesh, Int dim, const ID & id,
+    const std::shared_ptr<DOFManager> & dof_manager)
+    : SolidMechanicsModelCohesive(mesh, dim, id, dof_manager)
+{}
+
+/* -------------------------------------------------------------------------- */
+void SolidMechanicsModelCohesiveDamage::initConstitutiveLaws() {
+  AKANTU_DEBUG_IN();
+
+  // make sure the material are instantiated
+  instantiateMaterials();
+
+  auto & material_selector = this->getConstitutiveLawSelector();
+
+  // set the facet information in the material in case of dynamic insertion
+  // to know what material to call for stress checks
+  const Mesh & mesh_facets = inserter->getMeshFacets();
+  facet_material.initialize(
+      mesh_facets, _spatial_dimension = spatial_dimension - 1,
+      _with_nb_element = true,
+      _default_value =
+          DefaultMaterialCohesiveSelector::getDefaultCohesiveMaterial(*this));
+
+  for_each_element(
+      mesh_facets,
+      [&](auto && element) {
+        auto mat_index = material_selector(element);
+        if (not mat_index) {
+          return;
+        }
+        auto & mat =
+            aka::as_type<MaterialCohesive>(this->getConstitutiveLaw(mat_index));
+
+        facet_material(element) = mat_index;
+        if (is_extrinsic) {
+          mat.addFacet(element);
+        }
+      },
+      _spatial_dimension = spatial_dimension - 1, _ghost_type = _not_ghost);
+
+  SolidMechanicsModel::initConstitutiveLaws();
+
+  auto & initial_nodes = mesh.getNodalData<Idx>("initial_nodes_match");
+  initial_nodes.resize(mesh.getNbNodes());
+  for (auto && [node, init_node] : enumerate(initial_nodes)) {
+    init_node = node;
+  }
+
+  auto need_lambda = false;
+
+  this->for_each_constitutive_law([&need_lambda](auto && material) {
+    if (aka::is_of_type<MaterialCohesive>(material)) {
+      need_lambda |= aka::as_type<MaterialCohesive>(material).needLambda();
+    }
+  });
+
+  if (need_lambda) {
+    lambda =
+        std::make_unique<Array<Real>>(0, spatial_dimension, "cohesive lambda");
+    previous_lambda =
+        std::make_unique<Array<Real>>(0, spatial_dimension, "previous lambda");
+    lambda_increment =
+        std::make_unique<Array<Real>>(0, spatial_dimension, "lambda increment");
+    lambda_blocked_dofs = std::make_unique<Array<bool>>(0, spatial_dimension,
+                                                        "lambda_blocked_dofs");
+
+    lambda_mesh = std::make_unique<Mesh>(spatial_dimension,
+                                         mesh.getCommunicator(), "lambda_mesh");
+    registerFEEngineObject<MyFEEngineLambdaType>("LambdaFEEngine", *lambda_mesh,
+                                                 Model::spatial_dimension - 1);
+
+    auto & nodes_to_lambda = mesh.getNodalData<Idx>("nodes_to_lambda");
+    nodes_to_lambda.resize(mesh.getNbNodes(), -1);
+  }
+
+  if (is_extrinsic) {
+    this->initAutomaticInsertion();
+  } else {
+    this->insertIntrinsicElements();
+  }
+
+  if (lambda) {
+    auto & dof_manager = this->getDOFManager();
+    if (!dof_manager.hasDOFs("lambda")) {
+      dof_manager.registerDOFs("lambda", *this->lambda, *lambda_mesh);
+      dof_manager.registerDOFsIncrement("lambda", *this->lambda_increment);
+      dof_manager.registerDOFsPrevious("lambda", *this->previous_lambda);
+      dof_manager.registerBlockedDOFs("lambda", *this->lambda_blocked_dofs);
+    }
+  }
+
+  AKANTU_DEBUG_OUT();
+} // namespace akantu
+
+/* -------------------------------------------------------------------------- */
+UInt SolidMechanicsModelCohesiveDamage::checkCohesiveInsertion() {
+  AKANTU_DEBUG_IN();
+
+  if (not is_extrinsic) {
+    AKANTU_EXCEPTION(
+        "This function can only be used for extrinsic cohesive elements");
+  }
+
+  this->for_each_constitutive_law([&](auto && material) {
+    if (aka::is_of_type<MaterialCohesive>(material)) {
+      /// check which not ghost cohesive elements are to be created
+      auto & mat_cohesive = aka::as_type<MaterialCohesive>(material);
+      mat_cohesive.checkInsertion();
+    }
+  });
+
+  /// insert cohesive elements
+  auto nb_new_elements = inserter->insertElements();
+
+  AKANTU_DEBUG_OUT();
+
+  return nb_new_elements;
+}
+
+/* -------------------------------------------------------------------------- */
+void SolidMechanicsModelCohesiveDamage::computeLagrangeMultiplier() {
+  AKANTU_DEBUG_IN();
+
+  if (not is_extrinsic) {
+    AKANTU_EXCEPTION(
+        "This function can only be used for extrinsic cohesive elements");
+  }
+
+  interpolateStress();
+
+  this->for_each_constitutive_law([&](auto && material) {
+    if (aka::is_of_type<MaterialCohesive>(material)) {
+      /// check which not ghost cohesive elements are to be created
+      auto & mat_cohesive = aka::as_type<MaterialCohesive>(material);
+      mat_cohesive.computeLambda();
+    }
+  });
+
+  AKANTU_DEBUG_OUT();
+}
+
+/* -------------------------------------------------------------------------- */
+void SolidMechanicsModelCohesiveDamage::computeDamage() {
+  AKANTU_DEBUG_IN();
+
+  this->for_each_constitutive_law([&](auto && material) {
+    if (aka::is_of_type<MaterialCohesiveDamage>(material)) {
+      /// check which not ghost cohesive elements are to be created
+      auto & mat_cohesive = aka::as_type<MaterialCohesiveDamage>(material);
+      mat_cohesive.computeDamage();
+    }
+  });
+
+  AKANTU_DEBUG_OUT();
+}
+
+/* -------------------------------------------------------------------------- */
+void SolidMechanicsModelCohesiveDamage::updateLambdaMesh() {
+//    std::cout << " SolidMechanicsModelCohesiveDamage::updateLambdaMesh " << std::endl;
+
+  const auto & connectivities = mesh.getConnectivities();
+  const auto & initial_nodes = mesh.getNodalData<Idx>("initial_nodes_match");
+  auto & nodes_to_lambda = mesh.getNodalData<Idx>("nodes_to_lambda");
+  nodes_to_lambda.resize(mesh.getNbNodes(), -1);
+
+  auto & lambda_connectivities = MeshAccessor(*lambda_mesh).getConnectivities();
+
+  auto lambda_id = lambda->size();
+
+  std::vector<Idx> new_nodes;
+
+  NewNodesEvent node_event(*lambda_mesh, AKANTU_CURRENT_FUNCTION);
+  auto & node_list = node_event.getList();
+//  std::cout << "node_list before = " << std::endl ;
+//  ArrayPrintHelper<true>::print_content(node_list,std::cout,0);
+
+  NewElementsEvent element_event(*lambda_mesh, AKANTU_CURRENT_FUNCTION);
+  auto & element_list = element_event.getList();
+//  std::cout << "element_list before = " << std::endl ;
+//  ArrayPrintHelper<true>::print_content(element_list,std::cout,0);
+
+  for (auto ghost_type : ghost_types) {
+    for (auto type : connectivities.elementTypes(_element_kind = _ek_cohesive,
+                     _ghost_type = ghost_type)) {
+      auto underlying_type = Mesh::getFacetType(type);
+
+      auto & connectivity = connectivities(type, ghost_type);
+      auto & lambda_connectivity =
+          lambda_connectivities(underlying_type, ghost_type);
+
+//      std::cout << "connectivity = " << std::endl ;
+//      ArrayPrintHelper<true>::print_content(connectivity,std::cout,0);
+
+//      std::cout << "lambda_connectivity = " << std::endl ;
+//      ArrayPrintHelper<true>::print_content(lambda_connectivity,std::cout,0);
+
+
+      auto nb_new_elements = connectivity.size() - lambda_connectivity.size();
+      auto nb_old_elements = lambda_connectivity.size();
+
+      lambda_connectivity.resize(connectivity.size());
+
+      auto && view_iconn =
+          make_view(connectivity, connectivity.getNbComponent());
+      auto && view_conn =
+          make_view(lambda_connectivity, lambda_connectivity.getNbComponent());
+
+//      std::cout << " connectivity.getNbComponent() " << connectivity.getNbComponent() << std::endl  ;
+//      std::cout << " lambda_connectivity.getNbComponent() " << lambda_connectivity.getNbComponent() << std::endl  ;
+
+//      for (auto && [conn, lambda_conn] :
+//           zip(range(view_iconn.begin() + nb_old_elements, view_iconn.end()),
+//               range(view_conn.begin() + nb_old_elements, view_conn.end()))) {
+//          std::cout << "conn = " << conn << std::endl ;
+//          std::cout << "lambda_conn = " << lambda_conn << std::endl ;
+
+//        for (auto && [n, lambda_node] : enumerate(lambda_conn)) {
+//            std::cout << "n = " << n << std::endl ;
+//          auto node = conn[n];
+//          std::cout << "node conn= " << node << std::endl ;
+
+//          node = initial_nodes(node);
+//          std::cout << "node initial_nodes = " << node << std::endl ;
+
+//          auto & ntl = nodes_to_lambda(node);
+//          std::cout << "ntl = " << ntl << std::endl ;
+
+//          if (ntl == -1) {
+//            ntl = lambda_id;
+//            new_nodes.push_back(node);
+//            node_list.push_back(lambda_id);
+//            ++lambda_id;
+//          }
+
+//          lambda_node = ntl;
+//        }
+//      }
+
+      for (auto && [conn, lambda_conn] :
+           zip(range(view_iconn.begin() + nb_old_elements, view_iconn.end()),
+               range(view_conn.begin() + nb_old_elements, view_conn.end()))) {
+//          std::cout << "conn = " << conn << std::endl ;
+//          std::cout << "lambda_conn = " << lambda_conn << std::endl ;
+
+        for (auto && [n, lambda_node] : enumerate(lambda_conn)) {
+//            std::cout << "n = " << n << std::endl ;
+          auto node = conn[n];
+//          std::cout << "node conn= " << node << std::endl ;
+
+          node = initial_nodes(node);
+//          std::cout << "node initial_nodes = " << node << std::endl ;
+
+          auto & ntl = nodes_to_lambda(node);
+//          std::cout << "ntl = " << ntl << std::endl ;
+
+//          if (ntl == -1) {
+            ntl = lambda_id;
+            new_nodes.push_back(node);
+            node_list.push_back(lambda_id);
+            ++lambda_id;
+//          }
+
+          lambda_node = ntl;
+        }
+      }
+
+      for (auto && el : arange(nb_old_elements, nb_new_elements)) {
+//          std::cout << "el = " << el << std::endl ;
+        element_list.push_back({underlying_type, el, ghost_type});
+      }
+    }
+  }
+
+//  std::cout << "node_list after = " << std::endl ;
+//  ArrayPrintHelper<true>::print_content(node_list,std::cout,0);
+
+//  std::cout << "element_list after = " << std::endl ;
+//  ArrayPrintHelper<true>::print_content(element_list,std::cout,0);
+
+  lambda_mesh->copyNodes(mesh, new_nodes);
+
+  lambda->resize(lambda_id, 0.);
+  lambda_increment->resize(lambda_id, 0.);
+  previous_lambda->resize(lambda_id, 0.);
+
+  lambda_mesh->sendEvent(element_event);
+  lambda_mesh->sendEvent(node_event);
+}
+
+/* -------------------------------------------------------------------------- */
+void SolidMechanicsModelCohesiveDamage::onElementsAdded(
+    const Array<Element> & element_list, const NewElementsEvent & event) {
+  AKANTU_DEBUG_IN();
+
+//  std::cout << " SolidMechanicsModelCohesiveDamage::onElementsAdded " << std::endl;
+
+  SolidMechanicsModel::onElementsAdded(element_list, event);
+
+  if (lambda) {
+    auto & lambda_connectivities =
+        MeshAccessor(*lambda_mesh).getConnectivities();
+
+    for (auto ghost_type : ghost_types) {
+      for (auto type : mesh.elementTypes(_element_kind = _ek_cohesive,
+                       _ghost_type = ghost_type)) {
+        auto underlying_type = Mesh::getFacetType(type);
+        if (not lambda_connectivities.exists(underlying_type, ghost_type)) {
+          auto nb_nodes_per_element =
+              Mesh::getNbNodesPerElement(underlying_type);
+          lambda_connectivities.alloc(0, nb_nodes_per_element, underlying_type,
+                                      ghost_type, -1);
+        }
+      }
+    }
+  }
+
+  if (is_extrinsic) {
+    resizeFacetStress();
+  }
+
+  AKANTU_DEBUG_OUT();
+}
+
+/* -------------------------------------------------------------------------- */
+void SolidMechanicsModelCohesiveDamage::onNodesAdded(const Array<Idx> & new_nodes,
+                                               const NewNodesEvent & event) {
+  SolidMechanicsModel::onNodesAdded(new_nodes, event);
+
+  auto & initial_nodes = mesh.getNodalData<Idx>("initial_nodes_match");
+
+  auto old_max_nodes = initial_nodes.size();
+  initial_nodes.resize(mesh.getNbNodes(), -1);
+
+  const auto * cohesive_event =
+      dynamic_cast<const CohesiveNewNodesEvent *>(&event);
+  if (cohesive_event == nullptr) {
+    for (auto && node : new_nodes) {
+      initial_nodes(node) = node;
+    }
+    return;
+  }
+
+  auto old_nodes = cohesive_event->getOldNodesList();
+
+  // getting a corrected old_nodes for multiple doubling
+  for (auto & onode : old_nodes) {
+    while (onode >= old_max_nodes) {
+      auto nnode = new_nodes.find(onode);
+      AKANTU_DEBUG_ASSERT(nnode != -1,
+                          "If the old node is bigger than old_max_nodes it "
+                          "should also be a new node");
+      onode = nnode;
+    }
+  }
+
+  auto copy = [&new_nodes, &old_nodes](auto & arr) {
+    auto it = make_view(arr, arr.getNbComponent()).begin();
+    for (auto [new_node, old_node] : zip(new_nodes, old_nodes)) {
+      it[new_node] = it[old_node];
+    }
+  };
+
+  for (auto && ptr : {displacement.get(), velocity.get(), acceleration.get(),
+                      current_position.get(), previous_displacement.get(),
+                      displacement_increment.get()}) {
+    if (ptr != nullptr) {
+      copy(*ptr);
+    }
+  }
+
+  copy(*displacement);
+  copy(*blocked_dofs);
+
+  if (velocity) {
+    copy(*velocity);
+  }
+
+  if (acceleration) {
+    copy(*acceleration);
+  }
+
+  if (current_position) {
+    copy(*current_position);
+  }
+
+  if (previous_displacement) {
+    copy(*previous_displacement);
+  }
+
+  if (displacement_increment) {
+    copy(*displacement_increment);
+  }
+
+  copy(getDOFManager().getSolution("displacement"));
+
+  // correct connectivities
+  if (lambda) {
+    lambda_blocked_dofs->resize(mesh.getNbNodes(), false);
+    copy(*lambda_blocked_dofs);
+    updateLambdaMesh();
+  }
+}
+
+/* -------------------------------------------------------------------------- */
+ModelSolverOptions SolidMechanicsModelCohesiveDamage::getDefaultSolverOptions(
+    const TimeStepSolverType & type) const {
+  ModelSolverOptions options =
+      SolidMechanicsModel::getDefaultSolverOptions(type);
+
+    if (lambda) {
+//  if (true) {
+    switch (type) {
+    case TimeStepSolverType::_dynamic_lumped: {
+      options.non_linear_solver_type = NonLinearSolverType::_lumped;
+      options.integration_scheme_type["lambda"] =
+          IntegrationSchemeType::_central_difference;
+      options.solution_type["lambda"] = IntegrationScheme::_acceleration;
+      break;
+    }
+    case TimeStepSolverType::_static: {
+      options.non_linear_solver_type = NonLinearSolverType::_newton_raphson;
+      options.integration_scheme_type["lambda"] =
+          IntegrationSchemeType::_pseudo_time;
+      options.solution_type["lambda"] = IntegrationScheme::_not_defined;
+      break;
+    }
+    case TimeStepSolverType::_dynamic: {
+      if (this->method == _explicit_consistent_mass) {
+        options.non_linear_solver_type = NonLinearSolverType::_newton_raphson;
+        options.integration_scheme_type["lambda"] =
+            IntegrationSchemeType::_central_difference;
+        options.solution_type["lambda"] = IntegrationScheme::_acceleration;
+      } else {
+        options.non_linear_solver_type = NonLinearSolverType::_newton_raphson;
+        options.integration_scheme_type["lambda"] =
+            IntegrationSchemeType::_trapezoidal_rule_2;
+        options.solution_type["lambda"] = IntegrationScheme::_displacement;
+      }
+      break;
+    }
+    default:
+      AKANTU_EXCEPTION(type << " is not a valid time step solver type");
+    }
+  }
+  return options;
+}
+
+/* -------------------------------------------------------------------------- */
+void SolidMechanicsModelCohesiveDamage::printself(std::ostream & stream,
+                                            int indent) const {
+  std::string space(indent, AKANTU_INDENT);
+
+  stream << space << "SolidMechanicsModelCohesiveDamage ["
+         << "\n";
+  SolidMechanicsModelCohesive::printself(stream, indent + 2);
+  stream << space << "]\n";
+}
+
+/* -------------------------------------------------------------------------- */
+
+} // namespace akantu
diff --git a/src/model/solid_mechanics/solid_mechanics_model_cohesive/solid_mechanics_model_cohesive_damage.hh b/src/model/solid_mechanics/solid_mechanics_model_cohesive/solid_mechanics_model_cohesive_damage.hh
new file mode 100644
index 000000000..0737a6000
--- /dev/null
+++ b/src/model/solid_mechanics/solid_mechanics_model_cohesive/solid_mechanics_model_cohesive_damage.hh
@@ -0,0 +1,157 @@
+/**
+ * Copyright (©) 2012-2023 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ *
+ * This file is part of Akantu
+ *
+ * Akantu is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation, either version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/* -------------------------------------------------------------------------- */
+#include "solid_mechanics_model_cohesive.hh"
+/* -------------------------------------------------------------------------- */
+
+#ifndef AKANTU_SOLID_MECHANICS_MODEL_COHESIVE_DAMAGE_HH_
+#define AKANTU_SOLID_MECHANICS_MODEL_COHESIVE_DAMAGE_HH_
+
+/* -------------------------------------------------------------------------- */
+namespace akantu {
+class FacetSynchronizer;
+class FacetStressSynchronizer;
+class ElementSynchronizer;
+} // namespace akantu
+
+namespace akantu {
+
+/* -------------------------------------------------------------------------- */
+struct CohesiveIntegrationOrderFunctor {
+  template <ElementType type, ElementType cohesive_type =
+                                  CohesiveFacetProperty<type>::cohesive_type>
+  struct _helper {
+    static constexpr int get() {
+        //      return 1;
+        return ElementClassProperty<cohesive_type>::polynomial_degree;    }
+  };
+
+  template <ElementType type> struct _helper<type, _not_defined> {
+    static constexpr int get() {
+        //      return 1;
+        return ElementClassProperty<type>::polynomial_degree;    }
+  };
+
+  template <ElementType type> static inline constexpr int getOrder() {
+    return _helper<type>::get();
+  }
+};
+
+/* -------------------------------------------------------------------------- */
+/* Solid Mechanics Model for Cohesive damage elements                                */
+/* -------------------------------------------------------------------------- */
+class SolidMechanicsModelCohesiveDamage : public SolidMechanicsModelCohesive {
+    
+    using MyFEEngineLambdaType =
+      FEEngineTemplate<IntegratorGauss, ShapeLagrange, _ek_regular,
+                       FacetsCohesiveIntegrationOrderFunctor>;
+  
+  /* ------------------------------------------------------------------------ */
+  /* Constructors/Destructors                                                 */
+  /* ------------------------------------------------------------------------ */
+public:
+  SolidMechanicsModelCohesiveDamage(
+      Mesh & mesh, Int dim = _all_dimensions,
+      const ID & id = "solid_mechanics_model_cohesive_damage",
+      const std::shared_ptr<DOFManager> & dof_manager = nullptr);
+
+  /* ------------------------------------------------------------------------ */
+  /* Methods                                                                  */
+  /* ------------------------------------------------------------------------ */
+
+public:
+
+  /// function to perform an insertion check on each facet and insert
+  /// cohesive elements if needed (returns the number of new cohesive
+  /// elements)
+  UInt checkCohesiveInsertion();
+  
+  /// compute Lagrange multiplier
+  void computeLagrangeMultiplier();
+
+  /// compute damage variable
+  void computeDamage();
+
+protected:
+
+  /// initialize cohesive material
+  void initConstitutiveLaws() override;
+
+  /// function to print the contain of the class
+  void printself(std::ostream & stream, int indent = 0) const override;
+
+  /* ------------------------------------------------------------------------ */
+  /* SolidMechanicsModelEventHandler inherited members                        */
+  /* ------------------------------------------------------------------------ */
+public:
+
+  [[nodiscard]] ModelSolverOptions
+  getDefaultSolverOptions(const TimeStepSolverType & type) const override;
+
+  void updateLambdaMesh();
+
+  /* ------------------------------------------------------------------------ */
+  /* Accessors                                                                */
+  /* ------------------------------------------------------------------------ */
+public:
+
+  /// get the SolidMechanicsModel::lambda array
+  AKANTU_GET_MACRO_DEREF_PTR_NOT_CONST(Lambda, lambda);
+  /// get the SolidMechanicsModel::displacement array
+  AKANTU_GET_MACRO_DEREF_PTR(Lambda, lambda);
+
+  /// get lambda mesh
+  const Mesh & getLambdaMesh() {
+    if (not lambda_mesh) {
+      AKANTU_EXCEPTION("This model does not have a lambda mesh");
+    }
+    return *lambda_mesh;
+  }
+
+protected:
+  void onNodesAdded(const Array<Idx> & new_nodes,
+                    const NewNodesEvent & event) override;
+  void onElementsAdded(const Array<Element> & element_list,
+                       const NewElementsEvent & event) override;
+                       
+  /* ------------------------------------------------------------------------ */
+  /* Class Members                                                            */
+  /* ------------------------------------------------------------------------ */
+private:
+
+  /// lambda array
+  std::unique_ptr<Array<Real>> lambda;
+
+  /// lambda array at the previous time step
+  std::unique_ptr<Array<Real>> previous_lambda;
+
+  /// increment of lambda
+  std::unique_ptr<Array<Real>> lambda_increment;
+
+  /// array specifing if a lambda degree of freedom is blocked or not
+  std::unique_ptr<Array<bool>> lambda_blocked_dofs;
+
+  std::unique_ptr<Mesh> lambda_mesh;
+};
+
+} // namespace akantu
+
+#endif /* AKANTU_SOLID_MECHANICS_MODEL_COHESIVE_DAMAGE_HH_ */