diff --git a/src/mesh_utils/cohesive_element_inserter.cc b/src/mesh_utils/cohesive_element_inserter.cc
index 8de3b7efa..da3189a4f 100644
--- a/src/mesh_utils/cohesive_element_inserter.cc
+++ b/src/mesh_utils/cohesive_element_inserter.cc
@@ -1,269 +1,272 @@
 /**
  * @file   cohesive_element_inserter.cc
  *
  * @author Marco Vocialta <marco.vocialta@epfl.ch>
  *
  * @date creation: Wed Dec 04 2013
  * @date last modification: Mon Feb 19 2018
  *
  * @brief  Cohesive element inserter functions
  *
  * @section LICENSE
  *
  * Copyright (©) 2014-2018 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * 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 "communicator.hh"
 #include "element_group.hh"
 #include "global_ids_updater.hh"
 #include "mesh_accessor.hh"
 #include "mesh_iterators.hh"
+#include "element_synchronizer.hh"
 /* -------------------------------------------------------------------------- */
 #include <algorithm>
 #include <limits>
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 
 CohesiveElementInserter::CohesiveElementInserter(Mesh & mesh, const ID & id)
     : Parsable(ParserType::_cohesive_inserter), id(id), mesh(mesh),
       mesh_facets(mesh.initMeshFacets()),
       insertion_facets("insertion_facets", id),
       insertion_limits(mesh.getSpatialDimension(), 2),
       check_facets("check_facets", id) {
 
   this->registerParam("cohesive_surfaces", physical_groups, _pat_parsable,
                       "List of groups to consider for insertion");
   this->registerParam("bounding_box", insertion_limits, _pat_parsable,
                       "Global limit for insertion");
 
   UInt spatial_dimension = mesh.getSpatialDimension();
 
   MeshUtils::resetFacetToDouble(mesh_facets);
 
   /// init insertion limits
   for (UInt dim = 0; dim < spatial_dimension; ++dim) {
     insertion_limits(dim, 0) = std::numeric_limits<Real>::max() * Real(-1.);
     insertion_limits(dim, 1) = std::numeric_limits<Real>::max();
   }
 
   insertion_facets.initialize(mesh_facets,
                               _spatial_dimension = spatial_dimension - 1,
                               _with_nb_element = true, _default_value = false);
 }
 
 /* -------------------------------------------------------------------------- */
 CohesiveElementInserter::~CohesiveElementInserter() = default;
 
 /* -------------------------------------------------------------------------- */
 void CohesiveElementInserter::parseSection(const ParserSection & section) {
   Parsable::parseSection(section);
 
   if (is_extrinsic)
     limitCheckFacets(this->check_facets);
 }
 
 /* -------------------------------------------------------------------------- */
 void CohesiveElementInserter::limitCheckFacets() {
   limitCheckFacets(this->check_facets);
 }
 
 /* -------------------------------------------------------------------------- */
 void CohesiveElementInserter::setLimit(SpacialDirection axis, Real first_limit,
                                        Real second_limit) {
   AKANTU_DEBUG_ASSERT(
       axis < mesh.getSpatialDimension(),
       "You are trying to limit insertion in a direction that doesn't exist");
 
   insertion_limits(axis, 0) = std::min(first_limit, second_limit);
   insertion_limits(axis, 1) = std::max(first_limit, second_limit);
 }
 
 /* -------------------------------------------------------------------------- */
 UInt CohesiveElementInserter::insertIntrinsicElements() {
   limitCheckFacets(insertion_facets);
   return insertElements();
 }
 
 /* -------------------------------------------------------------------------- */
 void CohesiveElementInserter::limitCheckFacets(
     ElementTypeMapArray<bool> & check_facets) {
   AKANTU_DEBUG_IN();
 
   UInt spatial_dimension = mesh.getSpatialDimension();
 
   check_facets.initialize(mesh_facets,
                           _spatial_dimension = spatial_dimension - 1,
                           _with_nb_element = true, _default_value = true);
   check_facets.set(true);
 
   // remove the pure ghost elements
   for_each_element(
       mesh_facets,
       [&](auto && facet) {
         const auto & element_to_facet = mesh_facets.getElementToSubelement(
             facet.type, facet.ghost_type)(facet.element);
         auto & left = element_to_facet[0];
         auto & right = element_to_facet[1];
         if (right == ElementNull ||
             (left.ghost_type == _ghost && right.ghost_type == _ghost)) {
           check_facets(facet) = false;
           return;
         }
 
         if (left.kind() == _ek_cohesive or right.kind() == _ek_cohesive) {
           check_facets(facet) = false;
         }
       },
       _spatial_dimension = spatial_dimension - 1);
 
   auto tolerance = Math::getTolerance();
   Vector<Real> bary_facet(spatial_dimension);
   // set the limits to the bounding box
   for_each_element(
       mesh_facets,
       [&](auto && facet) {
         auto & need_check = check_facets(facet);
         if (not need_check)
           return;
 
         mesh_facets.getBarycenter(facet, bary_facet);
         UInt coord_in_limit = 0;
 
         while (coord_in_limit < spatial_dimension and
                bary_facet(coord_in_limit) >
                    (insertion_limits(coord_in_limit, 0) - tolerance) and
                bary_facet(coord_in_limit) <
                    (insertion_limits(coord_in_limit, 1) + tolerance))
           ++coord_in_limit;
 
         if (coord_in_limit != spatial_dimension)
           need_check = false;
       },
       _spatial_dimension = spatial_dimension - 1);
 
   if (physical_groups.size() == 0) {
     AKANTU_DEBUG_OUT();
     return;
   }
 
   if (not mesh_facets.hasData("physical_names")) {
     AKANTU_DEBUG_ASSERT(
         physical_groups.size() == 0,
         "No physical names in the mesh but insertion limited to a group");
     AKANTU_DEBUG_OUT();
     return;
   }
 
   const auto & physical_ids =
       mesh_facets.getData<std::string>("physical_names");
 
   // set the limits to the physical surfaces
   for_each_element(mesh_facets,
                    [&](auto && facet) {
                      auto & need_check = check_facets(facet);
                      if (not need_check)
                        return;
 
                      const auto & physical_id = physical_ids(facet);
                      auto it = find(physical_groups.begin(),
                                     physical_groups.end(), physical_id);
 
                      need_check = (it != physical_groups.end());
                    },
                    _spatial_dimension = spatial_dimension - 1);
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 UInt CohesiveElementInserter::insertElements(bool only_double_facets) {
-
   CohesiveNewNodesEvent node_event;
   NewElementsEvent element_event;
 
   Array<UInt> new_pairs(0, 2);
 
+  mesh_facets.getElementSynchronizer().synchronizeOnce(
+      *this, _gst_ce_groups);
+
   UInt nb_new_elements = MeshUtils::insertCohesiveElements(
       mesh, mesh_facets, insertion_facets, new_pairs, element_event.getList(),
       only_double_facets);
 
   UInt nb_new_nodes = new_pairs.size();
   node_event.getList().reserve(nb_new_nodes);
   node_event.getOldNodesList().reserve(nb_new_nodes);
   for (UInt n = 0; n < nb_new_nodes; ++n) {
     node_event.getList().push_back(new_pairs(n, 1));
     node_event.getOldNodesList().push_back(new_pairs(n, 0));
   }
 
   if (nb_new_elements > 0) {
     updateInsertionFacets();
   }
 
   MeshAccessor mesh_accessor(mesh);
   std::tie(nb_new_nodes, nb_new_elements) =
       mesh_accessor.updateGlobalData(node_event, element_event);
 
   return nb_new_elements;
 }
 
 /* -------------------------------------------------------------------------- */
 void CohesiveElementInserter::updateInsertionFacets() {
   AKANTU_DEBUG_IN();
 
   UInt spatial_dimension = mesh.getSpatialDimension();
 
   for (auto && facet_gt : ghost_types) {
     for (auto && facet_type :
          mesh_facets.elementTypes(spatial_dimension - 1, facet_gt)) {
       auto & ins_facets = insertion_facets(facet_type, facet_gt);
 
       // this is the intrinsic case
       if (not is_extrinsic)
         continue;
 
       auto & f_check = check_facets(facet_type, facet_gt);
       for (auto && pair : zip(ins_facets, f_check)) {
         bool & ins = std::get<0>(pair);
         bool & check = std::get<1>(pair);
         if (ins)
           ins = check = false;
       }
     }
   }
 
   // resize for the newly added facets
   insertion_facets.initialize(mesh_facets,
                               _spatial_dimension = spatial_dimension - 1,
                               _with_nb_element = true, _default_value = false);
 
   // resize for the newly added facets
   if (is_extrinsic) {
     check_facets.initialize(mesh_facets,
                             _spatial_dimension = spatial_dimension - 1,
                             _with_nb_element = true, _default_value = false);
   } else {
     insertion_facets.set(false);
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 } // namespace akantu
diff --git a/src/mesh_utils/cohesive_element_inserter.hh b/src/mesh_utils/cohesive_element_inserter.hh
index ab10d11a5..187125069 100644
--- a/src/mesh_utils/cohesive_element_inserter.hh
+++ b/src/mesh_utils/cohesive_element_inserter.hh
@@ -1,181 +1,171 @@
 /**
  * @file   cohesive_element_inserter.hh
  *
  * @author Fabian Barras <fabian.barras@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  * @author Marco Vocialta <marco.vocialta@epfl.ch>
  *
  * @date creation: Wed Dec 04 2013
  * @date last modification: Sun Feb 04 2018
  *
  * @brief  Cohesive element inserter
  *
  * @section LICENSE
  *
  * Copyright (©) 2014-2018 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * 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 "data_accessor.hh"
 #include "mesh_utils.hh"
 #include "parsable.hh"
 /* -------------------------------------------------------------------------- */
 #include <numeric>
 /* -------------------------------------------------------------------------- */
 
 #ifndef __AKANTU_COHESIVE_ELEMENT_INSERTER_HH__
 #define __AKANTU_COHESIVE_ELEMENT_INSERTER_HH__
 
 namespace akantu {
 class GlobalIdsUpdater;
 class FacetSynchronizer;
 } // akantu
 
 namespace akantu {
 
 class CohesiveElementInserter : public DataAccessor<Element>, public Parsable {
   /* ------------------------------------------------------------------------ */
   /* Constructors/Destructors                                                 */
   /* ------------------------------------------------------------------------ */
 public:
   CohesiveElementInserter(Mesh & mesh,
                           const ID & id = "cohesive_element_inserter");
 
   ~CohesiveElementInserter() override;
 
   /* ------------------------------------------------------------------------ */
   /* Methods                                                                  */
   /* ------------------------------------------------------------------------ */
 public:
   /// set range limitation for intrinsic cohesive element insertion
   void setLimit(SpacialDirection axis, Real first_limit, Real second_limit);
 
   /// insert intrinsic cohesive elements in a predefined range
   UInt insertIntrinsicElements();
 
   /// insert extrinsic cohesive elements (returns the number of new
   /// cohesive elements)
   UInt insertElements(bool only_double_facets = false);
 
   /// limit check facets to match given insertion limits
   void limitCheckFacets();
 
 protected:
   void parseSection(const ParserSection & section) override;
 
 protected:
   /// internal version of limitCheckFacets
   void limitCheckFacets(ElementTypeMapArray<bool> & check_facets);
 
   /// update facet insertion arrays after facets doubling
   void updateInsertionFacets();
 
   /// functions for parallel communications
   inline UInt getNbData(const Array<Element> & elements,
                         const SynchronizationTag & tag) const override;
 
   inline void packData(CommunicationBuffer & buffer,
                        const Array<Element> & elements,
                        const SynchronizationTag & tag) const override;
 
   inline void unpackData(CommunicationBuffer & buffer,
                          const Array<Element> & elements,
                          const SynchronizationTag & tag) override;
-
-  template <bool pack_mode>
-  inline void
-  packUnpackGlobalConnectivity(CommunicationBuffer & buffer,
-                               const Array<Element> & elements) const;
-
-  template <bool pack_mode>
-  inline void
-  packUnpackGroupedInsertionData(CommunicationBuffer & buffer,
-                                 const Array<Element> & elements) const;
   /* ------------------------------------------------------------------------ */
   /* Accessors                                                                */
   /* ------------------------------------------------------------------------ */
 public:
   AKANTU_GET_MACRO_NOT_CONST(InsertionFacetsByElement, insertion_facets,
                              ElementTypeMapArray<bool> &);
   AKANTU_GET_MACRO(InsertionFacetsByElement, insertion_facets,
                    const ElementTypeMapArray<bool> &);
   AKANTU_GET_MACRO_BY_ELEMENT_TYPE(InsertionFacets, insertion_facets, bool);
 
   AKANTU_GET_MACRO(CheckFacets, check_facets,
                    const ElementTypeMapArray<bool> &);
   AKANTU_GET_MACRO_BY_ELEMENT_TYPE(CheckFacets, check_facets, bool);
   AKANTU_GET_MACRO_BY_ELEMENT_TYPE_CONST(CheckFacets, check_facets, bool);
 
   AKANTU_GET_MACRO(MeshFacets, mesh_facets, const Mesh &);
   AKANTU_GET_MACRO_NOT_CONST(MeshFacets, mesh_facets, Mesh &);
 
   AKANTU_SET_MACRO(IsExtrinsic, is_extrinsic, bool);
 
 public:
   friend class SolidMechanicsModelCohesive;
 
   /* ------------------------------------------------------------------------ */
   /* Class Members                                                            */
   /* ------------------------------------------------------------------------ */
 private:
   /// object id
   ID id;
 
   /// main mesh where to insert cohesive elements
   Mesh & mesh;
 
   /// mesh containing facets
   Mesh & mesh_facets;
 
   /// list of facets where to insert elements
   ElementTypeMapArray<bool> insertion_facets;
 
   /// limits for element insertion
   Matrix<Real> insertion_limits;
 
   /// list of groups to consider for insertion, ignored if empty
   std::vector<ID> physical_groups;
 
   /// vector containing facets in which extrinsic cohesive elements can be
   /// inserted
   ElementTypeMapArray<bool> check_facets;
 
   /// global connectivity ids updater
   std::unique_ptr<GlobalIdsUpdater> global_ids_updater;
 
   /// is this inserter used in extrinsic
   bool is_extrinsic{false};
 };
 
 class CohesiveNewNodesEvent : public NewNodesEvent {
 public:
   CohesiveNewNodesEvent() = default;
   ~CohesiveNewNodesEvent() override = default;
 
   AKANTU_GET_MACRO_NOT_CONST(OldNodesList, old_nodes, Array<UInt> &);
   AKANTU_GET_MACRO(OldNodesList, old_nodes, const Array<UInt> &);
 
 private:
   Array<UInt> old_nodes;
 };
 
 } // akantu
 
 #include "cohesive_element_inserter_inline_impl.cc"
 
 #endif /* __AKANTU_COHESIVE_ELEMENT_INSERTER_HH__ */
diff --git a/src/mesh_utils/cohesive_element_inserter_inline_impl.cc b/src/mesh_utils/cohesive_element_inserter_inline_impl.cc
index d53f12d16..bf9aeee9d 100644
--- a/src/mesh_utils/cohesive_element_inserter_inline_impl.cc
+++ b/src/mesh_utils/cohesive_element_inserter_inline_impl.cc
@@ -1,121 +1,89 @@
 /**
  * @file   cohesive_element_inserter_inline_impl.cc
  *
  * @author Marco Vocialta <marco.vocialta@epfl.ch>
  *
  * @date creation: Wed Nov 05 2014
  * @date last modification: Fri Dec 08 2017
  *
  * @brief  Cohesive element inserter inline functions
  *
  * @section LICENSE
  *
  * Copyright (©) 2015-2018 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * 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"
 /* -------------------------------------------------------------------------- */
 
 #ifndef __AKANTU_COHESIVE_ELEMENT_INSERTER_INLINE_IMPL_CC__
 #define __AKANTU_COHESIVE_ELEMENT_INSERTER_INLINE_IMPL_CC__
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 inline UInt
 CohesiveElementInserter::getNbData(const Array<Element> & elements,
                                    const SynchronizationTag & tag) const {
   AKANTU_DEBUG_IN();
 
   UInt size = 0;
 
   if (tag == _gst_ce_groups) {
-    size = elements.size() * (sizeof(bool) + sizeof(unsigned int));
+    size = elements.size() * sizeof(bool);
   }
 
   AKANTU_DEBUG_OUT();
   return size;
 }
 
 /* -------------------------------------------------------------------------- */
 inline void
 CohesiveElementInserter::packData(CommunicationBuffer & buffer,
                                   const Array<Element> & elements,
                                   const SynchronizationTag & tag) const {
   AKANTU_DEBUG_IN();
-  if (tag == _gst_ce_groups)
-    packUnpackGroupedInsertionData<true>(buffer, elements);
-
+  if (tag == _gst_ce_groups) {
+    for (const auto & el : elements) {
+      const bool & data = insertion_facets(el);
+      buffer << data;
+    }
+  }
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 inline void
 CohesiveElementInserter::unpackData(CommunicationBuffer & buffer,
                                     const Array<Element> & elements,
                                     const SynchronizationTag & tag) {
   AKANTU_DEBUG_IN();
-  if (tag == _gst_ce_groups)
-    packUnpackGroupedInsertionData<false>(buffer, elements);
-
-  AKANTU_DEBUG_OUT();
-}
-
-/* -------------------------------------------------------------------------- */
-template <bool pack_mode>
-inline void CohesiveElementInserter::packUnpackGroupedInsertionData(
-    CommunicationBuffer & buffer, const Array<Element> & elements) const {
-
-  AKANTU_DEBUG_IN();
-
-  auto current_element_type = _not_defined;
-  auto current_ghost_type = _casper;
-  auto & physical_names = mesh_facets.registerData<UInt>("physical_names");
-
-  Array<bool> * vect = nullptr;
-  Array<UInt> * vect2 = nullptr;
-
-  for (const auto & el : elements) {
-    if (el.type != current_element_type ||
-        el.ghost_type != current_ghost_type) {
-      current_element_type = el.type;
-      current_ghost_type = el.ghost_type;
-      vect =
-          &const_cast<Array<bool> &>(insertion_facets(el.type, el.ghost_type));
-      vect2 = &(physical_names(el.type, el.ghost_type));
-    }
-
-    Vector<bool> data(vect->storage() + el.element, 1);
-    Vector<unsigned int> data2(vect2->storage() + el.element, 1);
 
-    if (pack_mode) {
-      buffer << data;
-      buffer << data2;
-    } else {
+  if (tag == _gst_ce_groups) {
+    for (const auto & el : elements) {
+      bool & data = insertion_facets(el);
       buffer >> data;
-      buffer >> data2;
     }
   }
-
   AKANTU_DEBUG_OUT();
 }
 
 } // namespace akantu
 
 #endif /* __AKANTU_COHESIVE_ELEMENT_INSERTER_INLINE_IMPL_CC__ */
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 e7613b780..477729d24 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,759 +1,705 @@
 /**
  * @file   solid_mechanics_model_cohesive.cc
  *
  * @author Fabian Barras <fabian.barras@epfl.ch>
  * @author Mauro Corrado <mauro.corrado@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  * @author Marco Vocialta <marco.vocialta@epfl.ch>
  *
  * @date creation: Tue May 08 2012
  * @date last modification: Wed Feb 21 2018
  *
  * @brief  Solid mechanics model for cohesive elements
  *
  * @section LICENSE
  *
  * Copyright (©)  2010-2018 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * 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.hh"
 #include "mesh_accessor.hh"
 #include "mesh_global_data_updater.hh"
 #include "parser.hh"
 #include "shape_cohesive.hh"
 /* -------------------------------------------------------------------------- */
 #include "dumpable_inline_impl.hh"
 #ifdef AKANTU_USE_IOHELPER
 #include "dumper_iohelper_paraview.hh"
 #endif
 /* -------------------------------------------------------------------------- */
 #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) {}
 
   /* ------------------------------------------------------------------------ */
   std::tuple<UInt, UInt>
   updateData(NewNodesEvent & nodes_event,
              NewElementsEvent & elements_event) override {
     auto cohesive_nodes_event =
         dynamic_cast<CohesiveNewNodesEvent *>(&nodes_event);
     if (not cohesive_nodes_event)
       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();
 
     UInt local_nb_new_nodes = new_nodes.size();
 
     MeshAccessor mesh_accessor(mesh);
     auto & nodes_type = mesh_accessor.getNodesType();
     UInt nb_old_nodes = nodes_type.size();
     nodes_type.resize(nb_old_nodes + local_nb_new_nodes);
 
     for (auto && data : zip(old_nodes, new_nodes)) {
       UInt old_node, new_node;
       std::tie(old_node, new_node) = data;
       nodes_type(new_node) = nodes_type(old_node);
     }
 
     model.updateCohesiveSynchronizers();
 
     UInt nb_new_nodes = global_ids_updater.updateGlobalIDs(new_nodes.size());
 
     Vector<UInt> nb_new_stuff = {nb_new_nodes, elements_event.getList().size()};
     const auto & comm = mesh.getCommunicator();
     comm.allReduce(nb_new_stuff, SynchronizerOperation::_sum);
 
     if (nb_new_stuff(1) > 0) {
       mesh.sendEvent(elements_event);
       MeshUtils::resetFacetToDouble(mesh.getMeshFacets());
     }
 
     if (nb_new_nodes > 0) {
       mesh.sendEvent(nodes_event);
       // mesh.sendEvent(global_ids_updater.getChangedNodeEvent());
     }
 
     return std::make_tuple(nb_new_nodes, nb_new_stuff(1));
   }
 
 private:
   SolidMechanicsModelCohesive & model;
   Mesh & mesh;
   GlobalIdsUpdater global_ids_updater;
 };
 
 /* -------------------------------------------------------------------------- */
 SolidMechanicsModelCohesive::SolidMechanicsModelCohesive(
     Mesh & mesh, UInt dim, const ID & id, const MemoryID & memory_id)
     : SolidMechanicsModel(mesh, dim, id, memory_id,
                           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->material_selector);
   this->material_selector = tmp_material_selector;
 
 #if defined(AKANTU_USE_IOHELPER)
   this->mesh.registerDumper<DumperParaview>("cohesive elements", id);
   this->mesh.addDumpMeshToDumper("cohesive elements", mesh,
                                  Model::spatial_dimension, _not_ghost,
                                  _ek_cohesive);
 #endif
 
   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, _gst_material_id);
     this->registerSynchronizer(*cohesive_synchronizer, _gst_smm_stress);
     this->registerSynchronizer(*cohesive_synchronizer, _gst_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();
 }
 
 /* -------------------------------------------------------------------------- */
 SolidMechanicsModelCohesive::~SolidMechanicsModelCohesive() = default;
 
 /* -------------------------------------------------------------------------- */
 void SolidMechanicsModelCohesive::setTimeStep(Real time_step,
                                               const ID & solver_id) {
   SolidMechanicsModel::setTimeStep(time_step, solver_id);
 
 #if defined(AKANTU_USE_IOHELPER)
   this->mesh.getDumper("cohesive elements").setTimeStep(time_step);
 #endif
 }
 
 /* -------------------------------------------------------------------------- */
 void SolidMechanicsModelCohesive::initFullImpl(const ModelOptions & options) {
   AKANTU_DEBUG_IN();
 
   const auto & smmc_options =
       dynamic_cast<const SolidMechanicsModelCohesiveOptions &>(options);
 
   this->is_extrinsic = smmc_options.extrinsic;
 
   inserter->setIsExtrinsic(is_extrinsic);
 
   if (mesh.isDistributed()) {
     auto & mesh_facets = inserter->getMeshFacets();
     auto & synchronizer =
         dynamic_cast<FacetSynchronizer &>(mesh_facets.getElementSynchronizer());
-    this->registerSynchronizer(synchronizer, _gst_smmc_facets);
+    // this->registerSynchronizer(synchronizer, _gst_smmc_facets);
     // this->registerSynchronizer(synchronizer, _gst_smmc_facets_conn);
 
     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,
                                  _gst_smmc_facets_stress);
     }
 
     MeshAccessor mesh_accessor(mesh);
     mesh_accessor.registerGlobalDataUpdater(
         std::make_unique<CohesiveMeshGlobalDataUpdater>(*this));
   }
 
   ParserSection section;
   bool is_empty;
   std::tie(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::initMaterials() {
   AKANTU_DEBUG_IN();
 
   // make sure the material are instantiated
   if (!are_materials_instantiated)
     instantiateMaterials();
 
   /// find the first cohesive material
   UInt cohesive_index = UInt(-1);
 
   for (auto && material : enumerate(materials)) {
     if (dynamic_cast<MaterialCohesive *>(std::get<1>(material).get())) {
       cohesive_index = std::get<0>(material);
       break;
     }
   }
 
   if (cohesive_index == UInt(-1))
     AKANTU_EXCEPTION("No cohesive materials in the material input file");
 
   material_selector->setFallback(cohesive_index);
 
   // set the facet information in the material in case of dynamic insertion
   // to know what material to call for stress checks
-  if (is_extrinsic) {
-    this->initExtrinsicMaterials();
-  } else {
-    this->initIntrinsicMaterials();
-  }
-
-  AKANTU_DEBUG_OUT();
-} // namespace akantu
 
-/* -------------------------------------------------------------------------- */
-void SolidMechanicsModelCohesive::initExtrinsicMaterials() {
   const Mesh & mesh_facets = inserter->getMeshFacets();
   facet_material.initialize(
       mesh_facets, _spatial_dimension = spatial_dimension - 1,
       _with_nb_element = true,
       _default_value = material_selector->getFallbackValue());
 
   for_each_element(
       mesh_facets,
       [&](auto && element) {
         auto mat_index = (*material_selector)(element);
         auto & mat = dynamic_cast<MaterialCohesive &>(*materials[mat_index]);
         facet_material(element) = mat_index;
-        mat.addFacet(element);
+        if (is_extrinsic) {
+          mat.addFacet(element);
+        }
       },
       _spatial_dimension = spatial_dimension - 1, _ghost_type = _not_ghost);
 
   SolidMechanicsModel::initMaterials();
 
-  this->initAutomaticInsertion();
-}
-
-/* -------------------------------------------------------------------------- */
-#if 0
-void SolidMechanicsModelCohesive::initIntrinsicCohesiveMaterials(
-    const std::string & cohesive_surfaces) {
-
-  AKANTU_DEBUG_IN();
-
-#if defined(AKANTU_PARALLEL_COHESIVE_ELEMENT)
-  if (facet_synchronizer != nullptr)
-    inserter->initParallel(facet_synchronizer, cohesive_element_synchronizer);
-//    inserter->initParallel(facet_synchronizer, synch_parallel);
-#endif
-  std::istringstream split(cohesive_surfaces);
-  std::string physname;
-  while (std::getline(split, physname, ',')) {
-    AKANTU_DEBUG_INFO(
-        "Pre-inserting cohesive elements along facets from physical surface: "
-        << physname);
-    insertElementsFromMeshData(physname);
-  }
-
-  synchronizeInsertionData();
-
-  SolidMechanicsModel::initMaterials();
-
-  auto && tmp = std::make_shared<MeshDataMaterialCohesiveSelector>(*this);
-  tmp->setFallback(material_selector->getFallbackValue());
-  tmp->setFallback(material_selector->getFallbackSelector());
-  material_selector = tmp;
-
-  // UInt nb_new_elements =
-  inserter->insertElements();
-  // if (nb_new_elements > 0) {
-  //   this->reinitializeSolver();
-  // }
-
-  AKANTU_DEBUG_OUT();
-}
-#endif
-/* -------------------------------------------------------------------------- */
-void SolidMechanicsModelCohesive::synchronizeInsertionData() {
-  if (inserter->getMeshFacets().isDistributed()) {
-    inserter->getMeshFacets().getElementSynchronizer().synchronizeOnce(
-        *inserter, _gst_ce_groups);
+  if (is_extrinsic) {
+    this->initAutomaticInsertion();
+  } else {
+    this->insertIntrinsicElements();
   }
-}
-
-/* -------------------------------------------------------------------------- */
-void SolidMechanicsModelCohesive::initIntrinsicMaterials() {
-  AKANTU_DEBUG_IN();
-
-  SolidMechanicsModel::initMaterials();
-
-  this->insertIntrinsicElements();
 
   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.size() == 0)
         continue;
 
       type = tmp_type;
       auto type_facet = Mesh::getFacetType(type);
       auto type_cohesive = FEEngine::getCohesiveElementType(type_facet);
       mesh.addConnectivityType(type_cohesive, type_ghost);
     }
   }
   AKANTU_DEBUG_ASSERT(type != _not_defined, "No elements in the mesh");
 
   getFEEngine("CohesiveFEEngine").initShapeFunctions(_not_ghost);
   getFEEngine("CohesiveFEEngine").initShapeFunctions(_ghost);
 
   if (is_extrinsic) {
     getFEEngine("FacetsFEEngine").initShapeFunctions(_not_ghost);
     getFEEngine("FacetsFEEngine").initShapeFunctions(_ghost);
   }
 
   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);
   // mesh_facets.initElementTypeMapArray(quad_facets, Model::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);
   // mesh.initElementTypeMapArray(elements_quad_facets,
   // Model::spatial_dimension,
   //                              Model::spatial_dimension);
 
   for (auto elem_gt : ghost_types) {
     for (auto & type : mesh.elementTypes(Model::spatial_dimension, elem_gt)) {
       UInt 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;
 
         Matrix<Real> 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;
 
         // for (UInt q = 0; q < nb_quad_per_facet; ++q) {
         //   for (UInt s = 0; s < Model::spatial_dimension; ++s) {
         //     el_q_facet(el * nb_facet_per_elem * nb_quad_per_facet +
         //                    f * nb_quad_per_facet + q,
         //                s) = quad_f(global_facet * nb_quad_per_facet + q,
         //                s);
         //   }
         // }
         //}
       }
     }
   }
 
   /// loop over non cohesive materials
   for (auto && material : materials) {
     if (dynamic_cast<MaterialCohesive *>(material.get()))
       continue;
     /// initialize the interpolation function
     material->initElementalFieldInterpolation(elements_quad_facets);
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void SolidMechanicsModelCohesive::assembleInternalForces() {
   AKANTU_DEBUG_IN();
 
   // f_int += f_int_cohe
   for (auto & material : this->materials) {
     try {
       auto & mat = dynamic_cast<MaterialCohesive &>(*material);
       mat.computeTraction(_not_ghost);
     } catch (std::bad_cast & bce) {
     }
   }
 
   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);
   // mesh_facets.initElementTypeMapArray(tangents, tangent_components,
   //                                     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);
 
   for (auto & material : materials) {
     auto * mat = dynamic_cast<MaterialCohesive *>(material.get());
     if (mat == nullptr)
       /// interpolate stress on facet quadrature points positions
       material->interpolateStressOnFacets(facet_stress, by_elem_result);
   }
 
   this->synchronize(_gst_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();
 
   for (auto & mat : materials) {
     auto * mat_cohesive = dynamic_cast<MaterialCohesive *>(mat.get());
     if (mat_cohesive) {
       /// check which not ghost cohesive elements are to be created
       mat_cohesive->checkInsertion();
     }
   }
 
   /// communicate data among processors
-  this->synchronize(_gst_smmc_facets);
+  // this->synchronize(_gst_smmc_facets);
 
   /// insert cohesive elements
   UInt nb_new_elements = inserter->insertElements();
 
   // if (nb_new_elements > 0) {
   //   this->reinitializeSolver();
   // }
 
   AKANTU_DEBUG_OUT();
 
   return nb_new_elements;
 }
 
 /* -------------------------------------------------------------------------- */
 void SolidMechanicsModelCohesive::onElementsAdded(
     const Array<Element> & element_list, const NewElementsEvent & event) {
   AKANTU_DEBUG_IN();
 
   SolidMechanicsModel::onElementsAdded(element_list, event);
 
   if (is_extrinsic)
     resizeFacetStress();
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void SolidMechanicsModelCohesive::onNodesAdded(const Array<UInt> & new_nodes,
                                                const NewNodesEvent & event) {
   AKANTU_DEBUG_IN();
 
   SolidMechanicsModel::onNodesAdded(new_nodes, event);
 
   const CohesiveNewNodesEvent * cohesive_event;
-  if ((cohesive_event = dynamic_cast<const CohesiveNewNodesEvent *>(&event)) == nullptr)
+  if ((cohesive_event = dynamic_cast<const CohesiveNewNodesEvent *>(&event)) ==
+      nullptr)
     return;
 
   const auto & old_nodes = cohesive_event->getOldNodesList();
 
   auto copy = [this, &new_nodes, &old_nodes](auto & arr) {
     UInt new_node, old_node;
 
     auto view = make_view(arr, spatial_dimension);
     auto begin = view.begin();
 
     for (auto && pair : zip(new_nodes, old_nodes)) {
       std::tie(new_node, old_node) = pair;
 
       auto old_ = begin + old_node;
       auto new_ = begin + new_node;
 
       *new_ = *old_;
     }
   };
 
   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 (external_force)
   //   copy(*external_force);
   // if (internal_force)
   //   copy(*internal_force);
 
   if (displacement_increment)
     copy(*displacement_increment);
 
   copy(getDOFManager().getSolution("displacement"));
   // this->assembleMassLumped();
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void SolidMechanicsModelCohesive::onEndSolveStep(const AnalysisMethod &) {
 
   AKANTU_DEBUG_IN();
 
   /*
    * This is required because the Cauchy stress is the stress measure that
    * is used to check the insertion of cohesive elements
    */
   for (auto & mat : materials) {
     if (mat->isFiniteDeformation())
       mat->computeAllCauchyStresses(_not_ghost);
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void SolidMechanicsModelCohesive::printself(std::ostream & stream,
                                             int indent) const {
   std::string space;
   for (Int i = 0; i < indent; i++, space += AKANTU_INDENT)
     ;
 
   stream << space << "SolidMechanicsModelCohesive [" << std::endl;
   SolidMechanicsModel::printself(stream, indent + 1);
   stream << space << "]" << std::endl;
 }
 
 /* -------------------------------------------------------------------------- */
 void SolidMechanicsModelCohesive::resizeFacetStress() {
   AKANTU_DEBUG_IN();
 
   this->facet_stress.initialize(getFEEngine("FacetsFEEngine"),
                                 _nb_component =
                                     2 * spatial_dimension * spatial_dimension,
                                 _spatial_dimension = spatial_dimension - 1);
 
   // for (auto && ghost_type : ghost_types) {
   //   for (const auto & type :
   //        mesh_facets.elementTypes(spatial_dimension - 1, ghost_type)) {
   //     UInt nb_facet = mesh_facets.getNbElement(type, ghost_type);
 
   //     UInt nb_quadrature_points = getFEEngine("FacetsFEEngine")
   //                                     .getNbIntegrationPoints(type,
   //                                     ghost_type);
 
   //     UInt new_size = nb_facet * nb_quadrature_points;
 
   //     facet_stress(type, ghost_type).resize(new_size);
   //   }
   // }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void SolidMechanicsModelCohesive::addDumpGroupFieldToDumper(
     const std::string & dumper_name, const std::string & field_id,
     const std::string & group_name, const ElementKind & element_kind,
     bool padding_flag) {
   AKANTU_DEBUG_IN();
 
   UInt 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 d94ab18b8..2a49a56da 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,321 +1,312 @@
 /**
  * @file   solid_mechanics_model_cohesive.hh
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  * @author Marco Vocialta <marco.vocialta@epfl.ch>
  *
  * @date creation: Tue May 08 2012
  * @date last modification: Mon Feb 05 2018
  *
  * @brief  Solid mechanics model for cohesive elements
  *
  * @section LICENSE
  *
  * Copyright (©)  2010-2018 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * 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
 #include "solid_mechanics_model.hh"
 #include "solid_mechanics_model_event_handler.hh"
 // ParameterTyped::operator Real()
 /* -------------------------------------------------------------------------- */
 
 #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 ElementClassProperty<cohesive_type>::polynomial_degree;
     }
   };
 
   template <ElementType type> struct _helper<type, _not_defined> {
     static constexpr int get() {
       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>;
 
   SolidMechanicsModelCohesive(Mesh & mesh,
                               UInt spatial_dimension = _all_dimensions,
                               const ID & id = "solid_mechanics_model_cohesive",
                               const MemoryID & memory_id = 0);
 
   ~SolidMechanicsModelCohesive() override;
 
   /* ------------------------------------------------------------------------ */
   /* 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();
 
   /// interpolate stress on facets
   void interpolateStress();
 
   /// update automatic insertion after a change in the element inserter
   void updateAutomaticInsertion();
 
   /// insert intrinsic cohesive elements
   void insertIntrinsicElements();
 
   // 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 initMaterials() override;
 
   /// init facet filters for cohesive materials
   void initFacetFilter();
 
-  // synchronize facets physical data before insertion along physical surfaces
-  void synchronizeInsertionData();
-
   /// function to print the contain of the class
   void printself(std::ostream & stream, int indent = 0) const override;
 
 private:
-  /// initialize cohesive material with extrinsic insertion
-  void initExtrinsicMaterials();
-
-  /// initialize cohesive material with intrinsic insertion
-  void initIntrinsicMaterials();
-
   /// 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<UInt> & nodes_list,
                     const NewNodesEvent & event) override;
   void onElementsAdded(const Array<Element> & nodes_list,
                        const NewElementsEvent & event) override;
 
   /* ------------------------------------------------------------------------ */
   /* SolidMechanicsModelEventHandler inherited members                        */
   /* ------------------------------------------------------------------------ */
 public:
   void onEndSolveStep(const AnalysisMethod & method) override;
 
   /* ------------------------------------------------------------------------ */
   /* Dumpable interface                                                       */
   /* ------------------------------------------------------------------------ */
 public:
   void onDump() override;
 
   void addDumpGroupFieldToDumper(const std::string & dumper_name,
                                  const std::string & field_id,
                                  const std::string & group_name,
                                  const ElementKind & element_kind,
                                  bool padding_flag) override;
 
 public:
   /// register the tags associated with the parallel synchronizer for
   /// cohesive elements
   // void initParallel(MeshPartition * partition,
   //                DataAccessor * data_accessor = NULL,
   //                bool extrinsic = false);
 
 protected:
   void synchronizeGhostFacetsConnectivity();
 
   void updateCohesiveSynchronizers();
   void updateFacetStressSynchronizer();
 
   friend class CohesiveElementInserter;
 
   /* ------------------------------------------------------------------------ */
   /* Data Accessor inherited members                                          */
   /* ------------------------------------------------------------------------ */
 public:
   UInt 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:
   UInt 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(ElementTypeMapArray<T> & data_to_pack,
                                        CommunicationBuffer & buffer,
                                        const Array<Element> & element) const;
 
   /* ------------------------------------------------------------------------ */
   /* Accessors                                                                */
   /* ------------------------------------------------------------------------ */
 public:
   /// get facet mesh
   AKANTU_GET_MACRO(MeshFacets, mesh.getMeshFacets(), const Mesh &);
 
   /// 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, UInt);
 
   /// get facet material
   AKANTU_GET_MACRO_BY_ELEMENT_TYPE_CONST(FacetMaterial, facet_material, UInt);
 
   /// get facet material
   AKANTU_GET_MACRO(FacetMaterial, facet_material,
                    const ElementTypeMapArray<UInt> &);
 
   /// @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(CohesiveSynchronizer, *cohesive_synchronizer,
                    const ElementSynchronizer &);
 
   /* ------------------------------------------------------------------------ */
   /* Class Members                                                            */
   /* ------------------------------------------------------------------------ */
 private:
   friend class CohesiveMeshGlobalDataUpdater;
 
   /// @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<UInt> facet_material;
 
   bool is_extrinsic;
 
   /// 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;
 };
 
 } // namespace akantu
 
 #include "solid_mechanics_model_cohesive_inline_impl.cc"
 
 #endif /* __AKANTU_SOLID_MECHANICS_MODEL_COHESIVE_HH__ */
diff --git a/src/model/solid_mechanics/solid_mechanics_model_cohesive/solid_mechanics_model_cohesive_parallel.cc b/src/model/solid_mechanics/solid_mechanics_model_cohesive/solid_mechanics_model_cohesive_parallel.cc
index 412cc689f..b5a02f27d 100644
--- a/src/model/solid_mechanics/solid_mechanics_model_cohesive/solid_mechanics_model_cohesive_parallel.cc
+++ b/src/model/solid_mechanics/solid_mechanics_model_cohesive/solid_mechanics_model_cohesive_parallel.cc
@@ -1,547 +1,549 @@
 /**
  * @file   solid_mechanics_model_cohesive_parallel.cc
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  * @author Marco Vocialta <marco.vocialta@epfl.ch>
  *
  * @date creation: Wed Nov 05 2014
  * @date last modification: Tue Feb 20 2018
  *
  * @brief  Functions for parallel cohesive elements
  *
  * @section LICENSE
  *
  * Copyright (©) 2015-2018 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * 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 "communicator.hh"
 #include "element_synchronizer.hh"
 #include "material_cohesive.hh"
 #include "solid_mechanics_model_cohesive.hh"
 #include "solid_mechanics_model_tmpl.hh"
 /* -------------------------------------------------------------------------- */
 #include <type_traits>
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 
 class FacetConnectivitySynchronizer : public DataAccessor<Element> {
 public:
   FacetConnectivitySynchronizer(Mesh & mesh)
       : global_connectivity("global_connectivity",
                             "facet_connectivity_synchronizer") {
     global_connectivity.initialize(
         mesh, _spatial_dimension = _all_dimensions, _with_nb_element = true,
         _with_nb_nodes_per_element = true, _element_kind = _ek_regular);
     mesh.getGlobalConnectivity(global_connectivity);
   }
 
   UInt getNbData(const Array<Element> & elements,
                  const SynchronizationTag & tag) const {
     UInt size = 0;
     if (tag == _gst_smmc_facets_conn) {
       UInt nb_nodes = Mesh::getNbNodesPerElementList(elements);
       size += nb_nodes * sizeof(UInt);
     }
     return size;
   }
 
   void packData(CommunicationBuffer & buffer, const Array<Element> & elements,
                 const SynchronizationTag & tag) const {
     if (tag == _gst_smmc_facets_conn) {
       for (const auto & element : elements) {
         auto & conns = global_connectivity(element.type, element.ghost_type);
         for (auto n : arange(conns.getNbComponent())) {
           buffer << conns(element.element, n);
         }
       }
     }
   }
 
   void unpackData(CommunicationBuffer & buffer, const Array<Element> & elements,
                   const SynchronizationTag & tag) {
     if (tag == _gst_smmc_facets_conn) {
       for (const auto & element : elements) {
         auto & conns = global_connectivity(element.type, element.ghost_type);
         for (auto n : arange(conns.getNbComponent())) {
           buffer >> conns(element.element, n);
         }
       }
     }
   }
 
   AKANTU_GET_MACRO(GlobalConnectivity, (global_connectivity), decltype(auto));
 
 protected:
   ElementTypeMapArray<UInt> global_connectivity;
 };
 
 /* -------------------------------------------------------------------------- */
 void SolidMechanicsModelCohesive::synchronizeGhostFacetsConnectivity() {
   AKANTU_DEBUG_IN();
 
   const Communicator & comm = mesh.getCommunicator();
   Int psize = comm.getNbProc();
 
   if (psize == 1) {
     AKANTU_DEBUG_OUT();
     return;
   }
 
   /// get global connectivity for not ghost facets
   auto & mesh_facets = inserter->getMeshFacets();
 
   FacetConnectivitySynchronizer data_accessor(mesh_facets);
 
   /// communicate
   mesh_facets.getElementSynchronizer().synchronizeOnce(data_accessor,
                                                        _gst_smmc_facets_conn);
 
   /// flip facets
   MeshUtils::flipFacets(mesh_facets, data_accessor.getGlobalConnectivity(),
                         _ghost);
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void SolidMechanicsModelCohesive::updateCohesiveSynchronizers() {
   /// update synchronizers if needed
 
   if (not mesh.isDistributed())
     return;
 
   auto & mesh_facets = inserter->getMeshFacets();
   auto & facet_synchronizer = mesh_facets.getElementSynchronizer();
   const auto & cfacet_synchronizer = facet_synchronizer;
 
   // update the cohesive element synchronizer
   cohesive_synchronizer->updateSchemes([&](auto && scheme, auto && proc,
                                            auto && direction) {
     auto & facet_scheme =
         cfacet_synchronizer.getCommunications().getScheme(proc, direction);
 
     for (auto && facet : facet_scheme) {
       const auto & cohesive_element =
           const_cast<const Mesh &>(mesh_facets)
               .getElementToSubelement(facet)[1];
 
       if (cohesive_element == ElementNull or
           cohesive_element.kind() != _ek_cohesive)
         continue;
 
       auto && cohesive_type = FEEngine::getCohesiveElementType(facet.type);
       auto old_nb_cohesive_elements =
           mesh.getNbElement(cohesive_type, facet.ghost_type);
       old_nb_cohesive_elements -=
           mesh_facets
               .getData<UInt>("facet_to_double", facet.type, facet.ghost_type)
               .size();
 
       if (cohesive_element.element >= old_nb_cohesive_elements) {
         scheme.push_back(cohesive_element);
       }
     }
   });
 
   if (not facet_stress_synchronizer)
     return;
 
   const auto & element_synchronizer = mesh.getElementSynchronizer();
   const auto & comm = mesh.getCommunicator();
   auto && my_rank = comm.whoAmI();
 
   // update the facet stress synchronizer
   facet_stress_synchronizer->updateSchemes([&](auto && scheme, auto && proc,
                                                auto && /*direction*/) {
     auto it_element = scheme.begin();
     for (auto && element : scheme) {
       auto && facet_check = inserter->getCheckFacets(
           element.type, element.ghost_type)(element.element); // slow access
                                                               // here
 
       if (facet_check) {
         auto && connected_elements = mesh_facets.getElementToSubelement(
             element.type, element.ghost_type)(element.element); // slow access
                                                                 // here
         auto && rank_left = element_synchronizer.getRank(connected_elements[0]);
         auto && rank_right =
             element_synchronizer.getRank(connected_elements[1]);
 
         // keep element if the element is still a boundary element between two
         // processors
         if ((rank_left == Int(proc) and rank_right == my_rank) or
             (rank_left == my_rank and rank_right == Int(proc))) {
           *it_element = element;
           ++it_element;
         }
       }
     }
     scheme.resize(it_element - scheme.begin());
   });
 }
 
 /* -------------------------------------------------------------------------- */
 void SolidMechanicsModelCohesive::updateFacetStressSynchronizer() {
   if (facet_stress_synchronizer != nullptr) {
     const auto & rank_to_element =
         mesh.getElementSynchronizer().getElementToRank();
     const auto & facet_checks = inserter->getCheckFacets();
     const auto & mesh_facets = inserter->getMeshFacets();
     const auto & element_to_facet = mesh_facets.getElementToSubelement();
     UInt rank = mesh.getCommunicator().whoAmI();
 
     facet_stress_synchronizer->updateSchemes(
         [&](auto & scheme, auto & proc, auto & /*direction*/) {
           UInt el = 0;
           for (auto && element : scheme) {
             if (not facet_checks(element))
               continue;
 
             const auto & next_el = element_to_facet(element);
             UInt rank_left = rank_to_element(next_el[0]);
             UInt rank_right = rank_to_element(next_el[1]);
 
             if ((rank_left == rank and rank_right == proc) or
                 (rank_left == proc and rank_right == rank)) {
               scheme[el] = element;
               ++el;
             }
           }
           scheme.resize(el);
         });
   }
 }
 
 /* -------------------------------------------------------------------------- */
 template <typename T>
 void SolidMechanicsModelCohesive::packFacetStressDataHelper(
     const ElementTypeMapArray<T> & data_to_pack, CommunicationBuffer & buffer,
     const Array<Element> & elements) const {
   packUnpackFacetStressDataHelper<T, true>(
       const_cast<ElementTypeMapArray<T> &>(data_to_pack), buffer, elements);
 }
 
 /* -------------------------------------------------------------------------- */
 template <typename T>
 void SolidMechanicsModelCohesive::unpackFacetStressDataHelper(
     ElementTypeMapArray<T> & data_to_unpack, CommunicationBuffer & buffer,
     const Array<Element> & elements) const {
   packUnpackFacetStressDataHelper<T, false>(data_to_unpack, buffer, elements);
 }
 
 /* -------------------------------------------------------------------------- */
 template <typename T, bool pack_helper>
 void SolidMechanicsModelCohesive::packUnpackFacetStressDataHelper(
     ElementTypeMapArray<T> & data_to_pack, CommunicationBuffer & buffer,
     const Array<Element> & elements) const {
   ElementType current_element_type = _not_defined;
   GhostType current_ghost_type = _casper;
   UInt nb_quad_per_elem = 0;
   UInt sp2 = spatial_dimension * spatial_dimension;
   UInt nb_component = sp2 * 2;
   bool element_rank = false;
   Mesh & mesh_facets = inserter->getMeshFacets();
 
   Array<T> * vect = nullptr;
   Array<std::vector<Element>> * element_to_facet = nullptr;
 
   auto & fe_engine = this->getFEEngine("FacetsFEEngine");
   for (auto && el : elements) {
     if (el.type == _not_defined)
       AKANTU_EXCEPTION(
           "packUnpackFacetStressDataHelper called with wrong inputs");
 
     if (el.type != current_element_type ||
         el.ghost_type != current_ghost_type) {
       current_element_type = el.type;
       current_ghost_type = el.ghost_type;
       vect = &data_to_pack(el.type, el.ghost_type);
 
       element_to_facet =
           &(mesh_facets.getElementToSubelement(el.type, el.ghost_type));
 
       nb_quad_per_elem =
           fe_engine.getNbIntegrationPoints(el.type, el.ghost_type);
     }
 
     if (pack_helper)
       element_rank =
           (*element_to_facet)(el.element)[0].ghost_type != _not_ghost;
     else
       element_rank =
           (*element_to_facet)(el.element)[0].ghost_type == _not_ghost;
 
     for (UInt q = 0; q < nb_quad_per_elem; ++q) {
       Vector<T> data(vect->storage() +
                          (el.element * nb_quad_per_elem + q) * nb_component +
                          element_rank * sp2,
                      sp2);
 
       if (pack_helper)
         buffer << data;
       else
         buffer >> data;
     }
   }
 }
 
 /* -------------------------------------------------------------------------- */
 UInt SolidMechanicsModelCohesive::getNbQuadsForFacetCheck(
     const Array<Element> & elements) const {
   UInt nb_quads = 0;
   UInt nb_quad_per_facet = 0;
 
   ElementType current_element_type = _not_defined;
   GhostType current_ghost_type = _casper;
   auto & fe_engine = this->getFEEngine("FacetsFEEngine");
   for (auto & el : elements) {
     if (el.type != current_element_type ||
         el.ghost_type != current_ghost_type) {
       current_element_type = el.type;
       current_ghost_type = el.ghost_type;
 
       nb_quad_per_facet =
           fe_engine.getNbIntegrationPoints(el.type, el.ghost_type);
     }
 
     nb_quads += nb_quad_per_facet;
   }
 
   return nb_quads;
 }
 
 /* -------------------------------------------------------------------------- */
 UInt SolidMechanicsModelCohesive::getNbData(
     const Array<Element> & elements, const SynchronizationTag & tag) const {
   AKANTU_DEBUG_IN();
 
   UInt size = 0;
   if (elements.size() == 0)
     return 0;
 
   /// regular element case
   if (elements(0).kind() == _ek_regular) {
     switch (tag) {
-    case _gst_smmc_facets: {
-      size += elements.size() * sizeof(bool);
-      break;
-    }
+    // case _gst_smmc_facets: {
+    //   size += elements.size() * sizeof(bool);
+    //   break;
+    // }
     case _gst_smmc_facets_stress: {
       UInt nb_quads = getNbQuadsForFacetCheck(elements);
       size += nb_quads * spatial_dimension * spatial_dimension * sizeof(Real);
       break;
     }
     case _gst_material_id: {
       for (auto && element : elements) {
         if (Mesh::getSpatialDimension(element.type) == (spatial_dimension - 1))
           size += sizeof(UInt);
       }
 
       size += SolidMechanicsModel::getNbData(elements, tag);
       break;
     }
 
     default: { size += SolidMechanicsModel::getNbData(elements, tag); }
     }
   }
   /// cohesive element case
   else if (elements(0).kind() == _ek_cohesive) {
 
     switch (tag) {
     case _gst_material_id: {
       size += elements.size() * sizeof(UInt);
       break;
     }
     case _gst_smm_boundary: {
       UInt nb_nodes_per_element = 0;
 
       for (auto && el : elements) {
         nb_nodes_per_element += Mesh::getNbNodesPerElement(el.type);
       }
 
       // force, displacement, boundary
       size += nb_nodes_per_element * spatial_dimension *
               (2 * sizeof(Real) + sizeof(bool));
       break;
     }
     default:
       break;
     }
 
     if (tag != _gst_material_id && tag != _gst_smmc_facets) {
       splitByMaterial(elements, [&](auto && mat, auto && elements) {
         size += mat.getNbData(elements, tag);
       });
     }
   }
 
   AKANTU_DEBUG_OUT();
   return size;
 }
 
 /* -------------------------------------------------------------------------- */
 void SolidMechanicsModelCohesive::packData(
     CommunicationBuffer & buffer, const Array<Element> & elements,
     const SynchronizationTag & tag) const {
   AKANTU_DEBUG_IN();
 
   if (elements.size() == 0)
     return;
 
   if (elements(0).kind() == _ek_regular) {
     switch (tag) {
-    case _gst_smmc_facets: {
-      packElementalDataHelper(inserter->getInsertionFacetsByElement(), buffer,
-                              elements, false, getFEEngine());
-      break;
-    }
+    // case _gst_smmc_facets: {
+    //   packElementalDataHelper(inserter->getInsertionFacetsByElement(), buffer,
+    //                           elements, false, getFEEngine());
+    //   break;
+    // }
     case _gst_smmc_facets_stress: {
       packFacetStressDataHelper(facet_stress, buffer, elements);
       break;
     }
     case _gst_material_id: {
       for (auto && element : elements) {
         if (Mesh::getSpatialDimension(element.type) != (spatial_dimension - 1))
           continue;
         buffer << material_index(element);
       }
 
       SolidMechanicsModel::packData(buffer, elements, tag);
       break;
     }
     default: { SolidMechanicsModel::packData(buffer, elements, tag); }
     }
 
     AKANTU_DEBUG_OUT();
     return;
   }
 
   if (elements(0).kind() == _ek_cohesive) {
     switch (tag) {
     case _gst_material_id: {
       packElementalDataHelper(material_index, buffer, elements, false,
                               getFEEngine("CohesiveFEEngine"));
       break;
     }
     case _gst_smm_boundary: {
       packNodalDataHelper(*internal_force, buffer, elements, mesh);
       packNodalDataHelper(*velocity, buffer, elements, mesh);
       packNodalDataHelper(*blocked_dofs, buffer, elements, mesh);
       break;
     }
     default: {}
     }
 
     if (tag != _gst_material_id && tag != _gst_smmc_facets) {
       splitByMaterial(elements, [&](auto && mat, auto && elements) {
         mat.packData(buffer, elements, tag);
       });
     }
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void SolidMechanicsModelCohesive::unpackData(CommunicationBuffer & buffer,
                                              const Array<Element> & elements,
                                              const SynchronizationTag & tag) {
   AKANTU_DEBUG_IN();
 
   if (elements.size() == 0)
     return;
 
   if (elements(0).kind() == _ek_regular) {
     switch (tag) {
-    case _gst_smmc_facets: {
-      unpackElementalDataHelper(inserter->getInsertionFacetsByElement(), buffer,
-                                elements, false, getFEEngine());
-      break;
-    }
+    // case _gst_smmc_facets: {
+    //   unpackElementalDataHelper(inserter->getInsertionFacetsByElement(), buffer,
+    //                             elements, false, getFEEngine());
+    //   break;
+    // }
     case _gst_smmc_facets_stress: {
       unpackFacetStressDataHelper(facet_stress, buffer, elements);
       break;
     }
     case _gst_material_id: {
       for (auto && element : elements) {
         if (Mesh::getSpatialDimension(element.type) != (spatial_dimension - 1))
           continue;
 
         UInt recv_mat_index;
         buffer >> recv_mat_index;
         UInt & mat_index = material_index(element);
         if (mat_index != UInt(-1))
           continue;
 
         // add ghosts element to the correct material
         mat_index = recv_mat_index;
         auto & mat = dynamic_cast<MaterialCohesive &>(*materials[mat_index]);
-        mat.addFacet(element);
+        if (is_extrinsic) {
+          mat.addFacet(element);
+        }
         facet_material(element) = recv_mat_index;
       }
       SolidMechanicsModel::unpackData(buffer, elements, tag);
       break;
     }
     default: { SolidMechanicsModel::unpackData(buffer, elements, tag); }
     }
 
     AKANTU_DEBUG_OUT();
     return;
   }
 
   if (elements(0).kind() == _ek_cohesive) {
     switch (tag) {
     case _gst_material_id: {
       for (auto && element : elements) {
         UInt recv_mat_index;
         buffer >> recv_mat_index;
         UInt & mat_index = material_index(element);
         if (mat_index != UInt(-1))
           continue;
 
         // add ghosts element to the correct material
         mat_index = recv_mat_index;
         UInt index = materials[mat_index]->addElement(element);
         material_local_numbering(element) = index;
       }
       break;
     }
     case _gst_smm_boundary: {
       unpackNodalDataHelper(*internal_force, buffer, elements, mesh);
       unpackNodalDataHelper(*velocity, buffer, elements, mesh);
       unpackNodalDataHelper(*blocked_dofs, buffer, elements, mesh);
       break;
     }
     default: {}
     }
 
     if (tag != _gst_material_id && tag != _gst_smmc_facets) {
       splitByMaterial(elements, [&](auto && mat, auto && elements) {
         mat.unpackData(buffer, elements, tag);
       });
     }
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 
 } // namespace akantu