diff --git a/src/common/aka_common.hh b/src/common/aka_common.hh
index 29de7f949..95abb457a 100644
--- a/src/common/aka_common.hh
+++ b/src/common/aka_common.hh
@@ -1,698 +1,714 @@
 /**
  * @file   aka_common.hh
  *
  * @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Mon Jun 14 2010
  * @date last modification: Mon Feb 12 2018
  *
  * @brief  common type descriptions for akantu
  *
  *
  * 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/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 
 #ifndef AKANTU_COMMON_HH_
 #define AKANTU_COMMON_HH_
 
 #include "aka_compatibilty_with_cpp_standard.hh"
 
 /* -------------------------------------------------------------------------- */
 #if defined(WIN32)
 #define __attribute__(x)
 #endif
 
 /* -------------------------------------------------------------------------- */
 #include "aka_config.hh"
 #include "aka_error.hh"
 #include "aka_safe_enum.hh"
 /* -------------------------------------------------------------------------- */
 #include <boost/preprocessor.hpp>
 #include <limits>
 #include <list>
 #include <memory>
 #include <string>
 #include <type_traits>
 #include <unordered_map>
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 /* Constants                                                                  */
 /* -------------------------------------------------------------------------- */
 namespace {
   [[gnu::unused]] constexpr UInt _all_dimensions{
       std::numeric_limits<UInt>::max()};
 #ifdef AKANTU_NDEBUG
   [[gnu::unused]] constexpr Real REAL_INIT_VALUE{0.};
 #else
   [[gnu::unused]] constexpr Real REAL_INIT_VALUE{
       std::numeric_limits<Real>::quiet_NaN()};
 #endif
 } // namespace
 
 /* -------------------------------------------------------------------------- */
 /* Common types                                                               */
 /* -------------------------------------------------------------------------- */
 using ID = std::string;
 } // namespace akantu
 
 /* -------------------------------------------------------------------------- */
 #include "aka_enum_macros.hh"
 /* -------------------------------------------------------------------------- */
 #include "aka_element_classes_info.hh"
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 /* -------------------------------------------------------------------------- */
 /* Mesh/FEM/Model types                                                       */
 /* -------------------------------------------------------------------------- */
 
 /// small help to use names for directions
 enum SpatialDirection { _x = 0, _y = 1, _z = 2 };
 
 /// enum MeshIOType type of mesh reader/writer
 enum MeshIOType {
   _miot_auto,        ///< Auto guess of the reader to use based on the extension
   _miot_gmsh,        ///< Gmsh files
   _miot_gmsh_struct, ///< Gsmh reader with reintpretation of elements has
                      /// structures elements
   _miot_diana,       ///< TNO Diana mesh format
   _miot_abaqus       ///< Abaqus mesh format
 };
 
 /// enum MeshEventHandlerPriority defines relative order of execution of
 /// events
 enum EventHandlerPriority {
   _ehp_highest = 0,
   _ehp_mesh = 5,
   _ehp_fe_engine = 9,
   _ehp_synchronizer = 10,
   _ehp_dof_manager = 20,
   _ehp_model = 94,
   _ehp_non_local_manager = 100,
   _ehp_lowest = 100
 };
 
 #if !defined(DOXYGEN)
 // clang-format off
 #define AKANTU_MODEL_TYPES                      \
   (model)                                       \
   (solid_mechanics_model)                       \
   (solid_mechanics_model_cohesive)              \
   (heat_transfer_model)                         \
   (structural_mechanics_model)                  \
   (embedded_model)                              \
   (contact_mechanics_model)                     \
   (coupler_solid_contact)                       \
   (coupler_solid_cohesive_contact)              \
   (phase_field_model)                           \
   (coupler_solid_phasefield)
 // clang-format on
 
 /// enum ModelType defines which type of physics is solved
 AKANTU_CLASS_ENUM_DECLARE(ModelType, AKANTU_MODEL_TYPES)
 AKANTU_CLASS_ENUM_OUTPUT_STREAM(ModelType, AKANTU_MODEL_TYPES)
 AKANTU_CLASS_ENUM_INPUT_STREAM(ModelType, AKANTU_MODEL_TYPES)
 #else
 enum class ModelType {
   model,
   solid_mechanics_model,
   solid_mechanics_model_cohesive,
   heat_transfer_model,
   structural_mechanics_model,
   embedded_model,
 };
 #endif
 /// enum AnalysisMethod type of solving method used to solve the equation of
 /// motion
 enum AnalysisMethod {
   _static = 0,
   _implicit_dynamic = 1,
   _explicit_lumped_mass = 2,
   _explicit_lumped_capacity = 2,
   _explicit_consistent_mass = 3,
   _explicit_contact = 4,
   _implicit_contact = 5
 };
 
 /// enum DOFSupportType defines which kind of dof that can exists
 enum DOFSupportType { _dst_nodal, _dst_generic };
 
 #if !defined(DOXYGEN)
 // clang-format off
 #define AKANTU_NON_LINEAR_SOLVER_TYPES                                 \
   (linear)                                                             \
   (newton_raphson)                                                     \
   (newton_raphson_modified)                                            \
   (lumped)                                                             \
   (gmres)                                                              \
   (bfgs)                                                               \
   (cg)                                                                 \
   (newton_raphson_contact)                                             \
   (auto)
 // clang-format on
 AKANTU_CLASS_ENUM_DECLARE(NonLinearSolverType, AKANTU_NON_LINEAR_SOLVER_TYPES)
 AKANTU_CLASS_ENUM_OUTPUT_STREAM(NonLinearSolverType,
                                 AKANTU_NON_LINEAR_SOLVER_TYPES)
 AKANTU_CLASS_ENUM_INPUT_STREAM(NonLinearSolverType,
                                AKANTU_NON_LINEAR_SOLVER_TYPES)
 #else
 /// Type of non linear resolution available in akantu
 enum class NonLinearSolverType {
   _linear,                  ///< No non linear convergence loop
   _newton_raphson,          ///< Regular Newton-Raphson
   _newton_raphson_modified, ///< Newton-Raphson with initial tangent
   _lumped,                  ///< Case of lumped mass or equivalent matrix
   _gmres,
   _bfgs,
   _cg,
-  _newton_raphson_contact,  ///< Regular Newton-Raphson modified
-                            /// for contact problem
-  _auto,  ///< This will take a default value that make sense in case of
-          ///  model::getNewSolver
+  _newton_raphson_contact, ///< Regular Newton-Raphson modified
+                           /// for contact problem
+  _auto, ///< This will take a default value that make sense in case of
+         ///  model::getNewSolver
 };
 #endif
 
 #if !defined(DOXYGEN)
 // clang-format off
 #define AKANTU_TIME_STEP_SOLVER_TYPE                                    \
   (static)                                                             \
   (dynamic)                                                            \
   (dynamic_lumped)                                                     \
   (not_defined)
 // clang-format on
 AKANTU_CLASS_ENUM_DECLARE(TimeStepSolverType, AKANTU_TIME_STEP_SOLVER_TYPE)
 AKANTU_CLASS_ENUM_OUTPUT_STREAM(TimeStepSolverType,
                                 AKANTU_TIME_STEP_SOLVER_TYPE)
 AKANTU_CLASS_ENUM_INPUT_STREAM(TimeStepSolverType, AKANTU_TIME_STEP_SOLVER_TYPE)
 #else
 /// Type of time stepping solver
 enum class TimeStepSolverType {
   _static,         ///< Static solution
   _dynamic,        ///< Dynamic solver
   _dynamic_lumped, ///< Dynamic solver with lumped mass
   _not_defined,    ///< For not defined cases
 };
 #endif
 
 #if !defined(DOXYGEN)
 // clang-format off
 #define AKANTU_INTEGRATION_SCHEME_TYPE                                 \
   (pseudo_time)                                                        \
   (forward_euler)                                                      \
   (trapezoidal_rule_1)                                                 \
   (backward_euler)                                                     \
   (central_difference)                                                 \
   (fox_goodwin)                                                        \
   (trapezoidal_rule_2)                                                 \
   (linear_acceleration)                                                \
   (newmark_beta)                                                       \
   (generalized_trapezoidal)
 // clang-format on
 AKANTU_CLASS_ENUM_DECLARE(IntegrationSchemeType, AKANTU_INTEGRATION_SCHEME_TYPE)
 AKANTU_CLASS_ENUM_OUTPUT_STREAM(IntegrationSchemeType,
                                 AKANTU_INTEGRATION_SCHEME_TYPE)
 AKANTU_CLASS_ENUM_INPUT_STREAM(IntegrationSchemeType,
                                AKANTU_INTEGRATION_SCHEME_TYPE)
 #else
 /// Type of integration scheme
 enum class IntegrationSchemeType {
   _pseudo_time,            ///< Pseudo Time
   _forward_euler,          ///< GeneralizedTrapezoidal(0)
   _trapezoidal_rule_1,     ///< GeneralizedTrapezoidal(1/2)
   _backward_euler,         ///< GeneralizedTrapezoidal(1)
   _central_difference,     ///< NewmarkBeta(0, 1/2)
   _fox_goodwin,            ///< NewmarkBeta(1/6, 1/2)
   _trapezoidal_rule_2,     ///< NewmarkBeta(1/2, 1/2)
   _linear_acceleration,    ///< NewmarkBeta(1/3, 1/2)
   _newmark_beta,           ///< generic NewmarkBeta with user defined
                            /// alpha and beta
   _generalized_trapezoidal ///< generic GeneralizedTrapezoidal with user
                            ///  defined alpha
 };
 #endif
 
 #if !defined(DOXYGEN)
 // clang-format off
 #define AKANTU_SOLVE_CONVERGENCE_CRITERIA       \
   (residual)                                    \
   (solution)                                    \
   (residual_mass_wgh)
 // clang-format on
 AKANTU_CLASS_ENUM_DECLARE(SolveConvergenceCriteria,
                           AKANTU_SOLVE_CONVERGENCE_CRITERIA)
 AKANTU_CLASS_ENUM_OUTPUT_STREAM(SolveConvergenceCriteria,
                                 AKANTU_SOLVE_CONVERGENCE_CRITERIA)
 AKANTU_CLASS_ENUM_INPUT_STREAM(SolveConvergenceCriteria,
                                AKANTU_SOLVE_CONVERGENCE_CRITERIA)
 #else
 /// enum SolveConvergenceCriteria different convergence criteria
 enum class SolveConvergenceCriteria {
   _residual,         ///< Use residual to test the convergence
   _solution,         ///< Use solution to test the convergence
   _residual_mass_wgh ///< Use residual weighted by inv. nodal mass to
                      ///< testb
 };
 #endif
 
 /// enum CohesiveMethod type of insertion of cohesive elements
 enum CohesiveMethod { _intrinsic, _extrinsic };
 
 /// @enum MatrixType type of sparse matrix used
 enum MatrixType { _unsymmetric, _symmetric, _mt_not_defined };
 
 /// @enum Type of contact detection
-enum DetectionType { _explicit, _implicit};
+enum DetectionType { _explicit, _implicit };
 
+
+#if !defined(DOXYGEN)
+// clang-format off
+#define AKANTU_CONTACT_STATE                      \
+  (no_contact)                                    \
+  (stick)                                         \
+  (slip)
+// clang-format on
+AKANTU_CLASS_ENUM_DECLARE(ContactState,
+                          AKANTU_CONTACT_STATE)
+AKANTU_CLASS_ENUM_OUTPUT_STREAM(ContactState,
+                                AKANTU_CONTACT_STATE)
+AKANTU_CLASS_ENUM_INPUT_STREAM(ContactState,
+                               AKANTU_CONTACT_STATE)
+#else
 /// @enum no contact or stick or slip state
 enum class ContactState {
   _no_contact = 0,
   _stick = 1,
   _slip = 2,
 };
-  
+#endif
+
 /* -------------------------------------------------------------------------- */
 /* Ghosts handling                                                            */
 /* -------------------------------------------------------------------------- */
 /// @enum CommunicatorType type of communication method to use
 enum CommunicatorType { _communicator_mpi, _communicator_dummy };
 
 #if !defined(DOXYGEN)
 // clang-format off
 #define AKANTU_SYNCHRONIZATION_TAG              \
   (whatever)                                    \
   (update)                                      \
   (ask_nodes)                                   \
   (size)                                        \
   (smm_mass)                                    \
   (smm_for_gradu)                               \
   (smm_boundary)                                \
   (smm_uv)                                      \
   (smm_res)                                     \
   (smm_init_mat)                                \
   (smm_stress)                                  \
   (smmc_facets)                                 \
   (smmc_facets_conn)                            \
   (smmc_facets_stress)                          \
   (smmc_damage)                                 \
   (giu_global_conn)                             \
   (ce_groups)                                   \
   (ce_insertion_order)                          \
   (gm_clusters)                                 \
   (htm_temperature)                             \
   (htm_gradient_temperature)                    \
   (htm_phi)                                     \
   (htm_gradient_phi)                            \
   (pfm_damage)                                  \
   (pfm_driving)                                 \
   (pfm_history)                                 \
   (pfm_energy)                                  \
   (csp_damage)                                  \
   (csp_strain)                                  \
   (mnl_for_average)                             \
   (mnl_weight)                                  \
   (nh_criterion)                                \
   (test)                                        \
   (user_1)                                      \
   (user_2)                                      \
   (material_id)                                 \
   (for_dump)                                    \
   (cf_nodal)                                    \
   (cf_incr)                                     \
   (solver_solution)
 // clang-format on
 AKANTU_CLASS_ENUM_DECLARE(SynchronizationTag, AKANTU_SYNCHRONIZATION_TAG)
 AKANTU_CLASS_ENUM_OUTPUT_STREAM(SynchronizationTag, AKANTU_SYNCHRONIZATION_TAG)
 #else
 /// @enum SynchronizationTag type of synchronizations
 enum class SynchronizationTag {
   //--- Generic tags ---
   _whatever,
   _update,
   _ask_nodes,
   _size,
 
   //--- SolidMechanicsModel tags ---
   _smm_mass,      ///< synchronization of the SolidMechanicsModel.mass
   _smm_for_gradu, ///< synchronization of the
                   /// SolidMechanicsModel.displacement
   _smm_boundary,  ///< synchronization of the boundary, forces, velocities
                   /// and displacement
   _smm_uv,        ///< synchronization of the nodal velocities and displacement
   _smm_res,       ///< synchronization of the nodal residual
   _smm_init_mat,  ///< synchronization of the data to initialize materials
   _smm_stress,    ///< synchronization of the stresses to compute the
                   ///< internal
                   /// forces
   _smmc_facets,   ///< synchronization of facet data to setup facet synch
   _smmc_facets_conn,   ///< synchronization of facet global connectivity
   _smmc_facets_stress, ///< synchronization of facets' stress to setup
                        ///< facet
                        /// synch
   _smmc_damage,        ///< synchronization of damage
 
   // --- GlobalIdsUpdater tags ---
   _giu_global_conn, ///< synchronization of global connectivities
 
   // --- CohesiveElementInserter tags ---
   _ce_groups, ///< synchronization of cohesive element insertion depending
               /// on facet groups
   _ce_insertion_order, ///< synchronization of the order of insertion of
                        /// cohesive elements
 
   // --- GroupManager tags ---
   _gm_clusters, ///< synchronization of clusters
 
   // --- HeatTransfer tags ---
   _htm_temperature,          ///< synchronization of the nodal temperature
   _htm_gradient_temperature, ///< synchronization of the element gradient
                              /// temperature
 
   // --- PhaseFieldModel tags ---
-  _pfm_damage,          ///< synchronization of the nodal damage
-  _pfm_driving,         ///< synchronization of the driving forces to
-                        /// compute the internal
-  _pfm_history,         ///< synchronization of the damage history to
-                        ///  compute the internal
-  _pfm_energy,          ///< synchronization of the damage energy
-                        /// density to compute the internal
+  _pfm_damage,  ///< synchronization of the nodal damage
+  _pfm_driving, ///< synchronization of the driving forces to
+                /// compute the internal
+  _pfm_history, ///< synchronization of the damage history to
+                ///  compute the internal
+  _pfm_energy,  ///< synchronization of the damage energy
+                /// density to compute the internal
 
   // --- CouplerSolidPhaseField tags ---
-  _csp_damage,        ///< synchronization of the damage from phase
-                      /// model to solid model
-  _csp_strain,        ///< synchronization of the strain from solid
-                      /// model to phase model
-  
+  _csp_damage, ///< synchronization of the damage from phase
+               /// model to solid model
+  _csp_strain, ///< synchronization of the strain from solid
+               /// model to phase model
+
   // --- LevelSet tags ---
   _htm_phi,          ///< synchronization of the nodal level set value phi
   _htm_gradient_phi, ///< synchronization of the element gradient phi
 
   _pfm_damage,
   _pfm_gradient_damage,
-  
+
   //--- Material non local ---
   _mnl_for_average, ///< synchronization of data to average in non local
                     /// material
   _mnl_weight,      ///< synchronization of data for the weight computations
 
   // --- NeighborhoodSynchronization tags ---
   _nh_criterion,
 
   // --- General tags ---
   _test,        ///< Test tag
   _user_1,      ///< tag for user simulations
   _user_2,      ///< tag for user simulations
   _material_id, ///< synchronization of the material ids
   _for_dump,    ///< everything that needs to be synch before dump
 
   // --- Contact & Friction ---
   _cf_nodal, ///< synchronization of disp, velo, and current position
   _cf_incr,  ///< synchronization of increment
 
   // --- Solver tags ---
   _solver_solution ///< synchronization of the solution obained with the
                    /// PETSc solver
 };
 #endif
 
 /// @enum GhostType type of ghost
 enum GhostType {
   _not_ghost = 0,
   _ghost = 1,
   _casper // not used but a real cute ghost
 };
 
 /// Define the flag that can be set to a node
 enum class NodeFlag : std::uint8_t {
   _normal = 0x00,
   _distributed = 0x01,
   _master = 0x03,
   _slave = 0x05,
   _pure_ghost = 0x09,
   _shared_mask = 0x0F,
   _periodic = 0x10,
   _periodic_master = 0x30,
   _periodic_slave = 0x50,
   _periodic_mask = 0xF0,
   _local_master_mask = 0xCC, // ~(_master & _periodic_mask)
 };
 
 inline NodeFlag operator&(const NodeFlag & a, const NodeFlag & b) {
   using under = std::underlying_type_t<NodeFlag>;
   return NodeFlag(under(a) & under(b));
 }
 
 inline NodeFlag operator|(const NodeFlag & a, const NodeFlag & b) {
   using under = std::underlying_type_t<NodeFlag>;
   return NodeFlag(under(a) | under(b));
 }
 
 inline NodeFlag & operator|=(NodeFlag & a, const NodeFlag & b) {
   a = a | b;
   return a;
 }
 
 inline NodeFlag & operator&=(NodeFlag & a, const NodeFlag & b) {
   a = a & b;
   return a;
 }
 
 inline NodeFlag operator~(const NodeFlag & a) {
   using under = std::underlying_type_t<NodeFlag>;
   return NodeFlag(~under(a));
 }
 
 std::ostream & operator<<(std::ostream & stream, NodeFlag flag);
 
 } // namespace akantu
 
 AKANTU_ENUM_HASH(GhostType)
 
 namespace akantu {
 /* -------------------------------------------------------------------------- */
 struct GhostType_def {
   using type = GhostType;
   static const type _begin_ = _not_ghost;
   static const type _end_ = _casper;
 };
 
 using ghost_type_t = safe_enum<GhostType_def>;
 namespace {
   constexpr ghost_type_t ghost_types{_casper};
 }
 
 /// standard output stream operator for GhostType
 // inline std::ostream & operator<<(std::ostream & stream, GhostType type);
 
 /* -------------------------------------------------------------------------- */
 /* Global defines                                                             */
 /* -------------------------------------------------------------------------- */
 #define AKANTU_MIN_ALLOCATION 2000
 
 #define AKANTU_INDENT ' '
 #define AKANTU_INCLUDE_INLINE_IMPL
 
 /* -------------------------------------------------------------------------- */
 #define AKANTU_SET_MACRO(name, variable, type)                                 \
   inline void set##name(type variable) { this->variable = variable; }
 
 #define AKANTU_GET_MACRO(name, variable, type)                                 \
   inline type get##name() const { return variable; }
 
 #define AKANTU_GET_MACRO_NOT_CONST(name, variable, type)                       \
   inline type get##name() { return variable; }
 
 #define AKANTU_GET_MACRO_DEREF_PTR(name, ptr)                                  \
   inline const auto & get##name() const {                                      \
     if (not(ptr)) {                                                            \
       AKANTU_EXCEPTION("The member " << #ptr << " is not initialized");        \
     }                                                                          \
     return (*(ptr));                                                           \
   }
 
 #define AKANTU_GET_MACRO_DEREF_PTR_NOT_CONST(name, ptr)                        \
   inline auto & get##name() {                                                  \
     if (not(ptr)) {                                                            \
       AKANTU_EXCEPTION("The member " << #ptr << " is not initialized");        \
     }                                                                          \
     return (*(ptr));                                                           \
   }
 
 #define AKANTU_GET_MACRO_BY_SUPPORT_TYPE(name, variable, type, support, con)   \
   inline con Array<type> & get##name(const support & el_type,                  \
                                      GhostType ghost_type = _not_ghost)        \
       con { /* NOLINT */                                                       \
     return variable(el_type, ghost_type);                                      \
   } // NOLINT
 
 #define AKANTU_GET_MACRO_BY_ELEMENT_TYPE(name, variable, type)                 \
   AKANTU_GET_MACRO_BY_SUPPORT_TYPE(name, variable, type, ElementType, )
 #define AKANTU_GET_MACRO_BY_ELEMENT_TYPE_CONST(name, variable, type)           \
   AKANTU_GET_MACRO_BY_SUPPORT_TYPE(name, variable, type, ElementType, const)
 
 #define AKANTU_GET_MACRO_BY_GEOMETRIE_TYPE(name, variable, type)               \
   AKANTU_GET_MACRO_BY_SUPPORT_TYPE(name, variable, type, GeometricalType, )
 #define AKANTU_GET_MACRO_BY_GEOMETRIE_TYPE_CONST(name, variable, type)         \
   AKANTU_GET_MACRO_BY_SUPPORT_TYPE(name, variable, type, GeometricalType, const)
 
 /* -------------------------------------------------------------------------- */
 /// initialize the static part of akantu
 void initialize(int & argc, char **& argv);
 /// initialize the static part of akantu and read the global input_file
 void initialize(const std::string & input_file, int & argc, char **& argv);
 /* -------------------------------------------------------------------------- */
 /// finilize correctly akantu and clean the memory
 void finalize();
 /* -------------------------------------------------------------------------- */
 /// Read an new input file
 void readInputFile(const std::string & input_file);
 /* -------------------------------------------------------------------------- */
 
 /* -------------------------------------------------------------------------- */
 /* string manipulation */
 /* -------------------------------------------------------------------------- */
 inline std::string to_lower(const std::string & str);
 /* -------------------------------------------------------------------------- */
 inline std::string trim(const std::string & to_trim);
 inline std::string trim(const std::string & to_trim, char c);
 /* -------------------------------------------------------------------------- */
 
 /* -------------------------------------------------------------------------- */
 /// give a string representation of the a human readable size in bit
 template <typename T> std::string printMemorySize(UInt size);
 /* -------------------------------------------------------------------------- */
 
 struct TensorTrait {};
 struct TensorProxyTrait {};
 
 } // namespace akantu
 
 /* -------------------------------------------------------------------------- */
 /* Type traits                                                                */
 /* -------------------------------------------------------------------------- */
 namespace aka {
 
 /* ------------------------------------------------------------------------ */
 template <typename T> using is_tensor = std::is_base_of<akantu::TensorTrait, T>;
 template <typename T>
 using is_tensor_proxy = std::is_base_of<akantu::TensorProxyTrait, T>;
 /* ------------------------------------------------------------------------ */
 template <typename T> using is_scalar = std::is_arithmetic<T>;
 /* ------------------------------------------------------------------------ */
 template <typename R, typename T,
           std::enable_if_t<std::is_reference<T>::value> * = nullptr>
 bool is_of_type(T && t) {
   return (
       dynamic_cast<std::add_pointer_t<
           std::conditional_t<std::is_const<std::remove_reference_t<T>>::value,
                              std::add_const_t<R>, R>>>(&t) != nullptr);
 }
 
 /* -------------------------------------------------------------------------- */
 template <typename R, typename T> bool is_of_type(std::unique_ptr<T> & t) {
   return (
       dynamic_cast<std::add_pointer_t<
           std::conditional_t<std::is_const<T>::value, std::add_const_t<R>, R>>>(
           t.get()) != nullptr);
 }
 
 /* ------------------------------------------------------------------------ */
 template <typename R, typename T,
           std::enable_if_t<std::is_reference<T>::value> * = nullptr>
 decltype(auto) as_type(T && t) {
   static_assert(
       disjunction<
           std::is_base_of<std::decay_t<T>, std::decay_t<R>>, // down-cast
           std::is_base_of<std::decay_t<R>, std::decay_t<T>>  // up-cast
           >::value,
       "Type T and R are not valid for a as_type conversion");
   return dynamic_cast<std::add_lvalue_reference_t<
       std::conditional_t<std::is_const<std::remove_reference_t<T>>::value,
                          std::add_const_t<R>, R>>>(t);
 }
 
 /* -------------------------------------------------------------------------- */
 template <typename R, typename T,
           std::enable_if_t<std::is_pointer<T>::value> * = nullptr>
 decltype(auto) as_type(T && t) {
   return &as_type<R>(*t);
 }
 
 /* -------------------------------------------------------------------------- */
 template <typename R, typename T>
 decltype(auto) as_type(const std::shared_ptr<T> & t) {
   return std::dynamic_pointer_cast<R>(t);
 }
 
 } // namespace aka
 
 #include "aka_common_inline_impl.hh"
 
 #include "aka_fwd.hh"
 
 namespace akantu {
 /// get access to the internal argument parser
 cppargparse::ArgumentParser & getStaticArgumentParser();
 
 /// get access to the internal input file parser
 Parser & getStaticParser();
 
 /// get access to the user part of the internal input file parser
 const ParserSection & getUserParser();
 
 #define AKANTU_CURRENT_FUNCTION                                                \
   (std::string(__func__) + "():" + std::to_string(__LINE__))
 
 } // namespace akantu
 
 /* -------------------------------------------------------------------------- */
 #if AKANTU_INTEGER_SIZE == 4
 #define AKANTU_HASH_COMBINE_MAGIC_NUMBER 0x9e3779b9
 #elif AKANTU_INTEGER_SIZE == 8
 #define AKANTU_HASH_COMBINE_MAGIC_NUMBER 0x9e3779b97f4a7c13LL
 #endif
 
 namespace std {
 /**
  * Hashing function for pairs based on hash_combine from boost The magic
  * number is coming from the golden number @f[\phi = \frac{1 + \sqrt5}{2}@f]
  * @f[\frac{2^32}{\phi} = 0x9e3779b9@f]
  * http://stackoverflow.com/questions/4948780/magic-number-in-boosthash-combine
  * http://burtleburtle.net/bob/hash/doobs.html
  */
 template <typename a, typename b> struct hash<std::pair<a, b>> {
   hash() = default;
   size_t operator()(const std::pair<a, b> & p) const {
     size_t seed = ah(p.first);
     return bh(p.second) + AKANTU_HASH_COMBINE_MAGIC_NUMBER + (seed << 6) +
            (seed >> 2);
   }
 
 private:
   const hash<a> ah{};
   const hash<b> bh{};
 };
 
 } // namespace std
 
 #endif // AKANTU_COMMON_HH_
diff --git a/src/common/aka_math.hh b/src/common/aka_math.hh
index 7e1121d91..a1df46c8e 100644
--- a/src/common/aka_math.hh
+++ b/src/common/aka_math.hh
@@ -1,283 +1,284 @@
 /**
  * @file   aka_math.hh
  *
  * @author Ramin Aghababaei <ramin.aghababaei@epfl.ch>
  * @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
  * @author Marion Estelle Chambart <marion.chambart@epfl.ch>
  * @author David Simon Kammer <david.kammer@epfl.ch>
  * @author Daniel Pino Muñoz <daniel.pinomunoz@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  * @author Leonardo Snozzi <leonardo.snozzi@epfl.ch>
  * @author Peter Spijker <peter.spijker@epfl.ch>
  * @author Marco Vocialta <marco.vocialta@epfl.ch>
  *
  * @date creation: Wed Aug 04 2010
  * @date last modification: Mon Sep 11 2017
  *
  * @brief  mathematical operations
  *
  *
  * 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 "aka_common.hh"
 /* -------------------------------------------------------------------------- */
 #include <utility>
 /* -------------------------------------------------------------------------- */
 
 #ifndef AKANTU_AKA_MATH_H_
 #define AKANTU_AKA_MATH_H_
 
 namespace akantu {
 /* -------------------------------------------------------------------------- */
 
 namespace Math {
   /// tolerance for functions that need one
   extern Real tolerance; // NOLINT
 
   /* ------------------------------------------------------------------------ */
   /* Matrix algebra                                                           */
   /* ------------------------------------------------------------------------ */
   /// @f$ y = A*x @f$
   void matrix_vector(UInt m, UInt n, const Array<Real> & A,
                      const Array<Real> & x, Array<Real> & y, Real alpha = 1.);
 
   /// @f$ y = A*x @f$
   inline void matrix_vector(UInt m, UInt n, Real * A, Real * x, Real * y,
                             Real alpha = 1.);
 
   /// @f$ y = A^t*x @f$
   inline void matrixt_vector(UInt m, UInt n, Real * A, Real * x, Real * y,
                              Real alpha = 1.);
 
   /// @f$ C = A*B @f$
   void matrix_matrix(UInt m, UInt n, UInt k, const Array<Real> & A,
                      const Array<Real> & B, Array<Real> & C, Real alpha = 1.);
 
   /// @f$ C = A*B^t @f$
   void matrix_matrixt(UInt m, UInt n, UInt k, const Array<Real> & A,
                       const Array<Real> & B, Array<Real> & C, Real alpha = 1.);
 
   /// @f$ C = A*B @f$
   inline void matrix_matrix(UInt m, UInt n, UInt k, Real * A, Real * B,
                             Real * C, Real alpha = 1.);
 
   /// @f$ C = A^t*B @f$
   inline void matrixt_matrix(UInt m, UInt n, UInt k, Real * A, Real * B,
                              Real * C, Real alpha = 1.);
 
   /// @f$ C = A*B^t @f$
   inline void matrix_matrixt(UInt m, UInt n, UInt k, Real * A, Real * B,
                              Real * C, Real alpha = 1.);
 
   /// @f$ C = A^t*B^t @f$
   inline void matrixt_matrixt(UInt m, UInt n, UInt k, Real * A, Real * B,
                               Real * C, Real alpha = 1.);
 
   template <bool tr_A, bool tr_B>
   inline void matMul(UInt m, UInt n, UInt k, Real alpha, Real * A, Real * B,
                      Real beta, Real * C);
 
   template <bool tr_A>
   inline void matVectMul(UInt m, UInt n, Real alpha, Real * A, Real * x,
                          Real beta, Real * y);
 
   inline void aXplusY(UInt n, Real alpha, Real * x, Real * y);
 
   inline void matrix33_eigenvalues(Real * A, Real * Adiag);
 
   inline void matrix22_eigenvalues(Real * A, Real * Adiag);
   template <UInt dim> inline void eigenvalues(Real * A, Real * d);
 
   /// solve @f$ A x = \Lambda x @f$ and return d and V such as @f$ A V[i:] =
   /// d[i] V[i:]@f$
   template <typename T> void matrixEig(UInt n, T * A, T * d, T * V = nullptr);
 
   /// determinent of a 2x2 matrix
   Real det2(const Real * mat);
   /// determinent of a 3x3 matrix
   Real det3(const Real * mat);
   /// determinent of a nxn matrix
   template <UInt n> Real det(const Real * mat);
   /// determinent of a nxn matrix
   template <typename T> T det(UInt n, const T * A);
 
   /// inverse a nxn matrix
   template <UInt n> inline void inv(const Real * A, Real * inv);
   /// inverse a nxn matrix
   template <typename T> inline void inv(UInt n, const T * A, T * inv);
   /// inverse a 3x3 matrix
   inline void inv3(const Real * mat, Real * inv);
   /// inverse a 2x2 matrix
   inline void inv2(const Real * mat, Real * inv);
 
   /// solve A x = b using a LU factorization
   template <typename T>
   inline void solve(UInt n, const T * A, T * x, const T * b);
 
   /// return the double dot product between 2 tensors in 2d
   inline Real matrixDoubleDot22(Real * A, Real * B);
 
   /// return the double dot product between 2 tensors in 3d
   inline Real matrixDoubleDot33(Real * A, Real * B);
 
   /// extension of the double dot product to two 2nd order tensor in dimension n
   inline Real matrixDoubleDot(UInt n, Real * A, Real * B);
 
   /* ------------------------------------------------------------------------ */
   /* Array algebra                                                            */
   /* ------------------------------------------------------------------------ */
   /// vector cross product
   inline void vectorProduct3(const Real * v1, const Real * v2, Real * res);
 
   /// normalize a vector
   inline void normalize2(Real * v);
 
   /// normalize a vector
   inline void normalize3(Real * v);
 
   /// return norm of a 2-vector
   inline Real norm2(const Real * v);
 
   /// return norm of a 3-vector
   inline Real norm3(const Real * v);
 
   /// return norm of a vector
   inline Real norm(UInt n, const Real * v);
 
   /// return the dot product between 2 vectors in 2d
   inline Real vectorDot2(const Real * v1, const Real * v2);
 
   /// return the dot product between 2 vectors in 3d
   inline Real vectorDot3(const Real * v1, const Real * v2);
 
   /// return the dot product between 2 vectors
   inline Real vectorDot(Real * v1, Real * v2, UInt n);
 
   /* ------------------------------------------------------------------------ */
   /* Geometry                                                                 */
   /* ------------------------------------------------------------------------ */
   /// compute normal a normal to a vector
   inline void normal2(const Real * vec, Real * normal);
 
   /// compute normal a normal to a vector
   inline void normal3(const Real * vec1, const Real * vec2, Real * normal);
 
   /// compute the tangents to an array of normal vectors
   void compute_tangents(const Array<Real> & normals, Array<Real> & tangents);
 
   /// distance in 2D between x and y
   inline Real distance_2d(const Real * x, const Real * y);
 
   /// distance in 3D between x and y
   inline Real distance_3d(const Real * x, const Real * y);
 
   /// radius of the in-circle of a triangle in 2d space
-  static inline Real triangle_inradius_2d(const Vector<Real> & coord1, const Vecotr<Real> & coord2,
-                                          const Vector<Real> & coord3);
+  static inline Real triangle_inradius(const Vector<Real> & coord1,
+                                       const Vector<Real> & coord2,
+                                       const Vector<Real> & coord3);
 
   /// radius of the in-circle of a tetrahedron
   inline Real tetrahedron_inradius(const Real * coord1, const Real * coord2,
                                    const Real * coord3, const Real * coord4);
 
   /// volume of a tetrahedron
   inline Real tetrahedron_volume(const Real * coord1, const Real * coord2,
                                  const Real * coord3, const Real * coord4);
 
   /// compute the barycenter of n points
   inline void barycenter(const Real * coord, UInt nb_points,
                          UInt spatial_dimension, Real * barycenter);
 
   /// vector between x and y
   inline void vector_2d(const Real * x, const Real * y, Real * res);
 
   /// vector pointing from x to y in 3 spatial dimension
   inline void vector_3d(const Real * x, const Real * y, Real * res);
 
   /// test if two scalar are equal within a given tolerance
   inline bool are_float_equal(Real x, Real y);
 
   /// test if two vectors are equal within a given tolerance
   inline bool are_vector_equal(UInt n, Real * x, Real * y);
 
 #ifdef isnan
 #error                                                                         \
     "You probably  included <math.h> which  is incompatible with aka_math  please use\
 <cmath> or add a \"#undef isnan\" before akantu includes"
 #endif
   /// test if a real is a NaN
   inline bool isnan(Real x);
 
   /// test if the line x and y intersects each other
   inline bool intersects(Real x_min, Real x_max, Real y_min, Real y_max);
 
   /// test if a is in the range [x_min, x_max]
   inline bool is_in_range(Real a, Real x_min, Real x_max);
 
   inline Real getTolerance() { return Math::tolerance; }
   inline void setTolerance(Real tol) { Math::tolerance = tol; }
 
   template <UInt p, typename T> inline T pow(T x);
 
   template <class T1, class T2,
             std::enable_if_t<std::is_integral<T1>::value and
                              std::is_integral<T2>::value> * = nullptr>
   inline Real kronecker(T1 i, T2 j) {
     return static_cast<Real>(i == j);
   }
 
   /// reduce all the values of an array, the summation is done in place and the
   /// array is modified
   Real reduce(Array<Real> & array);
 
   class NewtonRaphson {
   public:
     NewtonRaphson(Real tolerance, Real max_iteration)
         : tolerance(tolerance), max_iteration(max_iteration) {}
 
     template <class Functor> Real solve(const Functor & funct, Real x_0);
 
   private:
     Real tolerance;
     Real max_iteration;
   };
 
   struct NewtonRaphsonFunctor {
     explicit NewtonRaphsonFunctor(const std::string & name) : name(name) {}
 
     virtual ~NewtonRaphsonFunctor() = default;
 
     NewtonRaphsonFunctor(const NewtonRaphsonFunctor & other) = default;
     NewtonRaphsonFunctor(NewtonRaphsonFunctor && other) noexcept = default;
     NewtonRaphsonFunctor &
     operator=(const NewtonRaphsonFunctor & other) = default;
     NewtonRaphsonFunctor &
     operator=(NewtonRaphsonFunctor && other) noexcept = default;
 
     virtual Real f(Real x) const = 0;
     virtual Real f_prime(Real x) const = 0;
     std::string name;
   };
 } // namespace Math
 } // namespace akantu
 /* -------------------------------------------------------------------------- */
 /* inline functions                                                           */
 /* -------------------------------------------------------------------------- */
 #include "aka_math_tmpl.hh"
 
 #endif /* AKANTU_AKA_MATH_H_ */
diff --git a/src/common/aka_math_tmpl.hh b/src/common/aka_math_tmpl.hh
index 335b7228f..61a75f471 100644
--- a/src/common/aka_math_tmpl.hh
+++ b/src/common/aka_math_tmpl.hh
@@ -1,838 +1,839 @@
 /**
  * @file   aka_math_tmpl.hh
  *
  * @author Ramin Aghababaei <ramin.aghababaei@epfl.ch>
  * @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
  * @author Alejandro M. Aragón <alejandro.aragon@epfl.ch>
  * @author David Simon Kammer <david.kammer@epfl.ch>
  * @author Daniel Pino Muñoz <daniel.pinomunoz@epfl.ch>
  * @author Mathilde Radiguet <mathilde.radiguet@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  * @author Leonardo Snozzi <leonardo.snozzi@epfl.ch>
  * @author Peter Spijker <peter.spijker@epfl.ch>
  * @author Marco Vocialta <marco.vocialta@epfl.ch>
  *
  * @date creation: Wed Aug 04 2010
  * @date last modification: Tue Feb 20 2018
  *
  * @brief  Implementation of the inline functions of the math toolkit
  *
  *
  * 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 "aka_blas_lapack.hh"
 #include "aka_math.hh"
+#include "aka_types.hh"
 /* -------------------------------------------------------------------------- */
 #include <cmath>
 #include <typeinfo>
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 namespace Math {
   /* ------------------------------------------------------------------------ */
   inline void matrix_vector(UInt im, UInt in,
                             Real * A, // NOLINT(readability-non-const-parameter)
                             Real * x, // NOLINT(readability-non-const-parameter)
                             Real * y, Real alpha) {
 #ifdef AKANTU_USE_BLAS
     /// y = alpha*op(A)*x + beta*y
     char tran_A = 'N';
     int incx = 1;
     int incy = 1;
     double beta = 0.;
     int m = im;
     int n = in;
 
     aka_gemv(&tran_A, &m, &n, &alpha, A, &m, x, &incx, &beta, y, &incy);
 
 #else
     std::fill_n(y, im, 0.);
     for (UInt i = 0; i < im; ++i) {
       for (UInt j = 0; j < in; ++j) {
         y[i] += A[i + j * im] * x[j];
       }
       y[i] *= alpha;
     }
 #endif
   }
 
   /* ------------------------------------------------------------------------ */
   inline void
   matrixt_vector(UInt im, UInt in,
                  Real * A, // NOLINT(readability-non-const-parameter)
                  Real * x, // NOLINT(readability-non-const-parameter)
                  Real * y, Real alpha) {
 #ifdef AKANTU_USE_BLAS
     /// y = alpha*op(A)*x + beta*y
     char tran_A = 'T';
     int incx = 1;
     int incy = 1;
     double beta = 0.;
     int m = im;
     int n = in;
 
     aka_gemv(&tran_A, &m, &n, &alpha, A, &m, x, &incx, &beta, y, &incy);
 #else
     std::fill_n(y, in, 0.);
     for (UInt i = 0; i < im; ++i) {
       for (UInt j = 0; j < in; ++j) {
         y[j] += A[j * im + i] * x[i];
       }
       y[i] *= alpha;
     }
 #endif
   }
 
   /* ------------------------------------------------------------------------ */
   inline void matrix_matrix(UInt im, UInt in, UInt ik,
                             Real * A, // NOLINT(readability-non-const-parameter)
                             Real * B, // NOLINT(readability-non-const-parameter)
                             Real * C, Real alpha) {
 #ifdef AKANTU_USE_BLAS
     ///  C := alpha*op(A)*op(B) + beta*C
     char trans_a = 'N';
     char trans_b = 'N';
     double beta = 0.;
     int m = im, n = in, k = ik;
 
     aka_gemm(&trans_a, &trans_b, &m, &n, &k, &alpha, A, &m, B, &k, &beta, C,
              &m);
 #else
     std::fill_n(C, im * in, 0.);
     for (UInt j = 0; j < in; ++j) {
       UInt _jb = j * ik;
       UInt _jc = j * im;
       for (UInt i = 0; i < im; ++i) {
         for (UInt l = 0; l < ik; ++l) {
           UInt _la = l * im;
           C[i + _jc] += A[i + _la] * B[l + _jb];
         }
         C[i + _jc] *= alpha;
       }
     }
 #endif
   }
 
   /* ------------------------------------------------------------------------ */
   inline void
   matrixt_matrix(UInt im, UInt in, UInt ik,
                  Real * A, // NOLINT(readability-non-const-parameter)
                  Real * B, // NOLINT(readability-non-const-parameter)
                  Real * C, Real alpha) {
 #ifdef AKANTU_USE_BLAS
     ///  C := alpha*op(A)*op(B) + beta*C
     char trans_a = 'T';
     char trans_b = 'N';
     double beta = 0.;
     int m = im, n = in, k = ik;
 
     aka_gemm(&trans_a, &trans_b, &m, &n, &k, &alpha, A, &k, B, &k, &beta, C,
              &m);
 #else
     std::fill_n(C, im * in, 0.);
     for (UInt j = 0; j < in; ++j) {
       UInt _jc = j * im;
       UInt _jb = j * ik;
       for (UInt i = 0; i < im; ++i) {
         UInt _ia = i * ik;
         for (UInt l = 0; l < ik; ++l) {
           C[i + _jc] += A[l + _ia] * B[l + _jb];
         }
         C[i + _jc] *= alpha;
       }
     }
 #endif
   }
 
   /* ------------------------------------------------------------------------ */
   inline void
   matrix_matrixt(UInt im, UInt in, UInt ik,
                  Real * A, // NOLINT(readability-non-const-parameter)
                  Real * B, // NOLINT(readability-non-const-parameter)
                  Real * C, Real alpha) {
 #ifdef AKANTU_USE_BLAS
     ///  C := alpha*op(A)*op(B) + beta*C
     char trans_a = 'N';
     char trans_b = 'T';
     double beta = 0.;
     int m = im, n = in, k = ik;
 
     aka_gemm(&trans_a, &trans_b, &m, &n, &k, &alpha, A, &m, B, &n, &beta, C,
              &m);
 #else
     std::fill_n(C, im * in, 0.);
     for (UInt j = 0; j < in; ++j) {
       UInt _jc = j * im;
       for (UInt i = 0; i < im; ++i) {
         for (UInt l = 0; l < ik; ++l) {
           UInt _la = l * im;
           UInt _lb = l * in;
           C[i + _jc] += A[i + _la] * B[j + _lb];
         }
         C[i + _jc] *= alpha;
       }
     }
 #endif
   }
 
   /* ------------------------------------------------------------------------ */
   inline void
   matrixt_matrixt(UInt im, UInt in, UInt ik,
                   Real * A, // NOLINT(readability-non-const-parameter)
                   Real * B, // NOLINT(readability-non-const-parameter)
                   Real * C, Real alpha) {
 #ifdef AKANTU_USE_BLAS
     ///  C := alpha*op(A)*op(B) + beta*C
     char trans_a = 'T';
     char trans_b = 'T';
     double beta = 0.;
     int m = im, n = in, k = ik;
 
     aka_gemm(&trans_a, &trans_b, &m, &n, &k, &alpha, A, &k, B, &n, &beta, C,
              &m);
 #else
     std::fill_n(C, im * in, 0.);
     for (UInt j = 0; j < in; ++j) {
       UInt _jc = j * im;
       for (UInt i = 0; i < im; ++i) {
         UInt _ia = i * ik;
         for (UInt l = 0; l < ik; ++l) {
           UInt _lb = l * in;
           C[i + _jc] += A[l + _ia] * B[j + _lb];
         }
         C[i + _jc] *= alpha;
       }
     }
 #endif
   }
 
   /* ------------------------------------------------------------------------ */
   inline void aXplusY(UInt n, Real alpha,
                       Real * x, // NOLINT(readability-non-const-parameter)
                       Real * y) {
 #ifdef AKANTU_USE_BLAS
     ///  y := alpha x + y
     int incx = 1, incy = 1;
     aka_axpy(&n, &alpha, x, &incx, y, &incy);
 #else
     for (UInt i = 0; i < n; ++i) {
       *(y++) += alpha * *(x++);
     }
 #endif
   }
 
   /* ------------------------------------------------------------------------ */
   inline Real vectorDot(Real * v1, // NOLINT(readability-non-const-parameter)
                         Real * v2, // NOLINT(readability-non-const-parameter)
                         UInt in) {
 #ifdef AKANTU_USE_BLAS
     ///  d := v1 . v2
     int incx = 1, incy = 1, n = in;
     Real d = aka_dot(&n, v1, &incx, v2, &incy);
 #else
     Real d = 0;
     for (UInt i = 0; i < in; ++i) {
       d += v1[i] * v2[i];
     }
 #endif
     return d;
   }
 
   /* ------------------------------------------------------------------------ */
   template <bool tr_A, bool tr_B>
   inline void matMul(UInt m, UInt n, UInt k, Real alpha,
                      Real * A, // NOLINT(readability-non-const-parameter)
                      Real * B, // NOLINT(readability-non-const-parameter)
                      Real /*beta*/, Real * C) {
     if (tr_A) {
       if (tr_B) {
         matrixt_matrixt(m, n, k, A, B, C, alpha);
       } else {
         matrixt_matrix(m, n, k, A, B, C, alpha);
       }
     } else {
       if (tr_B) {
         matrix_matrixt(m, n, k, A, B, C, alpha);
       } else {
         matrix_matrix(m, n, k, A, B, C, alpha);
       }
     }
   }
 
   /* ------------------------------------------------------------------------ */
   template <bool tr_A>
   inline void matVectMul(UInt m, UInt n, Real alpha,
                          Real * A, // NOLINT(readability-non-const-parameter)
                          Real * x, // NOLINT(readability-non-const-parameter)
                          Real /*beta*/, Real * y) {
     if (tr_A) {
       matrixt_vector(m, n, A, x, y, alpha);
     } else {
       matrix_vector(m, n, A, x, y, alpha);
     }
   }
 
   /* ------------------------------------------------------------------------ */
   template <typename T>
   inline void matrixEig(UInt n,
                         T * A, // NOLINT(readability-non-const-parameter)
                         T * d, T * V) {
 
     // Matrix  A is  row major,  so the  lapack function  in fortran  will
     // process A^t. Asking for the left eigenvectors of A^t will give the
     // transposed right eigenvectors of A so in the C++ code the right
     // eigenvectors.
     char jobvr{'N'};
     if (V != nullptr) {
       jobvr = 'V'; // compute left  eigenvectors
     }
 
     char jobvl{'N'}; // compute right eigenvectors
 
     auto * di = new T[n]; // imaginary part of the eigenvalues
 
     int info;
     int N = n;
 
     T wkopt;
     int lwork = -1;
     // query and allocate the optimal workspace
     aka_geev<T>(&jobvl, &jobvr, &N, A, &N, d, di, nullptr, &N, V, &N, &wkopt,
                 &lwork, &info);
 
     lwork = int(wkopt);
     auto * work = new T[lwork];
     // solve the eigenproblem
     aka_geev<T>(&jobvl, &jobvr, &N, A, &N, d, di, nullptr, &N, V, &N, work,
                 &lwork, &info);
 
     AKANTU_DEBUG_ASSERT(
         info == 0,
         "Problem computing eigenvalues/vectors. DGEEV exited with the value "
             << info);
 
     delete[] work;
     delete[] di; // I hope for you that there was no complex eigenvalues !!!
   }
 
   /* ------------------------------------------------------------------------ */
   inline void
   matrix22_eigenvalues(Real * A, // NOLINT(readability-non-const-parameter)
                        Real * Adiag) {
     /// d = determinant of Matrix A
     Real d = det2(A);
     /// b = trace of Matrix A
     Real b = A[0] + A[3];
 
     Real c = std::sqrt(b * b - 4 * d);
     Adiag[0] = .5 * (b + c);
     Adiag[1] = .5 * (b - c);
   }
 
   /* ------------------------------------------------------------------------ */
   inline void
   matrix33_eigenvalues(Real * A, // NOLINT(readability-non-const-parameter)
                        Real * Adiag) {
     matrixEig(3, A, Adiag);
   }
 
   /* ------------------------------------------------------------------------ */
   template <UInt dim>
   inline void eigenvalues(Real * A, // NOLINT(readability-non-const-parameter)
                           Real * d) {
     if (dim == 1) {
       d[0] = A[0];
     } else if (dim == 2) {
       matrix22_eigenvalues(A, d);
     }
     // else if(dim == 3) { matrix33_eigenvalues(A, d); }
     else {
       matrixEig(dim, A, d);
     }
   }
 
   /* ------------------------------------------------------------------------ */
   inline Real det2(const Real * mat) {
     return mat[0] * mat[3] - mat[1] * mat[2];
   }
 
   /* ------------------------------------------------------------------------ */
   inline Real det3(const Real * mat) {
     return mat[0] * (mat[4] * mat[8] - mat[7] * mat[5]) -
            mat[3] * (mat[1] * mat[8] - mat[7] * mat[2]) +
            mat[6] * (mat[1] * mat[5] - mat[4] * mat[2]);
   }
 
   /* ------------------------------------------------------------------------ */
   template <UInt n> inline Real det(const Real * mat) {
     if (n == 1) {
       return *mat;
     }
     if (n == 2) {
       return det2(mat);
     }
     if (n == 3) {
       return det3(mat);
     }
     return det(n, mat);
   }
 
   /* ------------------------------------------------------------------------ */
   template <typename T> inline T det(UInt n, const T * A) {
     int N = n;
     int info;
     auto * ipiv = new int[N + 1];
 
     auto * LU = new T[N * N];
     std::copy(A, A + N * N, LU);
 
     // LU factorization of A
     aka_getrf(&N, &N, LU, &N, ipiv, &info);
     if (info > 0) {
       AKANTU_ERROR("Singular matrix - cannot factorize it (info: " << info
                                                                    << " )");
     }
 
     // det(A) = det(L) * det(U) = 1 * det(U) = product_i U_{ii}
     T det = 1.;
     for (int i = 0; i < N; ++i) {
       det *= (2 * (ipiv[i] == i) - 1) * LU[i * n + i];
     }
 
     delete[] ipiv;
     delete[] LU;
     return det;
   }
 
   /* ------------------------------------------------------------------------ */
   inline void normal2(const Real * vec, Real * normal) {
     normal[0] = vec[1];
     normal[1] = -vec[0];
     normalize2(normal);
   }
 
   /* ------------------------------------------------------------------------ */
   inline void normal3(const Real * vec1, const Real * vec2, Real * normal) {
     vectorProduct3(vec1, vec2, normal);
     normalize3(normal);
   }
 
   /* ------------------------------------------------------------------------ */
   inline void normalize2(Real * vec) {
     Real norm = norm2(vec);
     vec[0] /= norm;
     vec[1] /= norm;
   }
 
   /* ------------------------------------------------------------------------ */
   inline void normalize3(Real * vec) {
     Real norm = norm3(vec);
     vec[0] /= norm;
     vec[1] /= norm;
     vec[2] /= norm;
   }
 
   /* ------------------------------------------------------------------------ */
   inline Real norm2(const Real * vec) {
     return sqrt(vec[0] * vec[0] + vec[1] * vec[1]);
   }
 
   /* ------------------------------------------------------------------------ */
   inline Real norm3(const Real * vec) {
     return sqrt(vec[0] * vec[0] + vec[1] * vec[1] + vec[2] * vec[2]);
   }
 
   /* ------------------------------------------------------------------------ */
   inline Real norm(UInt n, const Real * vec) {
     Real norm = 0.;
     for (UInt i = 0; i < n; ++i) {
       norm += vec[i] * vec[i];
     }
     return sqrt(norm);
   }
 
   /* ------------------------------------------------------------------------ */
   inline void inv2(const Real * mat, Real * inv) {
     Real det_mat = det2(mat);
 
     inv[0] = mat[3] / det_mat;
     inv[1] = -mat[1] / det_mat;
     inv[2] = -mat[2] / det_mat;
     inv[3] = mat[0] / det_mat;
   }
 
   /* ------------------------------------------------------------------------ */
   inline void inv3(const Real * mat, Real * inv) {
     Real det_mat = det3(mat);
 
     inv[0] = (mat[4] * mat[8] - mat[7] * mat[5]) / det_mat;
     inv[1] = (mat[2] * mat[7] - mat[8] * mat[1]) / det_mat;
     inv[2] = (mat[1] * mat[5] - mat[4] * mat[2]) / det_mat;
     inv[3] = (mat[5] * mat[6] - mat[8] * mat[3]) / det_mat;
     inv[4] = (mat[0] * mat[8] - mat[6] * mat[2]) / det_mat;
     inv[5] = (mat[2] * mat[3] - mat[5] * mat[0]) / det_mat;
     inv[6] = (mat[3] * mat[7] - mat[6] * mat[4]) / det_mat;
     inv[7] = (mat[1] * mat[6] - mat[7] * mat[0]) / det_mat;
     inv[8] = (mat[0] * mat[4] - mat[3] * mat[1]) / det_mat;
   }
 
   /* ------------------------------------------------------------------------ */
   template <UInt n> inline void inv(const Real * A, Real * Ainv) {
     if (n == 1) {
       *Ainv = 1. / *A;
     } else if (n == 2) {
       inv2(A, Ainv);
     } else if (n == 3) {
       inv3(A, Ainv);
     } else {
       inv(n, A, Ainv);
     }
   }
 
   /* ------------------------------------------------------------------------ */
   template <typename T> inline void inv(UInt n, const T * A, T * invA) {
     int N = n;
     int info;
     auto * ipiv = new int[N + 1];
     int lwork = N * N;
     auto * work = new T[lwork];
 
     std::copy(A, A + n * n, invA);
 
     aka_getrf(&N, &N, invA, &N, ipiv, &info);
     if (info > 0) {
       AKANTU_ERROR("Singular matrix - cannot factorize it (info: " << info
                                                                    << " )");
     }
 
     aka_getri(&N, invA, &N, ipiv, work, &lwork, &info);
     if (info != 0) {
       AKANTU_ERROR("Cannot invert the matrix (info: " << info << " )");
     }
 
     delete[] ipiv;
     delete[] work;
   }
 
   /* ------------------------------------------------------------------------ */
   template <typename T>
   inline void solve(UInt n, const T * A, T * x, const T * b) {
     int N = n;
     int info;
     auto * ipiv = new int[N];
     auto * lu_A = new T[N * N];
 
     std::copy(A, A + N * N, lu_A);
 
     aka_getrf(&N, &N, lu_A, &N, ipiv, &info);
     if (info > 0) {
       AKANTU_ERROR("Singular matrix - cannot factorize it (info: " << info
                                                                    << " )");
     }
 
     char trans = 'N';
     int nrhs = 1;
 
     std::copy(b, b + N, x);
 
     aka_getrs(&trans, &N, &nrhs, lu_A, &N, ipiv, x, &N, &info);
     if (info != 0) {
       AKANTU_ERROR("Cannot solve the system (info: " << info << " )");
     }
 
     delete[] ipiv;
     delete[] lu_A;
   }
 
   /* ------------------------------------------------------------------------ */
   /* ------------------------------------------------------------------------ */
   inline Real
   matrixDoubleDot22(Real * A, // NOLINT(readability-non-const-parameter)
                     Real * B  // NOLINT(readability-non-const-parameter)
   ) {
     Real d;
     d = A[0] * B[0] + A[1] * B[1] + A[2] * B[2] + A[3] * B[3];
     return d;
   }
 
   /* ------------------------------------------------------------------------ */
   inline Real
   matrixDoubleDot33(Real * A, // NOLINT(readability-non-const-parameter)
                     Real * B  // NOLINT(readability-non-const-parameter)
   ) {
     Real d;
     d = A[0] * B[0] + A[1] * B[1] + A[2] * B[2] + A[3] * B[3] + A[4] * B[4] +
         A[5] * B[5] + A[6] * B[6] + A[7] * B[7] + A[8] * B[8];
     return d;
   }
 
   /* ------------------------------------------------------------------------ */
   inline Real
   matrixDoubleDot(UInt n,
                   Real * A, // NOLINT(readability-non-const-parameter)
                   Real * B  // NOLINT(readability-non-const-parameter)
   ) {
     Real d = 0.;
     for (UInt i = 0; i < n; ++i) {
       for (UInt j = 0; j < n; ++j) {
         d += A[i * n + j] * B[i * n + j];
       }
     }
     return d;
   }
 
   /* ------------------------------------------------------------------------ */
   inline void vectorProduct3(const Real * v1, const Real * v2, Real * res) {
     res[0] = v1[1] * v2[2] - v1[2] * v2[1];
     res[1] = v1[2] * v2[0] - v1[0] * v2[2];
     res[2] = v1[0] * v2[1] - v1[1] * v2[0];
   }
 
   /* ------------------------------------------------------------------------ */
   inline Real vectorDot2(const Real * v1, const Real * v2) {
     return (v1[0] * v2[0] + v1[1] * v2[1]);
   }
 
   /* ------------------------------------------------------------------------ */
   inline Real vectorDot3(const Real * v1, const Real * v2) {
     return (v1[0] * v2[0] + v1[1] * v2[1] + v1[2] * v2[2]);
   }
 
   /* ------------------------------------------------------------------------ */
   inline Real distance_2d(const Real * x, const Real * y) {
     return std::sqrt((y[0] - x[0]) * (y[0] - x[0]) +
                      (y[1] - x[1]) * (y[1] - x[1]));
   }
 
   /* ------------------------------------------------------------------------ */
   inline Real triangle_inradius(const Vector<Real> & coord1, const Vector<Real> & coord2,
                                 const Vector<Real> & coord3) {
     /**
      * @f{eqnarray*}{
      * r &=& A / s \\
      * A &=& 1/4 * \sqrt{(a + b + c) * (a - b + c) * (a + b - c) (-a + b + c)}
      * \\ s &=& \frac{a + b + c}{2}
      * @f}
      */
 
     Real a, b, c;
 
     a = coord1.distance(coord2);
     b = coord2.distance(coord3);
     c = coord1.distance(coord3);
 
     Real s;
     s = (a + b + c) * 0.5;
 
     return std::sqrt((s - a) * (s - b) * (s - c) / s);
   }
 
 
   /* ------------------------------------------------------------------------ */
   inline Real distance_3d(const Real * x, const Real * y) {
     return std::sqrt((y[0] - x[0]) * (y[0] - x[0]) +
                      (y[1] - x[1]) * (y[1] - x[1]) +
                      (y[2] - x[2]) * (y[2] - x[2]));
   }
 
   /* ------------------------------------------------------------------------ */
   inline Real tetrahedron_volume(const Real * coord1, const Real * coord2,
                                  const Real * coord3, const Real * coord4) {
     Real xx[9];
 
     xx[0] = coord2[0];
     xx[1] = coord2[1];
     xx[2] = coord2[2];
     xx[3] = coord3[0];
     xx[4] = coord3[1];
     xx[5] = coord3[2];
     xx[6] = coord4[0];
     xx[7] = coord4[1];
     xx[8] = coord4[2];
     auto vol = det3(xx);
 
     xx[0] = coord1[0];
     xx[1] = coord1[1];
     xx[2] = coord1[2];
     xx[3] = coord3[0];
     xx[4] = coord3[1];
     xx[5] = coord3[2];
     xx[6] = coord4[0];
     xx[7] = coord4[1];
     xx[8] = coord4[2];
     vol -= det3(xx);
 
     xx[0] = coord1[0];
     xx[1] = coord1[1];
     xx[2] = coord1[2];
     xx[3] = coord2[0];
     xx[4] = coord2[1];
     xx[5] = coord2[2];
     xx[6] = coord4[0];
     xx[7] = coord4[1];
     xx[8] = coord4[2];
     vol += det3(xx);
 
     xx[0] = coord1[0];
     xx[1] = coord1[1];
     xx[2] = coord1[2];
     xx[3] = coord2[0];
     xx[4] = coord2[1];
     xx[5] = coord2[2];
     xx[6] = coord3[0];
     xx[7] = coord3[1];
     xx[8] = coord3[2];
     vol -= det3(xx);
 
     vol /= 6;
 
     return vol;
   }
 
   /* ------------------------------------------------------------------------ */
   inline Real tetrahedron_inradius(const Real * coord1, const Real * coord2,
                                    const Real * coord3, const Real * coord4) {
     auto l12 = distance_3d(coord1, coord2);
     auto l13 = distance_3d(coord1, coord3);
     auto l14 = distance_3d(coord1, coord4);
     auto l23 = distance_3d(coord2, coord3);
     auto l24 = distance_3d(coord2, coord4);
     auto l34 = distance_3d(coord3, coord4);
 
     auto s1 = (l12 + l23 + l13) * 0.5;
     s1 = std::sqrt(s1 * (s1 - l12) * (s1 - l23) * (s1 - l13));
 
     auto s2 = (l12 + l24 + l14) * 0.5;
     s2 = std::sqrt(s2 * (s2 - l12) * (s2 - l24) * (s2 - l14));
 
     auto s3 = (l23 + l34 + l24) * 0.5;
     s3 = std::sqrt(s3 * (s3 - l23) * (s3 - l34) * (s3 - l24));
 
     auto s4 = (l13 + l34 + l14) * 0.5;
     s4 = std::sqrt(s4 * (s4 - l13) * (s4 - l34) * (s4 - l14));
 
     auto volume = tetrahedron_volume(coord1, coord2, coord3, coord4);
 
     return 3 * volume / (s1 + s2 + s3 + s4);
   }
 
   /* ------------------------------------------------------------------------ */
   inline void barycenter(const Real * coord, UInt nb_points,
                          UInt spatial_dimension, Real * barycenter) {
     std::fill_n(barycenter, spatial_dimension, 0.);
     for (UInt n = 0; n < nb_points; ++n) {
       UInt offset = n * spatial_dimension;
       for (UInt i = 0; i < spatial_dimension; ++i) {
         barycenter[i] += coord[offset + i] / (Real)nb_points;
       }
     }
   }
 
   /* ------------------------------------------------------------------------ */
   inline void vector_2d(const Real * x, const Real * y, Real * res) {
     res[0] = y[0] - x[0];
     res[1] = y[1] - x[1];
   }
 
   /* ------------------------------------------------------------------------ */
   inline void vector_3d(const Real * x, const Real * y, Real * res) {
     res[0] = y[0] - x[0];
     res[1] = y[1] - x[1];
     res[2] = y[2] - x[2];
   }
 
   /* ------------------------------------------------------------------------ */
   /// Combined absolute and relative tolerance test proposed in
   /// Real-time collision detection by C. Ericson (2004)
   inline bool are_float_equal(const Real x, const Real y) {
     Real abs_max = std::max(std::abs(x), std::abs(y));
     abs_max = std::max(abs_max, Real(1.));
     return std::abs(x - y) <= (tolerance * abs_max);
   }
 
   /* ------------------------------------------------------------------------ */
   inline bool isnan(Real x) {
 #if defined(__INTEL_COMPILER)
 #pragma warning(push)
 #pragma warning(disable : 1572)
 #endif // defined(__INTEL_COMPILER)
 
     // x = x return false means x = quiet_NaN
     return !(x == x);
 
 #if defined(__INTEL_COMPILER)
 #pragma warning(pop)
 #endif // defined(__INTEL_COMPILER)
   }
 
   /* ------------------------------------------------------------------------ */
   inline bool are_vector_equal(UInt n, Real * x, Real * y) {
     bool test = true;
     for (UInt i = 0; i < n; ++i) {
       test &= are_float_equal(x[i], y[i]);
     }
 
     return test;
   }
 
   /* ------------------------------------------------------------------------ */
   inline bool intersects(Real x_min, Real x_max, Real y_min, Real y_max) {
     return not((x_max < y_min) or (x_min > y_max));
   }
 
   /* ------------------------------------------------------------------------ */
   inline bool is_in_range(Real a, Real x_min, Real x_max) {
     return ((a >= x_min) and (a <= x_max));
   }
 
   /* ------------------------------------------------------------------------ */
   template <UInt p, typename T> inline T pow(T x) {
     return (pow<p - 1, T>(x) * x);
   }
   template <> inline UInt pow<0, UInt>(__attribute__((unused)) UInt x) {
     return (1);
   }
   template <> inline Real pow<0, Real>(__attribute__((unused)) Real x) {
     return (1.);
   }
 
   /* ------------------------------------------------------------------------ */
 
   template <class Functor>
   Real NewtonRaphson::solve(const Functor & funct, Real x_0) {
     Real x = x_0;
     Real f_x = funct.f(x);
     UInt iter = 0;
     while (std::abs(f_x) > this->tolerance && iter < this->max_iteration) {
       x -= f_x / funct.f_prime(x);
       f_x = funct.f(x);
       iter++;
     }
 
     AKANTU_DEBUG_ASSERT(iter < this->max_iteration,
                         "Newton Raphson ("
                             << funct.name << ") solve did not converge in "
                             << this->max_iteration << " iterations (tolerance: "
                             << this->tolerance << ")");
 
     return x;
   }
 
 } // namespace Math
 } // namespace akantu
diff --git a/src/fe_engine/element_classes/element_class_segment_2_inline_impl.hh b/src/fe_engine/element_classes/element_class_segment_2_inline_impl.hh
index eef8044ca..327c12940 100644
--- a/src/fe_engine/element_classes/element_class_segment_2_inline_impl.hh
+++ b/src/fe_engine/element_classes/element_class_segment_2_inline_impl.hh
@@ -1,116 +1,116 @@
 /**
  * @file   element_class_segment_2_inline_impl.hh
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Fri Jul 16 2010
  * @date last modification: Wed Oct 11 2017
  *
  * @brief  Specialization of the element_class class for the type _segment_2
  *
  *
  * 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/>.
  *
  *
  * @verbatim
               q
    --x--------|--------x---> x
     -1        0        1
  @endverbatim
  *
  * @f{eqnarray*}{
  * w_1(x) &=& 1/2(1 - x) \\
  * w_2(x) &=& 1/2(1 + x)
  * @f}
  *
  * @f{eqnarray*}{
  * x_{q}  &=& 0
  * @f}
  */
 /* -------------------------------------------------------------------------- */
 #include "element_class.hh"
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 /* -------------------------------------------------------------------------- */
 AKANTU_DEFINE_ELEMENT_CLASS_PROPERTY(_segment_2, _gt_segment_2,
                                      _itp_lagrange_segment_2, _ek_regular, 1,
                                      _git_segment, 1);
 
 /* -------------------------------------------------------------------------- */
 template <>
 template <class vector_type>
 inline void InterpolationElement<_itp_lagrange_segment_2>::computeShapes(
     const vector_type & natural_coords, vector_type & N) {
 
   /// natural coordinate
   Real c = natural_coords(0);
   /// shape functions
   N(0) = 0.5 * (1 - c);
   N(1) = 0.5 * (1 + c);
 }
 /* -------------------------------------------------------------------------- */
 
 template <>
 template <class vector_type, class matrix_type>
 inline void InterpolationElement<_itp_lagrange_segment_2>::computeDNDS(
     __attribute__((unused)) const vector_type & natural_coords,
     matrix_type & dnds) {
 
   /// dN1/de
   dnds(0, 0) = -.5;
   /// dN2/de
   dnds(0, 1) = .5;
 }
 
 
 /* -------------------------------------------------------------------------- */
 template<>
 template <class vector_type, class matrix_type>
 inline void InterpolationElement<_itp_lagrange_segment_2>::computeD2NDS2(
     const vector_type & /*natural_coords*/, matrix_type & d2nds2) {
   d2nds2.zero();
 }
 
 /* -------------------------------------------------------------------------- */
 template <>
 inline void
 InterpolationElement<_itp_lagrange_segment_2>::computeSpecialJacobian(
     const Matrix<Real> & dxds, Real & jac) {
   jac = dxds.norm<L_2>();
 }
 
 /* -------------------------------------------------------------------------- */
 template <>
 inline Real
 GeometricalElement<_gt_segment_2>::getInradius(const Matrix<Real> & coord) {
-Vector<Real> a(coord(0))
-Vector<Real> b(coord(1))
-return a.distance(b);
+  Vector<Real> a(coord(0));
+  Vector<Real> b(coord(1));
+  return a.distance(b);
 }
 
 // /* --------------------------------------------------------------------------
 // */
 // template<> inline bool ElementClass<_segment_2>::contains(const Vector<Real>
 // & natural_coords) {
 //   if (natural_coords(0) < -1.) return false;
 //   if (natural_coords(0) > 1.) return false;
 //   return true;
 // }
 
 /* -------------------------------------------------------------------------- */
 } // namespace akantu
diff --git a/src/io/dumper/dumper_compute.hh b/src/io/dumper/dumper_compute.hh
index e84b97bb5..e43209183 100644
--- a/src/io/dumper/dumper_compute.hh
+++ b/src/io/dumper/dumper_compute.hh
@@ -1,287 +1,393 @@
 /**
  * @file   dumper_compute.hh
  *
  * @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
  *
  * @date creation: Tue Sep 02 2014
  * @date last modification: Sun Dec 03 2017
  *
  * @brief  Field that map a function to another field
  *
  *
  * 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/>.
  *
  */
 
 #ifndef AKANTU_DUMPER_COMPUTE_HH_
 #define AKANTU_DUMPER_COMPUTE_HH_
 /* -------------------------------------------------------------------------- */
 #include "aka_common.hh"
 #include "dumper_field.hh"
 #include "dumper_iohelper.hh"
 #include "dumper_type_traits.hh"
+/* -------------------------------------------------------------------------- */
+#include <aka_iterators.hh>
+/* -------------------------------------------------------------------------- */
 #include <io_helper.hh>
-
+/* -------------------------------------------------------------------------- */
+#include <type_traits>
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 namespace dumpers {
-
+  /* ------------------------------------------------------------------------ */
   class ComputeFunctorInterface {
   public:
     virtual ~ComputeFunctorInterface() = default;
 
     virtual UInt getDim() = 0;
     virtual UInt getNbComponent(UInt old_nb_comp) = 0;
   };
 
-  /* --------------------------------------------------------------------------
-   */
+  /* ------------------------------------------------------------------------ */
 
   template <typename return_type>
   class ComputeFunctorOutput : public ComputeFunctorInterface {
   public:
     ComputeFunctorOutput() = default;
     ~ComputeFunctorOutput() override = default;
   };
 
-  /* --------------------------------------------------------------------------
-   */
+  /* ------------------------------------------------------------------------ */
   template <typename input_type, typename return_type>
   class ComputeFunctor : public ComputeFunctorOutput<return_type> {
   public:
     ComputeFunctor() = default;
     ~ComputeFunctor() override = default;
 
-    virtual return_type func(const input_type & d, Element global_index) = 0;
+    virtual return_type func(const input_type & /*d*/, Element /*global_index*/) {
+      AKANTU_TO_IMPLEMENT();
+    }
+    virtual return_type func(const input_type & /*d*/) { AKANTU_TO_IMPLEMENT(); }
   };
 
-  /* --------------------------------------------------------------------------
-   */
-  template <typename SubFieldCompute, typename _return_type>
+  /* ------------------------------------------------------------------------ */
+  template <class EnumType>
+  class ComputeUIntFromEnum
+      : public ComputeFunctor<Vector<EnumType>, Vector<UInt>> {
+  public:
+    ComputeUIntFromEnum() = default;
+
+    inline Vector<UInt> func(const Vector<EnumType> & in) override {
+      Vector<UInt> out(in.size());
+      for (auto && data : zip(in, out)) {
+        std::get<1>(data) =
+            static_cast<std::underlying_type_t<EnumType>>(std::get<0>(data));
+      }
+
+      return out;
+    }
+
+    UInt getDim() override { return 1; };
+    UInt getNbComponent(UInt old_nb_comp) override { return old_nb_comp; };
+  };
+
+  /* ------------------------------------------------------------------------ */
+  template <typename SubFieldCompute, typename _return_type,
+            class support_type_ = typename SubFieldCompute::support_type>
   class FieldCompute : public Field {
-    /* ------------------------------------------------------------------------
-     */
-    /* Typedefs */
-    /* ------------------------------------------------------------------------
-     */
+    /* ---------------------------------------------------------------------- */
+    /* Typedefs                                                               */
+    /* ---------------------------------------------------------------------- */
   public:
+    using return_type = _return_type;
+    using support_type = support_type_;
+
+  private:
     using sub_iterator = typename SubFieldCompute::iterator;
     using sub_types = typename SubFieldCompute::types;
     using sub_return_type = typename sub_types::return_type;
+    using data_type = typename sub_types::data_type;
+    using functor_type = ComputeFunctor<sub_return_type, return_type>;
+
+  public:
+    class iterator {
+    public:
+      iterator(const sub_iterator & it, functor_type & func)
+          : it(it), func(func) {}
+
+      bool operator!=(const iterator & it) const { return it.it != this->it; }
+
+      iterator operator++() {
+        ++this->it;
+        return *this;
+      }
+
+      return_type operator*() { return func.func(*it); }
+
+    protected:
+      sub_iterator it;
+      functor_type & func;
+    };
+
+    /* ---------------------------------------------------------------------- */
+    /* Constructors/Destructors                                               */
+    /* ---------------------------------------------------------------------- */
+  public:
+    FieldCompute(SubFieldCompute & cont,
+                 std::unique_ptr<ComputeFunctorInterface> func)
+        : sub_field(aka::as_type<SubFieldCompute>(cont.shared_from_this())),
+          func(aka::as_type<functor_type>(func.release())) {
+      this->checkHomogeneity();
+    };
+
+    void registerToDumper(const std::string & id,
+                          iohelper::Dumper & dumper) override {
+      dumper.addNodeDataField(id, *this);
+    }
+
+    /* ---------------------------------------------------------------------- */
+    /* Class Members                                                          */
+    /* ---------------------------------------------------------------------- */
+  public:
+    iterator begin() { return iterator(sub_field->begin(), *func); }
+    iterator end() { return iterator(sub_field->end(), *func); }
+
+    UInt getDim() { return func->getDim(); }
+
+    UInt size() {
+      throw;
+      // return Functor::size();
+      return 0;
+    }
+
+    void checkHomogeneity() override { this->homogeneous = true; };
+
+    iohelper::DataType getDataType() {
+      return iohelper::getDataType<data_type>();
+    }
+
+    /// for connection to a FieldCompute
+    inline std::shared_ptr<Field> connect(FieldComputeProxy & proxy) override;
+
+    /// for connection to a FieldCompute
+    std::unique_ptr<ComputeFunctorInterface>
+    connect(HomogenizerProxy & proxy) override;
+
+    /* ---------------------------------------------------------------------- */
+    /* Class Members                                                          */
+    /* ---------------------------------------------------------------------- */
+  public:
+    std::shared_ptr<SubFieldCompute> sub_field;
+    std::unique_ptr<functor_type> func;
+  };
+
+  /* ------------------------------------------------------------------------ */
+  template <typename SubFieldCompute, typename _return_type>
+  class FieldCompute<SubFieldCompute, _return_type, Element> : public Field {
+    /* ---------------------------------------------------------------------- */
+    /* Typedefs                                                               */
+    /* ---------------------------------------------------------------------- */
+  public:
     using return_type = _return_type;
+    using support_type = Element;
+
+    using sub_iterator = typename SubFieldCompute::iterator;
+    using sub_types = typename SubFieldCompute::types;
+    using sub_return_type = typename sub_types::return_type;
     using data_type = typename sub_types::data_type;
+    using functor_type = ComputeFunctor<sub_return_type, return_type>;
 
     using types =
         TypeTraits<data_type, return_type, ElementTypeMapArray<data_type>>;
 
+  public:
     class iterator {
     public:
-      iterator(const sub_iterator & it,
-               ComputeFunctor<sub_return_type, return_type> & func)
+      iterator(const sub_iterator & it, functor_type & func)
           : it(it), func(func) {}
 
       bool operator!=(const iterator & it) const { return it.it != this->it; }
       iterator operator++() {
         ++this->it;
         return *this;
       }
 
       UInt currentGlobalIndex() { return this->it.currentGlobalIndex(); }
 
       return_type operator*() { return func.func(*it, it.getCurrentElement()); }
 
       Element getCurrentElement() { return this->it.getCurrentElement(); }
 
       UInt element_type() { return this->it.element_type(); }
 
     protected:
       sub_iterator it;
-      ComputeFunctor<sub_return_type, return_type> & func;
+      functor_type & func;
     };
 
-    /* ------------------------------------------------------------------------
-     */
-    /* Constructors/Destructors */
-    /* ------------------------------------------------------------------------
-     */
+    /* ---------------------------------------------------------------------- */
+    /* Constructors/Destructors                                               */
+    /* ---------------------------------------------------------------------- */
   public:
     FieldCompute(SubFieldCompute & cont,
                  std::unique_ptr<ComputeFunctorInterface> func)
         : sub_field(aka::as_type<SubFieldCompute>(cont.shared_from_this())),
-          func(aka::as_type<ComputeFunctor<sub_return_type, return_type>>(
-              func.release())) {
+          func(aka::as_type<functor_type>(func.release())) {
       this->checkHomogeneity();
     };
 
     ~FieldCompute() override = default;
 
     void registerToDumper(const std::string & id,
                           iohelper::Dumper & dumper) override {
       dumper.addElemDataField(id, *this);
     }
 
-    /* ------------------------------------------------------------------------
-     */
-    /* Class Members */
-    /* ------------------------------------------------------------------------
-     */
+    /* ---------------------------------------------------------------------- */
+    /* Class Members                                                          */
+    /* ---------------------------------------------------------------------- */
   public:
     iterator begin() { return iterator(sub_field->begin(), *func); }
     iterator end() { return iterator(sub_field->end(), *func); }
 
     UInt getDim() { return func->getDim(); }
 
     UInt size() {
       throw;
       // return Functor::size();
       return 0;
     }
 
     void checkHomogeneity() override { this->homogeneous = true; };
 
     iohelper::DataType getDataType() {
       return iohelper::getDataType<data_type>();
     }
 
     /// get the number of components of the hosted field
     ElementTypeMap<UInt>
     getNbComponents(UInt dim = _all_dimensions,
                     GhostType ghost_type = _not_ghost,
                     ElementKind kind = _ek_not_defined) override {
       ElementTypeMap<UInt> nb_components;
       const auto & old_nb_components =
           this->sub_field->getNbComponents(dim, ghost_type, kind);
 
       for (auto type : old_nb_components.elementTypes(dim, ghost_type, kind)) {
         UInt nb_comp = old_nb_components(type, ghost_type);
         nb_components(type, ghost_type) = func->getNbComponent(nb_comp);
       }
       return nb_components;
     };
 
     /// for connection to a FieldCompute
     inline std::shared_ptr<Field> connect(FieldComputeProxy & proxy) override;
 
     /// for connection to a FieldCompute
     std::unique_ptr<ComputeFunctorInterface>
     connect(HomogenizerProxy & proxy) override;
 
-    /* ------------------------------------------------------------------------
-     */
-    /* Class Members */
-    /* ------------------------------------------------------------------------
-     */
+    /* ---------------------------------------------------------------------- */
+    /* Class Members                                                          */
+    /* ---------------------------------------------------------------------- */
   public:
     std::shared_ptr<SubFieldCompute> sub_field;
-    std::unique_ptr<ComputeFunctor<sub_return_type, return_type>> func;
+    std::unique_ptr<functor_type> func;
   };
 
-  /* --------------------------------------------------------------------------
-   */
-
-  /* --------------------------------------------------------------------------
-   */
-
+  /* ------------------------------------------------------------------------ */
   class FieldComputeProxy {
-    /* ------------------------------------------------------------------------
-     */
-    /* Constructors/Destructors */
-    /* ------------------------------------------------------------------------
-     */
+    /* ---------------------------------------------------------------------- */
+    /* Constructors/Destructors                                               */
+    /* ---------------------------------------------------------------------- */
   public:
     FieldComputeProxy(std::unique_ptr<ComputeFunctorInterface> func)
         : func(std::move(func)){};
 
     inline static std::shared_ptr<Field>
     createFieldCompute(std::shared_ptr<Field> & field,
                        std::unique_ptr<ComputeFunctorInterface> func) {
       FieldComputeProxy compute_proxy(std::move(func));
       return field->connect(compute_proxy);
     }
 
     template <typename T> std::shared_ptr<Field> connectToField(T * ptr) {
       if (aka::is_of_type<ComputeFunctorOutput<Vector<Real>>>(func)) {
         return this->connectToFunctor<Vector<Real>>(ptr);
       }
 
       if (aka::is_of_type<ComputeFunctorOutput<Vector<UInt>>>(func)) {
         return this->connectToFunctor<Vector<UInt>>(ptr);
       }
 
       if (aka::is_of_type<ComputeFunctorOutput<Matrix<UInt>>>(func)) {
         return this->connectToFunctor<Matrix<UInt>>(ptr);
       }
 
       if (aka::is_of_type<ComputeFunctorOutput<Matrix<Real>>>(func)) {
         return this->connectToFunctor<Matrix<Real>>(ptr);
       }
       throw;
     }
 
     template <typename output, typename T>
     std::shared_ptr<Field> connectToFunctor(T * ptr) {
       return std::make_shared<FieldCompute<T, output>>(*ptr, std::move(func));
     }
 
     template <typename output, typename SubFieldCompute, typename return_type1,
               typename return_type2>
     std::shared_ptr<Field>
     connectToFunctor(FieldCompute<FieldCompute<SubFieldCompute, return_type1>,
                                   return_type2> * /*ptr*/) {
       throw; //    return new FieldCompute<T,output>(*ptr,func);
       return nullptr;
     }
 
     template <typename output, typename SubFieldCompute, typename return_type1,
               typename return_type2, typename return_type3,
               typename return_type4>
     std::shared_ptr<Field> connectToFunctor(
         FieldCompute<FieldCompute<FieldCompute<FieldCompute<SubFieldCompute,
                                                             return_type1>,
                                                return_type2>,
                                   return_type3>,
                      return_type4> * /*ptr*/) {
       throw; //    return new FieldCompute<T,output>(*ptr,func);
       return nullptr;
     }
 
-    /* ------------------------------------------------------------------------
-     */
-    /* Class Members */
-    /* ------------------------------------------------------------------------
-     */
+    /* ---------------------------------------------------------------------- */
+    /* Class Members                                                          */
+    /* ---------------------------------------------------------------------- */
   public:
     std::unique_ptr<ComputeFunctorInterface> func;
   };
 
-  /* --------------------------------------------------------------------------
-   */
+  /* ------------------------------------------------------------------------ */
   /// for connection to a FieldCompute
+  template <typename SubFieldCompute, typename return_type,
+            typename support_type_>
+  inline std::shared_ptr<Field>
+  FieldCompute<SubFieldCompute, return_type, support_type_>::connect(
+      FieldComputeProxy & proxy) {
+    return proxy.connectToField(this);
+  }
+
   template <typename SubFieldCompute, typename return_type>
   inline std::shared_ptr<Field>
-  FieldCompute<SubFieldCompute, return_type>::connect(
+  FieldCompute<SubFieldCompute, return_type, Element>::connect(
       FieldComputeProxy & proxy) {
     return proxy.connectToField(this);
   }
 
-  /* --------------------------------------------------------------------------
-   */
+  /* ------------------------------------------------------------------------ */
 } // namespace dumpers
 } // namespace akantu
 
 #endif /* AKANTU_DUMPER_COMPUTE_HH_ */
diff --git a/src/io/dumper/dumper_elemental_field.hh b/src/io/dumper/dumper_elemental_field.hh
index 409bad555..7a8e739c4 100644
--- a/src/io/dumper/dumper_elemental_field.hh
+++ b/src/io/dumper/dumper_elemental_field.hh
@@ -1,75 +1,75 @@
 /**
  * @file   dumper_elemental_field.hh
  *
  * @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Fri Jun 18 2010
  * @date last modification: Sun Dec 03 2017
  *
  * @brief  description of elemental fields
  *
  *
  * 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/>.
  *
  */
 
 #ifndef AKANTU_DUMPER_ELEMENTAL_FIELD_HH_
 #define AKANTU_DUMPER_ELEMENTAL_FIELD_HH_
 /* -------------------------------------------------------------------------- */
 #include "communicator.hh"
 #include "dumper_field.hh"
 #include "dumper_generic_elemental_field.hh"
 #ifdef AKANTU_IGFEM
 #include "dumper_igfem_elemental_field.hh"
 #endif
 /* -------------------------------------------------------------------------- */
 namespace akantu {
 namespace dumpers {
 /* -------------------------------------------------------------------------- */
 
 template <typename T, template <class> class ret = Vector,
           bool filtered = false>
 class ElementalField
     : public GenericElementalField<SingleType<T, ret, filtered>,
                                    elemental_field_iterator> {
   /* ------------------------------------------------------------------------ */
   /* Typedefs                                                                 */
   /* ------------------------------------------------------------------------ */
 public:
   using types = SingleType<T, ret, filtered>;
   using field_type = typename types::field_type;
   using iterator = elemental_field_iterator<types>;
-
+  using support_type = Element;
   /* ------------------------------------------------------------------------ */
   /* Constructors/Destructors                                                 */
   /* ------------------------------------------------------------------------ */
 public:
   ElementalField(const field_type & field,
                  UInt spatial_dimension = _all_dimensions,
                  GhostType ghost_type = _not_ghost,
                  ElementKind element_kind = _ek_not_defined)
       : GenericElementalField<types, elemental_field_iterator>(
             field, spatial_dimension, ghost_type, element_kind) {}
 };
 
 /* -------------------------------------------------------------------------- */
 
 } // namespace dumpers
 } // namespace akantu
 
 #endif /* AKANTU_DUMPER_ELEMENTAL_FIELD_HH_ */
diff --git a/src/io/dumper/dumper_generic_elemental_field.hh b/src/io/dumper/dumper_generic_elemental_field.hh
index 26fbf377e..7a2a2ffa3 100644
--- a/src/io/dumper/dumper_generic_elemental_field.hh
+++ b/src/io/dumper/dumper_generic_elemental_field.hh
@@ -1,220 +1,221 @@
 /**
  * @file   dumper_generic_elemental_field.hh
  *
  * @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Tue Sep 02 2014
  * @date last modification: Wed Nov 08 2017
  *
  * @brief  Generic interface for elemental fields
  *
  *
  * 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/>.
  *
  */
 
 #ifndef AKANTU_DUMPER_GENERIC_ELEMENTAL_FIELD_HH_
 #define AKANTU_DUMPER_GENERIC_ELEMENTAL_FIELD_HH_
 /* -------------------------------------------------------------------------- */
 #include "dumper_element_iterator.hh"
 #include "dumper_field.hh"
 #include "dumper_homogenizing_field.hh"
 #include "element_type_map_filter.hh"
 /* -------------------------------------------------------------------------- */
 namespace akantu {
 namespace dumpers {
 /* -------------------------------------------------------------------------- */
 
 template <class _types, template <class> class iterator_type>
 class GenericElementalField : public Field {
   /* ------------------------------------------------------------------------ */
   /* Typedefs                                                                 */
   /* ------------------------------------------------------------------------ */
 public:
   // check dumper_type_traits.hh for additional information over these types
   using types = _types;
   using data_type = typename types::data_type;
   using it_type = typename types::it_type;
   using field_type = typename types::field_type;
   using array_type = typename types::array_type;
   using array_iterator = typename types::array_iterator;
   using field_type_iterator = typename field_type::type_iterator;
   using iterator = iterator_type<types>;
+  using support_type = Element;
 
   /* ------------------------------------------------------------------------ */
   /* Constructors/Destructors                                                 */
   /* ------------------------------------------------------------------------ */
 public:
   GenericElementalField(const field_type & field,
                         UInt spatial_dimension = _all_dimensions,
                         GhostType ghost_type = _not_ghost,
                         ElementKind element_kind = _ek_not_defined)
       : field(field), spatial_dimension(spatial_dimension),
         ghost_type(ghost_type), element_kind(element_kind) {
     this->checkHomogeneity();
   }
 
   /* ------------------------------------------------------------------------ */
   /* Methods                                                                  */
   /* ------------------------------------------------------------------------ */
 public:
   /// get the number of components of the hosted field
   ElementTypeMap<UInt>
   getNbComponents(UInt dim = _all_dimensions, GhostType ghost_type = _not_ghost,
                   ElementKind kind = _ek_not_defined) override {
     return this->field.getNbComponents(dim, ghost_type, kind);
   };
 
   /// return the size of the contained data: i.e. the number of elements ?
   virtual UInt size() {
     checkHomogeneity();
     return this->nb_total_element;
   }
 
   /// return the iohelper datatype to be dumped
   iohelper::DataType getDataType() {
     return iohelper::getDataType<data_type>();
   }
 
 protected:
   /// return the number of entries per element
   UInt getNbDataPerElem(ElementType type,
                         GhostType ghost_type = _not_ghost) const {
     if (!nb_data_per_elem.exists(type, ghost_type)) {
       return field(type, ghost_type).getNbComponent();
     }
 
     return nb_data_per_elem(type, this->ghost_type);
   }
 
   /// check if the same quantity of data for all element types
   void checkHomogeneity() override;
 
 public:
   void registerToDumper(const std::string & id,
                         iohelper::Dumper & dumper) override {
     dumper.addElemDataField(id, *this);
   };
 
   /// for connection to a FieldCompute
   inline std::shared_ptr<Field> connect(FieldComputeProxy & proxy) override {
     return proxy.connectToField(this);
   }
 
   /// for connection to a Homogenizer
   inline std::unique_ptr<ComputeFunctorInterface>
   connect(HomogenizerProxy & proxy) override {
     return proxy.connectToField(this);
   };
 
   virtual iterator begin() {
     /// type iterators on the elemental field
     auto types = this->field.elementTypes(this->spatial_dimension,
                                           this->ghost_type, this->element_kind);
     auto tit = types.begin();
     auto end = types.end();
 
     /// skip all types without data
     for (; tit != end and this->field(*tit, this->ghost_type).empty();
          ++tit) {
     }
 
     auto type = *tit;
 
     if (tit == end) {
       return this->end();
     }
 
     /// getting information for the field of the given type
     const auto & vect = this->field(type, this->ghost_type);
     UInt nb_data_per_elem = this->getNbDataPerElem(type);
 
     /// define element-wise iterator
     auto view = make_view(vect, nb_data_per_elem);
     auto it = view.begin();
     auto it_end = view.end();
     /// define data iterator
     iterator rit =
         iterator(this->field, tit, end, it, it_end, this->ghost_type);
     rit.setNbDataPerElem(this->nb_data_per_elem);
     return rit;
   }
 
   virtual iterator end() {
     auto types = this->field.elementTypes(this->spatial_dimension,
                                           this->ghost_type, this->element_kind);
     auto tit = types.begin();
     auto end = types.end();
 
     auto type = *tit;
     for (; tit != end; ++tit) {
       type = *tit;
     }
 
     const array_type & vect = this->field(type, this->ghost_type);
     UInt nb_data = this->getNbDataPerElem(type);
     auto it = make_view(vect, nb_data).end();
     auto rit = iterator(this->field, end, end, it, it, this->ghost_type);
     rit.setNbDataPerElem(this->nb_data_per_elem);
 
     return rit;
   }
 
   virtual UInt getDim() {
     if (this->homogeneous) {
       auto tit = this->field
                      .elementTypes(this->spatial_dimension, this->ghost_type,
                                    this->element_kind)
                      .begin();
       return this->getNbDataPerElem(*tit);
     }
 
     throw;
     return 0;
   }
 
   void setNbDataPerElem(const ElementTypeMap<UInt> & nb_data) override {
     nb_data_per_elem = nb_data;
   }
 
   /* ------------------------------------------------------------------------ */
   /* Class Members                                                            */
   /* ------------------------------------------------------------------------ */
 protected:
   /// the ElementTypeMapArray embedded in the field
   const field_type & field;
   /// total number of elements
   UInt nb_total_element;
   /// the spatial dimension of the problem
   UInt spatial_dimension;
   /// whether this is a ghost field or not (for type selection)
   GhostType ghost_type;
   /// The element kind to operate on
   ElementKind element_kind;
   /// The number of data per element type
   ElementTypeMap<UInt> nb_data_per_elem;
 };
 
 } // namespace dumpers
 } // namespace akantu
 
 /* -------------------------------------------------------------------------- */
 #include "dumper_generic_elemental_field_tmpl.hh"
 /* -------------------------------------------------------------------------- */
 
 #endif /* AKANTU_DUMPER_GENERIC_ELEMENTAL_FIELD_HH_ */
diff --git a/src/io/dumper/dumper_homogenizing_field.hh b/src/io/dumper/dumper_homogenizing_field.hh
index 96395e2b1..fe8b52990 100644
--- a/src/io/dumper/dumper_homogenizing_field.hh
+++ b/src/io/dumper/dumper_homogenizing_field.hh
@@ -1,204 +1,192 @@
 /**
  * @file   dumper_homogenizing_field.hh
  *
  * @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Tue Sep 02 2014
  * @date last modification: Wed Nov 08 2017
  *
  * @brief  description of field homogenizing field
  *
  *
  * 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/>.
  *
  */
 
 #ifndef AKANTU_DUMPER_HOMOGENIZING_FIELD_HH_
 #define AKANTU_DUMPER_HOMOGENIZING_FIELD_HH_
 /* -------------------------------------------------------------------------- */
 #include "dumper_compute.hh"
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 namespace dumpers {
 
-/* -------------------------------------------------------------------------- */
-
-template <typename type>
-inline type
-typeConverter(const type & input,
-              [[gnu::unused]] Vector<typename type::value_type> & res,
-              [[gnu::unused]] UInt nb_data) {
-  throw;
-  return input;
-}
-
-/* -------------------------------------------------------------------------- */
-
-template <typename type>
-inline Matrix<type> typeConverter(const Matrix<type> & input,
-                                  Vector<type> & res, UInt nb_data) {
-
-  Matrix<type> tmp(res.storage(), input.rows(), nb_data / input.rows());
-  Matrix<type> tmp2(tmp, true);
-  return tmp2;
-}
-
-/* -------------------------------------------------------------------------- */
+  /* ------------------------------------------------------------------------ */
+  template <typename type>
+  inline type
+  typeConverter(const type & input,
+                [[gnu::unused]] Vector<typename type::value_type> & res,
+                [[gnu::unused]] UInt nb_data) {
+    throw;
+    return input;
+  }
 
-template <typename type>
-inline Vector<type> typeConverter(const Vector<type> & /*unused*/,
-                                  Vector<type> & res, UInt /*unused*/) {
-  return res;
-}
+  /* ------------------------------------------------------------------------ */
+  template <typename type>
+  inline Matrix<type> typeConverter(const Matrix<type> & input,
+                                    Vector<type> & res, UInt nb_data) {
 
-/* -------------------------------------------------------------------------- */
+    Matrix<type> tmp(res.storage(), input.rows(), nb_data / input.rows());
+    Matrix<type> tmp2(tmp, true);
+    return tmp2;
+  }
 
-template <typename type>
-class AvgHomogenizingFunctor : public ComputeFunctor<type, type> {
-  /* ------------------------------------------------------------------------ */
-  /* Typedefs                                                                 */
   /* ------------------------------------------------------------------------ */
-  using value_type = typename type::value_type;
+  template <typename type>
+  inline Vector<type> typeConverter(const Vector<type> & /*unused*/,
+                                    Vector<type> & res, UInt /*unused*/) {
+    return res;
+  }
 
   /* ------------------------------------------------------------------------ */
-  /* Constructors/Destructors                                                 */
-  /* ------------------------------------------------------------------------ */
-public:
-  AvgHomogenizingFunctor(ElementTypeMap<UInt> & nb_datas) {
-
-    auto types = nb_datas.elementTypes();
-    auto tit = types.begin();
-    auto end = types.end();
+  template <typename type>
+  class AvgHomogenizingFunctor : public ComputeFunctor<type, type> {
+    /* ---------------------------------------------------------------------- */
+    /* Typedefs */
+    /* ---------------------------------------------------------------------- */
+  private:
+    using value_type = typename type::value_type;
+
+    /* ---------------------------------------------------------------------- */
+    /* Constructors/Destructors */
+    /* ---------------------------------------------------------------------- */
+  public:
+    AvgHomogenizingFunctor(ElementTypeMap<UInt> & nb_datas) {
+
+      auto types = nb_datas.elementTypes();
+      auto tit = types.begin();
+      auto end = types.end();
+
+      nb_data = nb_datas(*tit);
+
+      for (; tit != end; ++tit) {
+        if (nb_data != nb_datas(*tit)) {
+          throw;
+        }
+      }
+    }
 
-    nb_data = nb_datas(*tit);
+    /* ---------------------------------------------------------------------- */
+    /* Methods */
+    /* ---------------------------------------------------------------------- */
+  public:
+    type func(const type & d, Element /*global_index*/) override {
+      Vector<value_type> res(this->nb_data);
 
-    for (; tit != end; ++tit) {
-      if (nb_data != nb_datas(*tit)) {
+      if (d.size() % this->nb_data) {
         throw;
       }
-    }
-  }
+      UInt nb_to_average = d.size() / this->nb_data;
 
-  /* ------------------------------------------------------------------------ */
-  /* Methods                                                                  */
-  /* ------------------------------------------------------------------------ */
+      value_type * ptr = d.storage();
+      for (UInt i = 0; i < nb_to_average; ++i) {
+        Vector<value_type> tmp(ptr, this->nb_data);
+        res += tmp;
+        ptr += this->nb_data;
+      }
+      res /= nb_to_average;
+      return typeConverter(d, res, this->nb_data);
+    };
 
-  type func(const type & d, Element /*global_index*/) override {
-    Vector<value_type> res(this->nb_data);
+    UInt getDim() override { return nb_data; };
+    UInt getNbComponent(UInt /*old_nb_comp*/) override { throw; };
 
-    if (d.size() % this->nb_data) {
-      throw;
-    }
-    UInt nb_to_average = d.size() / this->nb_data;
+    /* ---------------------------------------------------------------------- */
+    /* Class Members */
+    /* ---------------------------------------------------------------------- */
 
-    value_type * ptr = d.storage();
-    for (UInt i = 0; i < nb_to_average; ++i) {
-      Vector<value_type> tmp(ptr, this->nb_data);
-      res += tmp;
-      ptr += this->nb_data;
-    }
-    res /= nb_to_average;
-    return typeConverter(d, res, this->nb_data);
+    /// The size of data: i.e. the size of the vector to be returned
+    UInt nb_data;
   };
-
-  UInt getDim() override { return nb_data; };
-  UInt getNbComponent(UInt /*old_nb_comp*/) override { throw; };
-
-  /* ------------------------------------------------------------------------ */
-  /* Class Members                                                            */
   /* ------------------------------------------------------------------------ */
 
-  /// The size of data: i.e. the size of the vector to be returned
-  UInt nb_data;
-};
-/* -------------------------------------------------------------------------- */
-
-/* -------------------------------------------------------------------------- */
-
-class HomogenizerProxy {
-  /* ------------------------------------------------------------------------ */
-  /* Constructors/Destructors                                                 */
   /* ------------------------------------------------------------------------ */
-public:
-  HomogenizerProxy() = default;
-
-public:
-  inline static std::unique_ptr<ComputeFunctorInterface>
-  createHomogenizer(Field & field);
+  class HomogenizerProxy {
+    /* ---------------------------------------------------------------------- */
+    /* Constructors/Destructors */
+    /* ---------------------------------------------------------------------- */
+  public:
+    HomogenizerProxy() = default;
+
+  public:
+    inline static std::unique_ptr<ComputeFunctorInterface>
+    createHomogenizer(Field & field);
+
+    template <typename T>
+    inline std::unique_ptr<ComputeFunctorInterface> connectToField(T * field) {
+      ElementTypeMap<UInt> nb_components = field->getNbComponents();
+
+      using ret_type = typename T::types::return_type;
+      return this->instantiateHomogenizer<ret_type>(nb_components);
+    }
 
-  template <typename T>
-  inline std::unique_ptr<ComputeFunctorInterface> connectToField(T * field) {
-    ElementTypeMap<UInt> nb_components = field->getNbComponents();
+    template <typename ret_type>
+    inline std::unique_ptr<ComputeFunctorInterface>
+    instantiateHomogenizer(ElementTypeMap<UInt> & nb_components);
+  };
 
-    using ret_type = typename T::types::return_type;
-    return this->instantiateHomogenizer<ret_type>(nb_components);
-  }
+  /* ------------------------------------------------------------------------ */
 
   template <typename ret_type>
   inline std::unique_ptr<ComputeFunctorInterface>
-  instantiateHomogenizer(ElementTypeMap<UInt> & nb_components);
-};
-
-/* -------------------------------------------------------------------------- */
-
-template <typename ret_type>
-inline std::unique_ptr<ComputeFunctorInterface>
-HomogenizerProxy::instantiateHomogenizer(ElementTypeMap<UInt> & nb_components) {
-  using Homogenizer = dumpers::AvgHomogenizingFunctor<ret_type>;
-  return std::make_unique<Homogenizer>(nb_components);
-}
-
-template <>
-inline std::unique_ptr<ComputeFunctorInterface>
-HomogenizerProxy::instantiateHomogenizer<Vector<iohelper::ElemType>>([
-    [gnu::unused]] ElementTypeMap<UInt> & nb_components) {
-  throw;
-  return nullptr;
-}
+  HomogenizerProxy::instantiateHomogenizer(
+      ElementTypeMap<UInt> & nb_components) {
+    using Homogenizer = dumpers::AvgHomogenizingFunctor<ret_type>;
+    return std::make_unique<Homogenizer>(nb_components);
+  }
 
-/* -------------------------------------------------------------------------- */
-/// for connection to a FieldCompute
-template <typename SubFieldCompute, typename return_type>
-inline std::unique_ptr<ComputeFunctorInterface>
-FieldCompute<SubFieldCompute, return_type>::connect(HomogenizerProxy & proxy) {
-  return proxy.connectToField(this);
-}
+  template <>
+  inline std::unique_ptr<ComputeFunctorInterface>
+  HomogenizerProxy::instantiateHomogenizer<Vector<iohelper::ElemType>>(
+      [[gnu::unused]] ElementTypeMap<UInt> & nb_components) {
+    throw;
+    return nullptr;
+  }
 
-/* -------------------------------------------------------------------------- */
-inline std::unique_ptr<ComputeFunctorInterface>
-HomogenizerProxy::createHomogenizer(Field & field) {
-  HomogenizerProxy homogenizer_proxy;
-  return field.connect(homogenizer_proxy);
-}
+  /* ------------------------------------------------------------------------ */
+  /// for connection to a FieldCompute
+  template <typename SubFieldCompute, typename return_type,
+            typename support_type_>
+  inline std::unique_ptr<ComputeFunctorInterface>
+  FieldCompute<SubFieldCompute, return_type, support_type_>::connect(
+      HomogenizerProxy & proxy) {
+    return proxy.connectToField(this);
+  }
 
-/* -------------------------------------------------------------------------- */
-// inline ComputeFunctorInterface & createHomogenizer(Field & field){
-//   HomogenizerProxy::createHomogenizer(field);
-//   throw;
-//   ComputeFunctorInterface * ptr = NULL;
-//   return *ptr;
-// }
-
-// /* --------------------------------------------------------------------------
-// */
+  /* ------------------------------------------------------------------------ */
+  inline std::unique_ptr<ComputeFunctorInterface>
+  HomogenizerProxy::createHomogenizer(Field & field) {
+    HomogenizerProxy homogenizer_proxy;
+    return field.connect(homogenizer_proxy);
+  }
 
 } // namespace dumpers
 } // namespace akantu
 
 #endif /* AKANTU_DUMPER_HOMOGENIZING_FIELD_HH_ */
diff --git a/src/io/dumper/dumper_internal_material_field.hh b/src/io/dumper/dumper_internal_material_field.hh
index 8bad2ffef..ba233717e 100644
--- a/src/io/dumper/dumper_internal_material_field.hh
+++ b/src/io/dumper/dumper_internal_material_field.hh
@@ -1,71 +1,72 @@
 /**
  * @file   dumper_internal_material_field.hh
  *
  * @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Fri Jun 18 2010
  * @date last modification: Wed Nov 08 2017
  *
  * @brief  description of material internal field
  *
  *
  * 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/>.
  *
  */
 
 #ifndef AKANTU_DUMPER_INTERNAL_MATERIAL_FIELD_HH_
 #define AKANTU_DUMPER_INTERNAL_MATERIAL_FIELD_HH_
 /* -------------------------------------------------------------------------- */
 #include "dumper_quadrature_point_iterator.hh"
 #ifdef AKANTU_IGFEM
 #include "dumper_igfem_material_internal_field.hh"
 #endif
 /* -------------------------------------------------------------------------- */
 namespace akantu {
 namespace dumpers {
 /* -------------------------------------------------------------------------- */
 
 template <typename T, bool filtered = false>
 class InternalMaterialField
     : public GenericElementalField<SingleType<T, Vector, filtered>,
                                    quadrature_point_iterator> {
 
   /* ------------------------------------------------------------------------ */
   /* Typedefs                                                                 */
   /* ------------------------------------------------------------------------ */
 
 public:
   using types = SingleType<T, Vector, filtered>;
   using parent = GenericElementalField<types, quadrature_point_iterator>;
   using field_type = typename types::field_type;
+  using support_type = Element;
 
   /* ------------------------------------------------------------------------ */
   /* Constructors/Destructors                                                 */
   /* ------------------------------------------------------------------------ */
 
   InternalMaterialField(const field_type & field,
                         UInt spatial_dimension = _all_dimensions,
                         GhostType ghost_type = _not_ghost,
                         ElementKind element_kind = _ek_not_defined)
       : parent(field, spatial_dimension, ghost_type, element_kind) {}
 };
 
 } // namespace dumpers
 } // namespace akantu
 
 #endif /* AKANTU_DUMPER_INTERNAL_MATERIAL_FIELD_HH_ */
diff --git a/src/io/dumper/dumper_material_padders.hh b/src/io/dumper/dumper_material_padders.hh
index 7ee640f0d..d3b02a5f0 100644
--- a/src/io/dumper/dumper_material_padders.hh
+++ b/src/io/dumper/dumper_material_padders.hh
@@ -1,319 +1,305 @@
 /**
  * @file   dumper_material_padders.hh
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  * @author Marco Vocialta <marco.vocialta@epfl.ch>
  *
  * @date creation: Tue Sep 02 2014
  * @date last modification: Wed Nov 29 2017
  *
  * @brief  Material padders for plane stress/ plane strain
  *
  *
  * 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/>.
  *
  */
 
 #ifndef AKANTU_DUMPER_MATERIAL_PADDERS_HH_
 #define AKANTU_DUMPER_MATERIAL_PADDERS_HH_
 /* -------------------------------------------------------------------------- */
 #include "dumper_padding_helper.hh"
 /* -------------------------------------------------------------------------- */
 namespace akantu {
 namespace dumpers {
-  /* --------------------------------------------------------------------------
-   */
+  /* ------------------------------------------------------------------------ */
   class MaterialFunctor {
-    /* ------------------------------------------------------------------------
-     */
-    /* Constructors/Destructors */
-    /* ------------------------------------------------------------------------
-     */
+    /* ---------------------------------------------------------------------- */
+    /* Constructors/Destructors                                               */
+    /* ---------------------------------------------------------------------- */
   public:
     MaterialFunctor(const SolidMechanicsModel & model)
         : model(model), material_index(model.getMaterialByElement()),
           nb_data_per_element("nb_data_per_element", model.getID()),
           spatial_dimension(model.getSpatialDimension()) {}
 
-    /* ------------------------------------------------------------------------
-     */
-    /* Methods */
-    /* ------------------------------------------------------------------------
-     */
+    /* ---------------------------------------------------------------------- */
+    /* Methods                                                                */
+    /* ---------------------------------------------------------------------- */
     /// return the material from the global element index
     const Material & getMaterialFromGlobalIndex(Element global_index) {
       UInt index = global_index.element;
       UInt material_id = material_index(global_index.type)(index);
       const Material & material = model.getMaterial(material_id);
       return material;
     }
 
     /// return the type of the element from global index
     ElementType
     getElementTypeFromGlobalIndex( // NOLINT(readability-convert-member-functions-to-static)
         Element global_index) {
       return global_index.type;
     }
 
   protected:
-    /* ------------------------------------------------------------------------
-     */
-    /* Class Members */
-    /* ------------------------------------------------------------------------
-     */
+    /* ---------------------------------------------------------------------- */
+    /* Class Members                                                          */
+    /* ---------------------------------------------------------------------- */
 
     /// all material padders probably need access to solid mechanics model
     const SolidMechanicsModel & model;
 
     /// they also need an access to the map from global ids to material id and
     /// local ids
     const ElementTypeMapArray<UInt> & material_index;
 
     /// the number of data per element
     const ElementTypeMapArray<UInt> nb_data_per_element;
 
     UInt spatial_dimension;
   };
 
-  /* --------------------------------------------------------------------------
-   */
+  /* ------------------------------------------------------------------------ */
   template <class T, class R>
   class MaterialPadder : public MaterialFunctor,
                          public PadderGeneric<Vector<T>, R> {
   public:
     MaterialPadder(const SolidMechanicsModel & model)
         : MaterialFunctor(model) {}
   };
 
-  /* --------------------------------------------------------------------------
-   */
+  /* ------------------------------------------------------------------------ */
 
   template <UInt spatial_dimension>
   class StressPadder : public MaterialPadder<Real, Matrix<Real>> {
 
   public:
     StressPadder(const SolidMechanicsModel & model)
         : MaterialPadder<Real, Matrix<Real>>(model) {
       this->setPadding(3, 3);
     }
 
     inline Matrix<Real> func(const Vector<Real> & in,
                              Element global_element_id) override {
       UInt nrows = spatial_dimension;
       UInt ncols = in.size() / nrows;
       UInt nb_data = in.size() / (nrows * nrows);
 
       Matrix<Real> stress = this->pad(in, nrows, ncols, nb_data);
       const Material & material =
           this->getMaterialFromGlobalIndex(global_element_id);
       bool plane_strain = true;
       if (spatial_dimension == 2) {
         plane_strain = !((bool)material.getParam("Plane_Stress"));
       }
 
       if (plane_strain) {
         Real nu = material.getParam("nu");
         for (UInt d = 0; d < nb_data; ++d) {
           stress(2, 2 + 3 * d) =
               nu * (stress(0, 0 + 3 * d) + stress(1, 1 + 3 * d));
         }
       }
       return stress;
     }
 
     UInt getDim() override { return 9; };
 
     UInt getNbComponent(UInt /*old_nb_comp*/) override {
       return this->getDim();
     };
   };
 
-  /* --------------------------------------------------------------------------
-   */
+  /* ------------------------------------------------------------------------ */
   template <UInt spatial_dimension>
   class StrainPadder : public MaterialFunctor,
                        public PadderGeneric<Matrix<Real>, Matrix<Real>> {
   public:
     StrainPadder(const SolidMechanicsModel & model) : MaterialFunctor(model) {
       this->setPadding(3, 3);
     }
 
     inline Matrix<Real> func(const Matrix<Real> & in,
                              Element global_element_id) override {
       UInt nrows = spatial_dimension;
       UInt nb_data = in.size() / (nrows * nrows);
 
       Matrix<Real> strain = this->pad(in, nb_data);
       const Material & material =
           this->getMaterialFromGlobalIndex(global_element_id);
       bool plane_stress = material.getParam("Plane_Stress");
 
       if (plane_stress) {
         Real nu = material.getParam("nu");
         for (UInt d = 0; d < nb_data; ++d) {
           strain(2, 2 + 3 * d) =
               nu / (nu - 1) * (strain(0, 0 + 3 * d) + strain(1, 1 + 3 * d));
         }
       }
 
       return strain;
     }
 
     UInt getDim() override { return 9; };
 
     UInt getNbComponent(UInt /*old_nb_comp*/) override {
       return this->getDim();
     };
   };
 
-  /* --------------------------------------------------------------------------
-   */
+  /* ------------------------------------------------------------------------ */
   template <bool green_strain>
   class ComputeStrain : public MaterialFunctor,
                         public ComputeFunctor<Vector<Real>, Matrix<Real>> {
   public:
     ComputeStrain(const SolidMechanicsModel & model) : MaterialFunctor(model) {}
 
     inline Matrix<Real> func(const Vector<Real> & in,
                              Element /*global_element_id*/) override {
       UInt nrows = spatial_dimension;
       UInt ncols = in.size() / nrows;
       UInt nb_data = in.size() / (nrows * nrows);
 
       Matrix<Real> ret_all_strain(nrows, ncols);
       Tensor3<Real> all_grad_u(in.storage(), nrows, nrows, nb_data);
       Tensor3<Real> all_strain(ret_all_strain.storage(), nrows, nrows, nb_data);
 
       for (UInt d = 0; d < nb_data; ++d) {
         Matrix<Real> grad_u = all_grad_u(d);
         Matrix<Real> strain = all_strain(d);
 
         if (spatial_dimension == 2) {
           if (green_strain) {
             Material::gradUToE<2>(grad_u, strain);
           } else {
             Material::gradUToEpsilon<2>(grad_u, strain);
           }
         } else if (spatial_dimension == 3) {
           if (green_strain) {
             Material::gradUToE<3>(grad_u, strain);
           } else {
             Material::gradUToEpsilon<3>(grad_u, strain);
           }
         }
       }
 
       return ret_all_strain;
     }
 
     UInt getDim() override { return spatial_dimension * spatial_dimension; };
 
     UInt getNbComponent(UInt /*old_nb_comp*/) override {
       return this->getDim();
     };
   };
 
-  /* --------------------------------------------------------------------------
-   */
+  /* ------------------------------------------------------------------------ */
   template <bool green_strain>
   class ComputePrincipalStrain
       : public MaterialFunctor,
         public ComputeFunctor<Vector<Real>, Matrix<Real>> {
   public:
     ComputePrincipalStrain(const SolidMechanicsModel & model)
         : MaterialFunctor(model) {}
 
     inline Matrix<Real> func(const Vector<Real> & in,
                              Element /*global_element_id*/) override {
       UInt nrows = spatial_dimension;
       UInt nb_data = in.size() / (nrows * nrows);
 
       Matrix<Real> ret_all_strain(nrows, nb_data);
       Tensor3<Real> all_grad_u(in.storage(), nrows, nrows, nb_data);
       Matrix<Real> strain(nrows, nrows);
 
       for (UInt d = 0; d < nb_data; ++d) {
         Matrix<Real> grad_u = all_grad_u(d);
 
         if (spatial_dimension == 2) {
           if (green_strain) {
             Material::gradUToE<2>(grad_u, strain);
           } else {
             Material::gradUToEpsilon<2>(grad_u, strain);
           }
         } else if (spatial_dimension == 3) {
           if (green_strain) {
             Material::gradUToE<3>(grad_u, strain);
           } else {
             Material::gradUToEpsilon<3>(grad_u, strain);
           }
         }
 
         Vector<Real> principal_strain(ret_all_strain(d));
         strain.eig(principal_strain);
       }
 
       return ret_all_strain;
     }
 
     UInt getDim() override { return spatial_dimension; };
 
     UInt getNbComponent(UInt /*old_nb_comp*/) override {
       return this->getDim();
     };
   };
 
-  /* --------------------------------------------------------------------------
-   */
+  /* ------------------------------------------------------------------------ */
   class ComputeVonMisesStress
       : public MaterialFunctor,
         public ComputeFunctor<Vector<Real>, Vector<Real>> {
   public:
     ComputeVonMisesStress(const SolidMechanicsModel & model)
         : MaterialFunctor(model) {}
 
     inline Vector<Real> func(const Vector<Real> & in,
                              Element /*global_element_id*/) override {
       UInt nrows = spatial_dimension;
       UInt nb_data = in.size() / (nrows * nrows);
 
       Vector<Real> von_mises_stress(nb_data);
       Matrix<Real> deviatoric_stress(3, 3);
 
       for (UInt d = 0; d < nb_data; ++d) {
         Matrix<Real> cauchy_stress(in.storage() + d * nrows * nrows, nrows,
                                    nrows);
         von_mises_stress(d) = Material::stressToVonMises(cauchy_stress);
       }
 
       return von_mises_stress;
     }
 
     UInt getDim() override { return 1; };
 
     UInt getNbComponent(UInt /*old_nb_comp*/) override {
       return this->getDim();
     };
   };
 
-  /* --------------------------------------------------------------------------
-   */
+  /* ------------------------------------------------------------------------ */
 
 } // namespace dumpers
 } // namespace akantu
 
 #endif /* AKANTU_DUMPER_MATERIAL_PADDERS_HH_ */
diff --git a/src/io/dumper/dumper_nodal_field.hh b/src/io/dumper/dumper_nodal_field.hh
index 2749754a9..e8e6b4386 100644
--- a/src/io/dumper/dumper_nodal_field.hh
+++ b/src/io/dumper/dumper_nodal_field.hh
@@ -1,243 +1,238 @@
 /**
  * @file   dumper_nodal_field.hh
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Fri Oct 26 2012
  * @date last modification: Wed Nov 08 2017
  *
  * @brief  Description of nodal fields
  *
  *
  * 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/>.
  *
  */
 
 #ifndef AKANTU_DUMPER_NODAL_FIELD_HH_
 #define AKANTU_DUMPER_NODAL_FIELD_HH_
 
 #include "dumper_field.hh"
 #include <io_helper.hh>
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 namespace dumpers {
 
-// This represents a iohelper compatible field
-template <typename T, bool filtered = false, class Container = Array<T>,
-          class Filter = Array<UInt>>
-class NodalField;
+  // This represents a iohelper compatible field
+  template <typename T, bool filtered = false, class Container = Array<T>,
+            class Filter = Array<UInt>>
+  class NodalField;
 
-/* -------------------------------------------------------------------------- */
-template <typename T, class Container, class Filter>
-class NodalField<T, false, Container, Filter> : public dumpers::Field {
-public:
-  /* ------------------------------------------------------------------------ */
-  /* Typedefs                                                                 */
   /* ------------------------------------------------------------------------ */
-
-  /// associated iterator with any nodal field (non filetered)
-  class iterator : public iohelper::iterator<T, iterator, Vector<T>> {
+  template <typename T, class Container, class Filter>
+  class NodalField<T, false, Container, Filter> : public dumpers::Field {
   public:
-    iterator(T * vect, UInt offset, UInt n, UInt stride,
-             __attribute__((unused)) const UInt * filter = nullptr)
-        :
-
-          internal_it(vect), offset(offset), n(n), stride(stride) {}
+    /* ---------------------------------------------------------------------- */
+    /* Typedefs */
+    /* ---------------------------------------------------------------------- */
+    using support_type = UInt;
+
+    /// associated iterator with any nodal field (non filetered)
+    class iterator : public iohelper::iterator<T, iterator, Vector<T>> {
+    public:
+      iterator(T * vect, UInt offset, UInt n, UInt stride,
+               __attribute__((unused)) const UInt * filter = nullptr)
+          : internal_it(vect), offset(offset), n(n), stride(stride) {}
+
+      bool operator!=(const iterator & it) const override {
+        return internal_it != it.internal_it;
+      }
+      iterator & operator++() override {
+        internal_it += offset;
+        return *this;
+      };
+      Vector<T> operator*() override {
+        return Vector<T>(internal_it + stride, n);
+      };
+
+    private:
+      T * internal_it;
+      UInt offset, n, stride;
+    };
 
-    bool operator!=(const iterator & it) const override {
-      return internal_it != it.internal_it;
+    /* ---------------------------------------------------------------------- */
+    /* Constructors/Destructors */
+    /* ---------------------------------------------------------------------- */
+  public:
+    NodalField(const Container & field, UInt n = 0, UInt stride = 0,
+               [[gnu::unused]] const Filter * filter = nullptr)
+        : field(field), n(n), stride(stride), padding(0) {
+      AKANTU_DEBUG_ASSERT(filter == nullptr,
+                          "Filter passed to unfiltered NodalField!");
+      if (n == 0) {
+        this->n = field.getNbComponent() - stride;
+      }
     }
-    iterator & operator++() override {
-      internal_it += offset;
-      return *this;
-    };
-    Vector<T> operator*() override {
-      return Vector<T>(internal_it + stride, n);
-    };
 
-  private:
-    T * internal_it;
-    UInt offset, n, stride;
-  };
+    /* ---------------------------------------------------------------------- */
+    /* Methods */
+    /* ---------------------------------------------------------------------- */
+  public:
+    void registerToDumper(const std::string & id,
+                          iohelper::Dumper & dumper) override {
+      dumper.addNodeDataField(id, *this);
+    }
 
-  /* ------------------------------------------------------------------------ */
-  /* Constructors/Destructors                                                 */
-  /* ------------------------------------------------------------------------ */
-  NodalField(const Container & field, UInt n = 0, UInt stride = 0,
-             [[gnu::unused]] const Filter * filter = nullptr)
-      : field(field), n(n), stride(stride), padding(0) {
-    AKANTU_DEBUG_ASSERT(filter == nullptr,
-                        "Filter passed to unfiltered NodalField!");
-    if (n == 0) {
-      this->n = field.getNbComponent() - stride;
+    inline iterator begin() {
+      return iterator(field.storage(), field.getNbComponent(), n, stride);
     }
-  }
 
-  /* ------------------------------------------------------------------------ */
-  /* Methods                                                                  */
-  /* ------------------------------------------------------------------------ */
-  void registerToDumper(const std::string & id,
-                        iohelper::Dumper & dumper) override {
-    dumper.addNodeDataField(id, *this);
-  }
-
-  inline iterator begin() {
-    return iterator(field.storage(), field.getNbComponent(), n, stride);
-  }
-
-  inline iterator end() {
-    return iterator(field.storage() + field.getNbComponent() * field.size(),
-                    field.getNbComponent(), n, stride);
-  }
-
-  bool isHomogeneous() override { return true; }
-  void checkHomogeneity() override { this->homogeneous = true; }
-
-  virtual UInt getDim() {
-    if (this->padding) {
-      return this->padding;
+    inline iterator end() {
+      return iterator(field.storage() + field.getNbComponent() * field.size(),
+                      field.getNbComponent(), n, stride);
     }
+
+    bool isHomogeneous() override { return true; }
+    void checkHomogeneity() override { this->homogeneous = true; }
+
+    virtual UInt getDim() {
+      if (this->padding) {
+        return this->padding;
+      }
       return n;
+    }
 
-  }
+    void setPadding(UInt padding) { this->padding = padding; }
 
-  void setPadding(UInt padding) { this->padding = padding; }
+    UInt size() { return field.size(); }
 
-  UInt size() { return field.size(); }
+    iohelper::DataType getDataType() { return iohelper::getDataType<T>(); }
 
-  iohelper::DataType getDataType() { return iohelper::getDataType<T>(); }
+    /* ---------------------------------------------------------------------- */
+    /* Class Members */
+    /* ---------------------------------------------------------------------- */
+  private:
+    const Container & field;
+    UInt n, stride;
+    UInt padding;
+  };
 
   /* ------------------------------------------------------------------------ */
-  /* Class Members                                                            */
-  /* ------------------------------------------------------------------------ */
+  template <typename T, class Container, class Filter>
+  class NodalField<T, true, Container, Filter> : public dumpers::Field {
+    /* ---------------------------------------------------------------------- */
+    /* Typedefs */
+    /* ---------------------------------------------------------------------- */
+  public:
+    class iterator : public iohelper::iterator<T, iterator, Vector<T>> {
 
-private:
-  const Container & field;
-  UInt n, stride;
-  UInt padding;
-};
+    public:
+      iterator(T * const vect, UInt _offset, UInt _n, UInt _stride,
+               const UInt * filter)
+          :
 
-/* -------------------------------------------------------------------------- */
-template <typename T, class Container, class Filter>
-class NodalField<T, true, Container, Filter> : public dumpers::Field {
+            internal_it(vect), offset(_offset), n(_n), stride(_stride),
+            filter(filter) {}
 
-  /* ------------------------------------------------------------------------ */
-  /* Typedefs                                                                 */
-  /* ------------------------------------------------------------------------ */
+      bool operator!=(const iterator & it) const override {
+        return filter != it.filter;
+      }
 
-public:
-  class iterator : public iohelper::iterator<T, iterator, Vector<T>> {
+      iterator & operator++() override {
+        ++filter;
+        return *this;
+      }
 
-  public:
-    iterator(T * const vect, UInt _offset, UInt _n, UInt _stride,
-             const UInt * filter)
-        :
+      Vector<T> operator*() override {
+        return Vector<T>(internal_it + *(filter)*offset + stride, n);
+      }
 
-          internal_it(vect), offset(_offset), n(_n), stride(_stride),
-          filter(filter) {}
+    private:
+      T * const internal_it;
+      UInt offset, n, stride;
+      const UInt * filter;
+    };
 
-    bool operator!=(const iterator & it) const override {
-      return filter != it.filter;
+    /* ---------------------------------------------------------------------- */
+    /* Constructors/Destructors */
+    /* ---------------------------------------------------------------------- */
+  public:
+    NodalField(const Container & _field, UInt _n = 0, UInt _stride = 0,
+               const Filter * filter = NULL)
+        : field(_field), n(_n), stride(_stride), filter(filter), padding(0) {
+      AKANTU_DEBUG_ASSERT(this->filter != nullptr,
+                          "No filter passed to filtered NodalField!");
+
+      AKANTU_DEBUG_ASSERT(this->filter->getNbComponent() == 1,
+                          "Multi-component filter given to NodalField ("
+                              << this->filter->getNbComponent()
+                              << " components detected, sould be 1");
+      if (n == 0) {
+        this->n = field.getNbComponent() - stride;
+      }
     }
 
-    iterator & operator++() override {
-      ++filter;
-      return *this;
+    /* ---------------------------------------------------------------------- */
+    /* Methods */
+    /* ---------------------------------------------------------------------- */
+  public:
+    void registerToDumper(const std::string & id,
+                          iohelper::Dumper & dumper) override {
+      dumper.addNodeDataField(id, *this);
     }
 
-    Vector<T> operator*() override {
-      return Vector<T>(internal_it + *(filter)*offset + stride, n);
+    inline iterator begin() {
+      return iterator(field.storage(), field.getNbComponent(), n, stride,
+                      filter->storage());
     }
 
-  private:
-    T * const internal_it;
-    UInt offset, n, stride;
-    const UInt * filter;
-  };
-
-  /* ------------------------------------------------------------------------ */
-  /* Constructors/Destructors                                                 */
-  /* ------------------------------------------------------------------------ */
-
-  NodalField(const Container & _field, UInt _n = 0, UInt _stride = 0,
-             const Filter * filter = NULL)
-      : field(_field), n(_n), stride(_stride), filter(filter), padding(0) {
-    AKANTU_DEBUG_ASSERT(this->filter != nullptr,
-                        "No filter passed to filtered NodalField!");
-
-    AKANTU_DEBUG_ASSERT(this->filter->getNbComponent() == 1,
-                        "Multi-component filter given to NodalField ("
-                            << this->filter->getNbComponent()
-                            << " components detected, sould be 1");
-    if (n == 0) {
-      this->n = field.getNbComponent() - stride;
+    inline iterator end() {
+      return iterator(field.storage(), field.getNbComponent(), n, stride,
+                      filter->storage() + filter->size());
     }
-  }
 
-  /* ------------------------------------------------------------------------ */
-  /* Methods                                                                  */
-  /* ------------------------------------------------------------------------ */
+    bool isHomogeneous() override { return true; }
+    void checkHomogeneity() override { this->homogeneous = true; }
 
-  void registerToDumper(const std::string & id,
-                        iohelper::Dumper & dumper) override {
-    dumper.addNodeDataField(id, *this);
-  }
-
-  inline iterator begin() {
-    return iterator(field.storage(), field.getNbComponent(), n, stride,
-                    filter->storage());
-  }
-
-  inline iterator end() {
-    return iterator(field.storage(), field.getNbComponent(), n, stride,
-                    filter->storage() + filter->size());
-  }
-
-  bool isHomogeneous() override { return true; }
-  void checkHomogeneity() override { this->homogeneous = true; }
-
-  virtual UInt getDim() {
-    if (this->padding) {
-      return this->padding;
-    }
+    virtual UInt getDim() {
+      if (this->padding) {
+        return this->padding;
+      }
       return n;
+    }
 
-  }
-
-  void setPadding(UInt padding) { this->padding = padding; }
-
-  UInt size() { return filter->size(); }
+    void setPadding(UInt padding) { this->padding = padding; }
 
-  iohelper::DataType getDataType() { return iohelper::getDataType<T>(); }
+    UInt size() { return filter->size(); }
 
-  /* ------------------------------------------------------------------------ */
-  /* Class Members                                                            */
-  /* ------------------------------------------------------------------------ */
+    iohelper::DataType getDataType() { return iohelper::getDataType<T>(); }
 
-private:
-  const Container & field;
-  UInt n, stride;
-  const Filter * filter;
+    /* ---------------------------------------------------------------------- */
+    /* Class Members */
+    /* ---------------------------------------------------------------------- */
+  private:
+    const Container & field;
+    UInt n, stride;
+    const Filter * filter;
 
-  UInt padding;
-};
+    UInt padding;
+  };
 
 } // namespace dumpers
 } // namespace akantu
 /* -------------------------------------------------------------------------- */
 #endif /* AKANTU_DUMPER_NODAL_FIELD_HH_ */
diff --git a/src/io/dumper/dumper_type_traits.hh b/src/io/dumper/dumper_type_traits.hh
index cb608b329..810b78b25 100644
--- a/src/io/dumper/dumper_type_traits.hh
+++ b/src/io/dumper/dumper_type_traits.hh
@@ -1,89 +1,88 @@
 /**
  * @file   dumper_type_traits.hh
  *
  * @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
  *
  * @date creation: Tue Sep 02 2014
  * @date last modification: Wed Nov 08 2017
  *
  * @brief  Type traits for field properties
  *
  *
  * 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/>.
  *
  */
 
 #ifndef AKANTU_DUMPER_TYPE_TRAITS_HH_
 #define AKANTU_DUMPER_TYPE_TRAITS_HH_
 /* -------------------------------------------------------------------------- */
 #include "element_type_map.hh"
 #include "element_type_map_filter.hh"
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 namespace dumpers {
   /* ------------------------------------------------------------------------ */
   template <class data, class ret, class field> struct TypeTraits {
-
     //! the stored data (real, int, uint, ...)
     using data_type = data;
     //! the type returned by the operator *
     using return_type = ret;
     //! the field type (ElementTypeMap or ElementTypeMapFilter)
     using field_type = field;
     //! the type over which we iterate
     using it_type = typename field_type::type;
     //! the type of array (Array<T> or ArrayFilter<T>)
     using array_type = typename field_type::array_type;
     //! the iterator over the array
     using array_iterator = typename array_type::const_vector_iterator;
   };
 
   /* ------------------------------------------------------------------------ */
 
   // specialization for the case in which input and output types are the same
   template <class T, template <class> class ret, bool filtered>
   struct SingleType : public TypeTraits<T, ret<T>, ElementTypeMapArray<T>> {};
 
   /* ------------------------------------------------------------------------ */
 
   // same as before but for filtered data
   template <class T, template <class> class ret>
   struct SingleType<T, ret, true>
       : public TypeTraits<T, ret<T>, ElementTypeMapArrayFilter<T>> {};
   /* ------------------------------------------------------------------------ */
 
   // specialization for the case in which input and output types are different
   template <class it_type, class data_type, template <class> class ret,
             bool filtered>
   struct DualType : public TypeTraits<data_type, ret<data_type>,
                                       ElementTypeMapArray<it_type>> {};
 
   /* ------------------------------------------------------------------------ */
 
   // same as before but for filtered data
   template <class it_type, class data_type, template <class> class ret>
   struct DualType<it_type, data_type, ret, true>
       : public TypeTraits<data_type, ret<data_type>,
                           ElementTypeMapArrayFilter<it_type>> {};
   /* ------------------------------------------------------------------------ */
 } // namespace dumpers
 } // namespace akantu
 
 /* -------------------------------------------------------------------------- */
 
 #endif /* AKANTU_DUMPER_TYPE_TRAITS_HH_ */
diff --git a/src/model/contact_mechanics/contact_detector_inline_impl.cc b/src/model/contact_mechanics/contact_detector_inline_impl.cc
index 96fadcb77..8004ed90d 100644
--- a/src/model/contact_mechanics/contact_detector_inline_impl.cc
+++ b/src/model/contact_mechanics/contact_detector_inline_impl.cc
@@ -1,333 +1,332 @@
 /**
  * @file contact_detection.hh
  *
  * @author Mohit Pundir <mohit.pundir@epfl.ch>
  *
  * @date creation: Mon Apr 29 2019
  * @date last modification: Mon Apr 29 2019
  *
  * @brief  inine implementation of the contact detector class
  *
  * @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 "contact_detector.hh"
 /* -------------------------------------------------------------------------- */
 
 #ifndef __AKANTU_CONTACT_DETECTOR_INLINE_IMPL_CC__
 #define __AKANTU_CONTACT_DETECTOR_INLINE_IMPL_CC__
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 inline bool
 ContactDetector::checkValidityOfProjection(Vector<Real> & projection) {
-
-  UInt nb_xi_inside = 0;
   Real tolerance = 1e-3;
 
   for (auto xi : projection) {
     if ((xi < -1.0 - tolerance) or (xi > 1.0 + tolerance)) {
       return false;
+    }
   }
   return true;
 }
 
 /* -------------------------------------------------------------------------- */
 inline void ContactDetector::coordinatesOfElement(const Element & el,
                                                   Matrix<Real> & coords) {
 
   UInt nb_nodes_per_element = Mesh::getNbNodesPerElement(el.type);
   Vector<UInt> connect = mesh.getConnectivity(el.type, _not_ghost)
                              .begin(nb_nodes_per_element)[el.element];
 
   for (UInt n = 0; n < nb_nodes_per_element; ++n) {
     UInt node = connect[n];
     for (UInt s : arange(spatial_dimension)) {
       coords(s, n) = this->positions(node, s);
     }
   }
 }
 
 /* -------------------------------------------------------------------------- */
 inline void ContactDetector::computeCellSpacing(Vector<Real> & spacing) {
   for (UInt s : arange(spatial_dimension))
     spacing(s) = std::sqrt(2.0) * max_dd;
 }
 
 /* -------------------------------------------------------------------------- */
 inline void
 ContactDetector::constructBoundingBox(BBox & bbox,
                                       const Array<UInt> & nodes_list) {
 
   auto to_bbox = [&](UInt node) {
     Vector<Real> pos(spatial_dimension);
     for (UInt s : arange(spatial_dimension)) {
       pos(s) = this->positions(node, s);
     }
     bbox += pos;
   };
 
   std::for_each(nodes_list.begin(), nodes_list.end(), to_bbox);
 
   auto & lower_bound = bbox.getLowerBounds();
   auto & upper_bound = bbox.getUpperBounds();
 
   for (UInt s : arange(spatial_dimension)) {
     lower_bound(s) -= this->max_bb;
     upper_bound(s) += this->max_bb;
   }
 
   AKANTU_DEBUG_INFO("BBox" << bbox);
 }
 
 /* -------------------------------------------------------------------------- */
 inline void ContactDetector::constructGrid(SpatialGrid<UInt> & grid,
                                            BBox & bbox,
                                            const Array<UInt> & nodes_list) {
   auto to_grid = [&](UInt node) {
     Vector<Real> pos(spatial_dimension);
     for (UInt s : arange(spatial_dimension)) {
       pos(s) = this->positions(node, s);
     }
 
     if (bbox.contains(pos)) {
       grid.insert(node, pos);
     }
   };
 
   std::for_each(nodes_list.begin(), nodes_list.end(), to_grid);
 }
 
 /* -------------------------------------------------------------------------- */
 inline void ContactDetector::computeMaximalDetectionDistance() {
 
   AKANTU_DEBUG_IN();
 
   Real elem_size;
   Real max_elem_size = std::numeric_limits<Real>::min();
   Real min_elem_size = std::numeric_limits<Real>::max();
 
   auto & master_nodes = this->surface_selector->getMasterList();
 
   for (auto & master : master_nodes) {
     Array<Element> elements;
     this->mesh.getAssociatedElements(master, elements);
 
     for (auto element : elements) {
       UInt nb_nodes_per_element = mesh.getNbNodesPerElement(element.type);
       Matrix<Real> elem_coords(spatial_dimension, nb_nodes_per_element);
       this->coordinatesOfElement(element, elem_coords);
 
       elem_size = FEEngine::getElementInradius(elem_coords, element.type);
       max_elem_size = std::max(max_elem_size, elem_size);
       min_elem_size = std::min(min_elem_size, elem_size);
     }
   }
 
   AKANTU_DEBUG_INFO("The maximum element size : " << max_elem_size);
 
   this->min_dd = min_elem_size;
   this->max_dd = max_elem_size;
   this->max_bb = max_elem_size;
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 inline Vector<UInt>
 ContactDetector::constructConnectivity(UInt & slave, const Element & master) {
 
   Vector<UInt> master_conn =
       const_cast<const Mesh &>(this->mesh).getConnectivity(master);
 
   Vector<UInt> elem_conn(master_conn.size() + 1);
 
   elem_conn[0] = slave;
   for (UInt i = 1; i < elem_conn.size(); ++i) {
     elem_conn[i] = master_conn[i - 1];
   }
 
   return elem_conn;
 }
 
 /* -------------------------------------------------------------------------- */
 inline void ContactDetector::computeNormalOnElement(const Element & element,
                                                     Vector<Real> & normal) {
 
   Matrix<Real> vectors(spatial_dimension, spatial_dimension - 1);
   this->vectorsAlongElement(element, vectors);
 
   switch (this->spatial_dimension) {
   case 2: {
     Math::normal2(vectors.storage(), normal.storage());
     break;
   }
   case 3: {
     Math::normal3(vectors(0).storage(), vectors(1).storage(), normal.storage());
     break;
   }
   default: { AKANTU_ERROR("Unknown dimension : " << spatial_dimension); }
   }
 
   // to ensure that normal is always outwards from master surface
   const auto & element_to_subelement =
       mesh.getElementToSubelement(element.type)(element.element);
 
   Vector<Real> outside(spatial_dimension);
   mesh.getBarycenter(element, outside);
 
   // check if mesh facets exists for cohesive elements contact
   Vector<Real> inside(spatial_dimension);
   if (mesh.isMeshFacets()) {
     mesh.getMeshParent().getBarycenter(element_to_subelement[0], inside);
   } else {
     mesh.getBarycenter(element_to_subelement[0], inside);
   }
 
   Vector<Real> inside_to_outside = outside - inside;
   auto projection = inside_to_outside.dot(normal);
 
   if (projection < 0) {
     normal *= -1.0;
   }
 }
 
 /* -------------------------------------------------------------------------- */
 inline void ContactDetector::vectorsAlongElement(const Element & el,
                                                  Matrix<Real> & vectors) {
 
   UInt nb_nodes_per_element = Mesh::getNbNodesPerElement(el.type);
 
   Matrix<Real> coords(spatial_dimension, nb_nodes_per_element);
   this->coordinatesOfElement(el, coords);
 
   for(auto i : arange(spatial_dimension - 1)) {
     vectors(i) = Vector<Real>(coords(i + 1)) - Vector<Real>(coords(0));
   }
 }
 
 /* -------------------------------------------------------------------------- */
 inline Real ContactDetector::computeGap(Vector<Real> & slave,
                                         Vector<Real> & master) {
 
   Vector<Real> slave_to_master(spatial_dimension);
   slave_to_master = master - slave;
 
   Real gap = slave_to_master.norm();
   return gap;
 }
 
 /* -------------------------------------------------------------------------- */
 inline void
 ContactDetector::filterBoundaryElements(Array<Element> & elements,
                                         Array<Element> & boundary_elements) {
 
   for (auto elem : elements) {
 
     const auto & element_to_subelement =
         mesh.getElementToSubelement(elem.type)(elem.element);
 
     // for regular boundary elements
     if (element_to_subelement.size() == 1 and
         element_to_subelement[0].kind() == _ek_regular) {
       boundary_elements.push_back(elem);
       continue;
     }
 
     // for cohesive boundary elements
     UInt nb_subelements_regular = 0;
     for (auto subelem : element_to_subelement) {
       if (subelem == ElementNull)
         continue;
 
       if (subelem.kind() == _ek_regular)
         ++nb_subelements_regular;
     }
 
     auto nb_subelements = element_to_subelement.size();
 
     if (nb_subelements_regular < nb_subelements)
       boundary_elements.push_back(elem);
   }
 }
 
 
 /* -------------------------------------------------------------------------- */
 inline bool
 ContactDetector::isValidSelfContact(const UInt & slave_node, const Real & gap,
 				    const Vector<Real> & normal) {
 
   UInt master_node;
 
   // finding the master node corresponding to slave node
   for (auto & pair : contact_pairs) {
     if (pair.first == slave_node) {
       master_node = pair.second;
       break;
     }
   }
 
   Array<Element> slave_elements;
   this->mesh.getAssociatedElements(slave_node, slave_elements);
 
   // Check 1 : master node is not connected to elements connected to
   // slave node
   Vector<Real> slave_normal(spatial_dimension);
   for (auto & element : slave_elements) {
     if (element.kind() != _ek_regular)
       continue;
 
     Vector<UInt> connectivity =
         const_cast<const Mesh &>(this->mesh).getConnectivity(element);
 
     // finding the normal at slave node by averaging of normals 
     Vector<Real> normal(spatial_dimension);
     GeometryUtils::normal(mesh, positions, element, normal);
     slave_normal = slave_normal + normal;
     
     auto node_iter =
         std::find(connectivity.begin(), connectivity.end(), master_node);
     if (node_iter != connectivity.end()) 
       return false;
   }
 
   // Check 2 : if gap is twice the size of smallest element 
   if (std::abs(gap) > 2.0 * min_dd) 
     return false;
   
   // Check 3 : check the directions of normal at slave node and at
   // master element, should be in opposite directions 
   auto norm = slave_normal.norm();
   if (norm != 0)
     slave_normal /= norm;
      
   auto product = slave_normal.dot(normal);
   if (product >= 0)  
     return false;
   
   return true;
 }
 
   
 } // namespace akantu
 
 #endif /*  __AKANTU_CONTACT_DETECTOR_INLINE_IMPL_CC__ */
diff --git a/src/model/contact_mechanics/contact_mechanics_model.cc b/src/model/contact_mechanics/contact_mechanics_model.cc
index 333b51d99..54b27e4b1 100644
--- a/src/model/contact_mechanics/contact_mechanics_model.cc
+++ b/src/model/contact_mechanics/contact_mechanics_model.cc
@@ -1,754 +1,760 @@
 /**
  * @file   coontact_mechanics_model.cc
  *
  * @author Mohit Pundir <mohit.pundir@epfl.ch>
  *
  * @date creation: Tue May 08 2012
  * @date last modification: Wed Feb 21 2018
  *
  * @brief  Contact mechanics model
  *
  * @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 "contact_mechanics_model.hh"
 #include "boundary_condition_functor.hh"
 #include "dumpable_inline_impl.hh"
+#include "group_manager_inline_impl.hh"
 #include "integrator_gauss.hh"
 #include "shape_lagrange.hh"
-#include "group_manager_inline_impl.hh"
 
 #ifdef AKANTU_USE_IOHELPER
 #include "dumper_iohelper_paraview.hh"
 #endif
 
 /* -------------------------------------------------------------------------- */
 #include <algorithm>
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 ContactMechanicsModel::ContactMechanicsModel(
     Mesh & mesh, UInt dim, const ID & id,
     std::shared_ptr<DOFManager> dof_manager, const ModelType model_type)
     : Model(mesh, model_type, dof_manager, dim, id) {
 
   AKANTU_DEBUG_IN();
 
   this->registerFEEngineObject<MyFEEngineType>("ContactMechanicsModel", mesh,
                                                Model::spatial_dimension);
 #if defined(AKANTU_USE_IOHELPER)
   this->mesh.registerDumper<DumperParaview>("contact_mechanics", id, true);
   this->mesh.addDumpMeshToDumper("contact_mechanics", mesh,
                                  Model::spatial_dimension, _not_ghost,
                                  _ek_regular);
 #endif
 
   this->registerDataAccessor(*this);
 
   this->detector =
       std::make_unique<ContactDetector>(this->mesh, id + ":contact_detector");
 
   registerFEEngineObject<MyFEEngineType>("ContactFacetsFEEngine", mesh,
-					 Model::spatial_dimension - 1);
-  
+                                         Model::spatial_dimension - 1);
+
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 ContactMechanicsModel::~ContactMechanicsModel() {
   AKANTU_DEBUG_IN();
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void ContactMechanicsModel::initFullImpl(const ModelOptions & options) {
 
   Model::initFullImpl(options);
 
   // initalize the resolutions
   if (this->parser.getLastParsedFile() != "") {
     this->instantiateResolutions();
     this->initResolutions();
   }
 
   this->initBC(*this, *displacement, *displacement_increment, *external_force);
 }
 
 /* -------------------------------------------------------------------------- */
 void ContactMechanicsModel::instantiateResolutions() {
   ParserSection model_section;
   bool is_empty;
   std::tie(model_section, is_empty) = this->getParserSection();
 
   if (not is_empty) {
     auto model_resolutions =
         model_section.getSubSections(ParserType::_contact_resolution);
     for (const auto & section : model_resolutions) {
       this->registerNewResolution(section);
     }
   }
 
   auto sub_sections =
       this->parser.getSubSections(ParserType::_contact_resolution);
   for (const auto & section : sub_sections) {
     this->registerNewResolution(section);
   }
 
   if (resolutions.empty())
     AKANTU_EXCEPTION("No contact resolutions where instantiated for the model"
                      << getID());
   are_resolutions_instantiated = true;
 }
 
 /* -------------------------------------------------------------------------- */
 Resolution &
 ContactMechanicsModel::registerNewResolution(const ParserSection & section) {
   std::string res_name;
   std::string res_type = section.getName();
   std::string opt_param = section.getOption();
 
   try {
     std::string tmp = section.getParameter("name");
     res_name = tmp; /** this can seem weird, but there is an ambiguous operator
                      * overload that i couldn't solve. @todo remove the
                      * weirdness of this code
                      */
   } catch (debug::Exception &) {
     AKANTU_ERROR("A contact resolution of type \'"
                  << res_type
                  << "\' in the input file has been defined without a name!");
   }
   Resolution & res = this->registerNewResolution(res_name, res_type, opt_param);
 
   res.parseSection(section);
 
   return res;
 }
 
 /* -------------------------------------------------------------------------- */
 Resolution & ContactMechanicsModel::registerNewResolution(
     const ID & res_name, const ID & res_type, const ID & opt_param) {
   AKANTU_DEBUG_ASSERT(resolutions_names_to_id.find(res_name) ==
                           resolutions_names_to_id.end(),
                       "A resolution with this name '"
                           << res_name << "' has already been registered. "
                           << "Please use unique names for resolutions");
 
   UInt res_count = resolutions.size();
   resolutions_names_to_id[res_name] = res_count;
 
   std::stringstream sstr_res;
   sstr_res << this->id << ":" << res_count << ":" << res_type;
   ID res_id = sstr_res.str();
 
   std::unique_ptr<Resolution> resolution =
       ResolutionFactory::getInstance().allocate(res_type, spatial_dimension,
                                                 opt_param, *this, res_id);
 
   resolutions.push_back(std::move(resolution));
 
   return *(resolutions.back());
 }
 
 /* -------------------------------------------------------------------------- */
 void ContactMechanicsModel::initResolutions() {
   AKANTU_DEBUG_ASSERT(resolutions.size() != 0,
                       "No resolutions to initialize !");
 
   if (!are_resolutions_instantiated)
     instantiateResolutions();
 
   // \TODO check if each resolution needs a initResolution() method
 }
 
 /* -------------------------------------------------------------------------- */
 void ContactMechanicsModel::initModel() {
 
   AKANTU_DEBUG_IN();
-  
+
   getFEEngine("ContactMechanicsModel").initShapeFunctions(_not_ghost);
   getFEEngine("ContactMechanicsModel").initShapeFunctions(_ghost);
 
   getFEEngine("ContactFacetsFEEngine").initShapeFunctions(_not_ghost);
   getFEEngine("ContactFacetsFEEngine").initShapeFunctions(_ghost);
 
-  AKANTU_DEBUG_OUT(); 
+  AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 FEEngine & ContactMechanicsModel::getFEEngineBoundary(const ID & name) {
   return dynamic_cast<FEEngine &>(
       getFEEngineClassBoundary<MyFEEngineType>(name));
 }
 
 /* -------------------------------------------------------------------------- */
 void ContactMechanicsModel::initSolver(
     TimeStepSolverType /*time_step_solver_type*/, NonLinearSolverType) {
 
   // for alloc type of solvers
   this->allocNodalField(this->displacement, spatial_dimension, "displacement");
   this->allocNodalField(this->displacement_increment, spatial_dimension,
                         "displacement_increment");
   this->allocNodalField(this->internal_force, spatial_dimension,
                         "internal_force");
   this->allocNodalField(this->external_force, spatial_dimension,
                         "external_force");
-  this->allocNodalField(this->normal_force, spatial_dimension,
-			"normal_force");
+  this->allocNodalField(this->normal_force, spatial_dimension, "normal_force");
   this->allocNodalField(this->tangential_force, spatial_dimension,
-			"tangential_force");
-  
+                        "tangential_force");
+
   this->allocNodalField(this->gaps, 1, "gaps");
   this->allocNodalField(this->nodal_area, 1, "areas");
   this->allocNodalField(this->blocked_dofs, 1, "blocked_dofs");
   this->allocNodalField(this->contact_state, 1, "contact_state");
-  this->allocNodalField(this->previous_master_elements, 1, "previous_master_elements");
-  
+  this->allocNodalField(this->previous_master_elements, 1,
+                        "previous_master_elements");
+
   this->allocNodalField(this->normals, spatial_dimension, "normals");
 
   auto surface_dimension = spatial_dimension - 1;
-  this->allocNodalField(this->tangents, surface_dimension*spatial_dimension,
-			"tangents");
-  this->allocNodalField(this->projections, surface_dimension,
-			"projections");
+  this->allocNodalField(this->tangents, surface_dimension * spatial_dimension,
+                        "tangents");
+  this->allocNodalField(this->projections, surface_dimension, "projections");
   this->allocNodalField(this->previous_projections, surface_dimension,
-			"previous_projections");
-  this->allocNodalField(this->previous_tangents, surface_dimension*spatial_dimension,
-			"previous_tangents");
+                        "previous_projections");
+  this->allocNodalField(this->previous_tangents,
+                        surface_dimension * spatial_dimension,
+                        "previous_tangents");
   this->allocNodalField(this->tangential_tractions, surface_dimension,
-			"tangential_tractions");
+                        "tangential_tractions");
   this->allocNodalField(this->previous_tangential_tractions, surface_dimension,
-			"previous_tangential_tractions");
-    
+                        "previous_tangential_tractions");
+
   // todo register multipliers as dofs for lagrange multipliers
 }
 
 /* -------------------------------------------------------------------------- */
 std::tuple<ID, TimeStepSolverType>
 ContactMechanicsModel::getDefaultSolverID(const AnalysisMethod & method) {
 
   switch (method) {
   case _explicit_lumped_mass: {
     return std::make_tuple("explicit_lumped",
                            TimeStepSolverType::_dynamic_lumped);
   }
   case _explicit_consistent_mass: {
     return std::make_tuple("explicit", TimeStepSolverType::_dynamic);
   }
   case _static: {
     return std::make_tuple("static", TimeStepSolverType::_static);
   }
   case _implicit_dynamic: {
     return std::make_tuple("implicit", TimeStepSolverType::_dynamic);
   }
   default:
     return std::make_tuple("unknown", TimeStepSolverType::_not_defined);
   }
 }
 
 /* -------------------------------------------------------------------------- */
 ModelSolverOptions ContactMechanicsModel::getDefaultSolverOptions(
     const TimeStepSolverType & type) const {
   ModelSolverOptions options;
 
   switch (type) {
   case TimeStepSolverType::_dynamic: {
     options.non_linear_solver_type = NonLinearSolverType::_lumped;
     options.integration_scheme_type["displacement"] =
         IntegrationSchemeType::_central_difference;
     options.solution_type["displacement"] = IntegrationScheme::_acceleration;
     break;
   }
   case TimeStepSolverType::_dynamic_lumped: {
     options.non_linear_solver_type = NonLinearSolverType::_lumped;
     options.integration_scheme_type["displacement"] =
         IntegrationSchemeType::_central_difference;
     options.solution_type["displacement"] = IntegrationScheme::_acceleration;
     break;
   }
   case TimeStepSolverType::_static: {
     options.non_linear_solver_type =
         NonLinearSolverType::_newton_raphson_contact;
     options.integration_scheme_type["displacement"] =
         IntegrationSchemeType::_pseudo_time;
     options.solution_type["displacement"] = IntegrationScheme::_not_defined;
     break;
   }
   default:
     AKANTU_EXCEPTION(type << " is not a valid time step solver type");
     break;
   }
 
   return options;
 }
 
 /* -------------------------------------------------------------------------- */
 void ContactMechanicsModel::assembleResidual() {
   AKANTU_DEBUG_IN();
 
   /* ------------------------------------------------------------------------ */
   // computes the internal forces
   this->assembleInternalForces();
 
   /* ------------------------------------------------------------------------ */
   this->getDOFManager().assembleToResidual("displacement",
                                            *this->internal_force, 1);
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void ContactMechanicsModel::assembleInternalForces() {
   AKANTU_DEBUG_IN();
 
   AKANTU_DEBUG_INFO("Assemble the contact forces");
 
   UInt nb_nodes = mesh.getNbNodes();
   this->internal_force->clear();
   this->normal_force->clear();
   this->tangential_force->clear();
 
   internal_force->resize(nb_nodes, 0.);
   normal_force->resize(nb_nodes, 0.);
   tangential_force->resize(nb_nodes, 0.);
 
   // assemble the forces due to contact
   auto assemble = [&](auto && ghost_type) {
     for (auto & resolution : resolutions) {
       resolution->assembleInternalForces(ghost_type);
     }
   };
 
   AKANTU_DEBUG_INFO("Assemble residual for local elements");
   assemble(_not_ghost);
 
   // assemble the stresses due to ghost elements
   AKANTU_DEBUG_INFO("Assemble residual for ghost elements");
-  //assemble(_ghost);
+  // assemble(_ghost);
   // TODO : uncomment when developing code for parallelization,
   // currently it addes the force twice for not ghost elements
   // hence source of error
 
   AKANTU_DEBUG_OUT();
 }
 /* -------------------------------------------------------------------------- */
 void ContactMechanicsModel::search() {
 
-  // save the previous state 
+  // save the previous state
   this->savePreviousState();
-  
+
   contact_elements.clear();
 
-  // this needs to be resized if cohesive elements are added 
+  // this needs to be resized if cohesive elements are added
   UInt nb_nodes = mesh.getNbNodes();
 
   auto resize_arrays = [&](auto & internal_array) {
     internal_array->resize(nb_nodes);
     internal_array->zero();
   };
 
   resize_arrays(gaps);
   resize_arrays(normals);
   resize_arrays(tangents);
   resize_arrays(projections);
   resize_arrays(tangential_tractions);
   resize_arrays(contact_state);
   resize_arrays(nodal_area);
   resize_arrays(external_force);
-  
-  this->detector->search(contact_elements, *gaps,
-			 *normals, *tangents, *projections);
+
+  this->detector->search(contact_elements, *gaps, *normals, *tangents,
+                         *projections);
 
   // intepenetration value must be positive for contact mechanics
   // model to work by default the gap value from detector is negative
-  std::for_each((*gaps).begin(), (*gaps).end(),
-  		[](Real & gap){ gap *= -1.; });
-  
+  std::for_each((*gaps).begin(), (*gaps).end(), [](Real & gap) { gap *= -1.; });
+
   if (contact_elements.size() != 0) {
-     this->computeNodalAreas();
+    this->computeNodalAreas();
   }
-  
 }
 
 /* -------------------------------------------------------------------------- */
 void ContactMechanicsModel::savePreviousState() {
 
   AKANTU_DEBUG_IN();
 
-  // saving previous natural projections 
+  // saving previous natural projections
   (*previous_projections).copy(*projections);
 
   // saving previous tangents
   (*previous_tangents).copy(*tangents);
 
   // saving previous tangential traction
   (*previous_tangential_tractions).copy(*tangential_tractions);
 
   previous_master_elements->clear();
   previous_master_elements->resize(projections->size());
   previous_master_elements->set(ElementNull);
   for (auto & element : contact_elements) {
     (*previous_master_elements)[element.slave] = element.master;
   }
 
   AKANTU_DEBUG_OUT();
 }
 
-  
 /* -------------------------------------------------------------------------- */
 void ContactMechanicsModel::computeNodalAreas(GhostType ghost_type) {
 
   UInt nb_nodes = mesh.getNbNodes();
 
   nodal_area->resize(nb_nodes);
   nodal_area->zero();
 
   external_force->resize(nb_nodes);
   external_force->zero();
-  
-  auto & fem_boundary = getFEEngineClassBoundary<MyFEEngineType>("ContactMechanicsModel");
+
+  auto & fem_boundary =
+      getFEEngineClassBoundary<MyFEEngineType>("ContactMechanicsModel");
 
   fem_boundary.initShapeFunctions(getPositions(), _not_ghost);
   fem_boundary.initShapeFunctions(getPositions(), _ghost);
-  
+
   fem_boundary.computeNormalsOnIntegrationPoints(_not_ghost);
   fem_boundary.computeNormalsOnIntegrationPoints(_ghost);
-  
-  
+
   IntegrationPoint quad_point;
   quad_point.ghost_type = ghost_type;
-  
+
   auto & group = mesh.getElementGroup("contact_surface");
   UInt nb_degree_of_freedom = external_force->getNbComponent();
 
   for (auto && type : group.elementTypes(spatial_dimension - 1, ghost_type)) {
     const auto & element_ids = group.getElements(type, ghost_type);
-    
-    UInt nb_quad_points =
-      fem_boundary.getNbIntegrationPoints(type, ghost_type);
+
+    UInt nb_quad_points = fem_boundary.getNbIntegrationPoints(type, ghost_type);
     UInt nb_elements = element_ids.size();
-    
-    UInt nb_nodes_per_element = mesh.getNbNodesPerElement(type);        
+
+    UInt nb_nodes_per_element = mesh.getNbNodesPerElement(type);
 
     Array<Real> dual_before_integ(nb_elements * nb_quad_points,
-				  nb_degree_of_freedom, 0.);
+                                  nb_degree_of_freedom, 0.);
     Array<Real> quad_coords(nb_elements * nb_quad_points, spatial_dimension);
 
     const auto & normals_on_quad =
-      fem_boundary.getNormalsOnIntegrationPoints(type, ghost_type);
+        fem_boundary.getNormalsOnIntegrationPoints(type, ghost_type);
 
     auto normals_begin = normals_on_quad.begin(spatial_dimension);
     decltype(normals_begin) normals_iter;
     auto quad_coords_iter = quad_coords.begin(spatial_dimension);
     auto dual_iter = dual_before_integ.begin(nb_degree_of_freedom);
 
     quad_point.type = type;
 
     Element subelement;
     subelement.type = type;
     subelement.ghost_type = ghost_type;
     for (auto el : element_ids) {
       subelement.element = el;
       const auto & element_to_subelement =
-	mesh.getElementToSubelement(type)(el);
+          mesh.getElementToSubelement(type)(el);
 
       Vector<Real> outside(spatial_dimension);
       mesh.getBarycenter(subelement, outside);
 
       Vector<Real> inside(spatial_dimension);
       if (mesh.isMeshFacets()) {
-	mesh.getMeshParent().getBarycenter(element_to_subelement[0], inside);
-      }
-      else {
-	mesh.getBarycenter(element_to_subelement[0], inside);
+        mesh.getMeshParent().getBarycenter(element_to_subelement[0], inside);
+      } else {
+        mesh.getBarycenter(element_to_subelement[0], inside);
       }
 
       Vector<Real> inside_to_outside(spatial_dimension);
       inside_to_outside = outside - inside;
-      
+
       normals_iter = normals_begin + el * nb_quad_points;
-   
+
       quad_point.element = el;
       for (auto q : arange(nb_quad_points)) {
-          quad_point.num_point = q;
-	  auto ddot = inside_to_outside.dot(*normals_iter);
-	  Vector<Real> normal(*normals_iter);
-	  if (ddot < 0)
-	    normal *= -1.0;
-
-	  (*dual_iter).mul<false>(Matrix<Real>::eye(spatial_dimension, 1),
-				  normal);
-	  ++dual_iter;
-          ++quad_coords_iter;
-          ++normals_iter;
+        quad_point.num_point = q;
+        auto ddot = inside_to_outside.dot(*normals_iter);
+        Vector<Real> normal(*normals_iter);
+        if (ddot < 0)
+          normal *= -1.0;
+
+        (*dual_iter)
+            .mul<false>(Matrix<Real>::eye(spatial_dimension, 1), normal);
+        ++dual_iter;
+        ++quad_coords_iter;
+        ++normals_iter;
       }
     }
 
     Array<Real> dual_by_shapes(nb_elements * nb_quad_points,
-			       nb_degree_of_freedom * nb_nodes_per_element);
+                               nb_degree_of_freedom * nb_nodes_per_element);
 
-    fem_boundary.computeNtb(dual_before_integ, dual_by_shapes, type,
-			    ghost_type, element_ids);
+    fem_boundary.computeNtb(dual_before_integ, dual_by_shapes, type, ghost_type,
+                            element_ids);
 
     Array<Real> dual_by_shapes_integ(nb_elements, nb_degree_of_freedom *
-				     nb_nodes_per_element);
+                                                      nb_nodes_per_element);
     fem_boundary.integrate(dual_by_shapes, dual_by_shapes_integ,
-			   nb_degree_of_freedom * nb_nodes_per_element, type,
-			   ghost_type, element_ids);
+                           nb_degree_of_freedom * nb_nodes_per_element, type,
+                           ghost_type, element_ids);
 
     this->getDOFManager().assembleElementalArrayLocalArray(
-          dual_by_shapes_integ, *external_force, type, ghost_type, 1., element_ids);
+        dual_by_shapes_integ, *external_force, type, ghost_type, 1.,
+        element_ids);
   }
 
   for (auto && tuple :
-	 zip(*nodal_area,
-	     make_view(*external_force, spatial_dimension))) {
-    
+       zip(*nodal_area, make_view(*external_force, spatial_dimension))) {
+
     auto & area = std::get<0>(tuple);
     Vector<Real> force(std::get<1>(tuple));
     area = force.norm();
   }
-  
+
   this->external_force->clear();
 }
 
 /* -------------------------------------------------------------------------- */
 void ContactMechanicsModel::printself(std::ostream & stream, int indent) const {
   std::string space(indent, AKANTU_INDENT);
 
   stream << space << "Contact Mechanics Model [" << std::endl;
   stream << space << " + id                : " << id << std::endl;
   stream << space << " + spatial dimension : " << Model::spatial_dimension
          << std::endl;
   stream << space << " + fem [" << std::endl;
   getFEEngine().printself(stream, indent + 2);
   stream << space << AKANTU_INDENT << "]" << std::endl;
 
   stream << space << " + resolutions [" << std::endl;
   for (auto & resolution : resolutions) {
     resolution->printself(stream, indent + 1);
   }
   stream << space << AKANTU_INDENT << "]" << std::endl;
 
   stream << space << "]" << std::endl;
 }
 
 /* -------------------------------------------------------------------------- */
 MatrixType ContactMechanicsModel::getMatrixType(const ID & matrix_id) {
   if (matrix_id == "K")
     return _symmetric;
 
   return _mt_not_defined;
 }
 
 /* -------------------------------------------------------------------------- */
 void ContactMechanicsModel::assembleMatrix(const ID & matrix_id) {
   if (matrix_id == "K") {
     this->assembleStiffnessMatrix();
   }
 }
 
 /* -------------------------------------------------------------------------- */
 void ContactMechanicsModel::assembleStiffnessMatrix() {
   AKANTU_DEBUG_IN();
 
   AKANTU_DEBUG_INFO("Assemble the new stiffness matrix");
 
   if (!this->getDOFManager().hasMatrix("K")) {
     this->getDOFManager().getNewMatrix("K", getMatrixType("K"));
   }
 
   for (auto & resolution : resolutions) {
     resolution->assembleStiffnessMatrix(_not_ghost);
   }
 }
 
 /* -------------------------------------------------------------------------- */
 void ContactMechanicsModel::assembleLumpedMatrix(const ID & /*matrix_id*/) {
   AKANTU_TO_IMPLEMENT();
 }
 
 /* -------------------------------------------------------------------------- */
 void ContactMechanicsModel::beforeSolveStep() {
-  for (auto & resolution : resolutions)
+  for (auto & resolution : resolutions) {
     resolution->beforeSolveStep();
+  }
 }
 
 /* -------------------------------------------------------------------------- */
 void ContactMechanicsModel::afterSolveStep(bool converged) {
-  for (auto & resolution : resolutions)
+  for (auto & resolution : resolutions) {
     resolution->afterSolveStep(converged);
+  }
 }
-  
 
 /* -------------------------------------------------------------------------- */
 #ifdef AKANTU_USE_IOHELPER
 
 /* -------------------------------------------------------------------------- */
 std::shared_ptr<dumpers::Field>
 ContactMechanicsModel::createNodalFieldBool(const std::string &,
-					    const std::string &, bool) {
-
+                                            const std::string &, bool) {
   return nullptr;
 }
 
-  
 /* -------------------------------------------------------------------------- */
 std::shared_ptr<dumpers::Field>
 ContactMechanicsModel::createNodalFieldReal(const std::string & field_name,
                                             const std::string & group_name,
                                             bool padding_flag) {
-
   std::map<std::string, Array<Real> *> real_nodal_fields;
-  real_nodal_fields["contact_force"]    = this->internal_force.get();
-  real_nodal_fields["normal_force"]     = this->normal_force.get();
+  real_nodal_fields["contact_force"] = this->internal_force.get();
+  real_nodal_fields["normal_force"] = this->normal_force.get();
   real_nodal_fields["tangential_force"] = this->tangential_force.get();
-  real_nodal_fields["blocked_dofs"]     = this->blocked_dofs.get();
-  real_nodal_fields["normals"]          = this->normals.get();
-  real_nodal_fields["tangents"]         = this->tangents.get();
-  real_nodal_fields["gaps"]             = this->gaps.get();
-  real_nodal_fields["areas"]            = this->nodal_area.get();
-  real_nodal_fields["contact_state"]    = this->contact_state.get();
+  real_nodal_fields["blocked_dofs"] = this->blocked_dofs.get();
+  real_nodal_fields["normals"] = this->normals.get();
+  real_nodal_fields["tangents"] = this->tangents.get();
+  real_nodal_fields["gaps"] = this->gaps.get();
+  real_nodal_fields["areas"] = this->nodal_area.get();
   real_nodal_fields["tangential_traction"] = this->tangential_tractions.get();
-  
+
   std::shared_ptr<dumpers::Field> field;
-  if (padding_flag) 
-    field = this->mesh.createNodalField(real_nodal_fields[field_name],
-                                       group_name, 3);
-  else
+  if (padding_flag) {
     field = this->mesh.createNodalField(real_nodal_fields[field_name],
-                                       group_name); 
+                                        group_name, 3);
+  } else {
+    field =
+        this->mesh.createNodalField(real_nodal_fields[field_name], group_name);
+  }
+  return field;
+}
+
+/* -------------------------------------------------------------------------- */
+std::shared_ptr<dumpers::Field>
+ContactMechanicsModel::createNodalFieldUInt(const std::string & field_name,
+                                            const std::string & group_name,
+                                            bool /*padding_flag*/) {
+  std::shared_ptr<dumpers::Field> field;
+  if (field_name == "contact_state") {
+    auto && func =
+        std::make_unique<dumpers::ComputeUIntFromEnum<ContactState>>();
+    field = mesh.createNodalField(this->contact_state.get(), group_name);
+    field =
+        dumpers::FieldComputeProxy::createFieldCompute(field, std::move(func));
+  }
   return field;
 }
 
 #else
 /* -------------------------------------------------------------------------- */
 std::shared_ptr<dumpers::Field>
 ContactMechanicsModel::createNodalFieldBool(const std::string &,
-					    const std::string &, bool) {
-
+                                            const std::string &, bool) {
   return nullptr;
 }
 
-
 /* -------------------------------------------------------------------------- */
 std::shared_ptr<dumpers::Field>
-ContactMechanicsModel::createNodalFieldReal(const std::string & ,
-                                            const std::string & , bool) {
+ContactMechanicsModel::createNodalFieldReal(const std::string &,
+                                            const std::string &, bool) {
   return nullptr;
 }
-
 #endif
 
 /* -------------------------------------------------------------------------- */
 void ContactMechanicsModel::dump(const std::string & dumper_name) {
   mesh.dump(dumper_name);
 }
 
 /* -------------------------------------------------------------------------- */
 void ContactMechanicsModel::dump(const std::string & dumper_name, UInt step) {
   mesh.dump(dumper_name, step);
 }
 
 /* ------------------------------------------------------------------------- */
 void ContactMechanicsModel::dump(const std::string & dumper_name, Real time,
                                  UInt step) {
   mesh.dump(dumper_name, time, step);
 }
 
 /* -------------------------------------------------------------------------- */
 void ContactMechanicsModel::dump() { mesh.dump(); }
 
 /* -------------------------------------------------------------------------- */
 void ContactMechanicsModel::dump(UInt step) { mesh.dump(step); }
 
 /* -------------------------------------------------------------------------- */
 void ContactMechanicsModel::dump(Real time, UInt step) {
   mesh.dump(time, step);
 }
 
 /* -------------------------------------------------------------------------- */
 UInt ContactMechanicsModel::getNbData(
     const Array<Element> & elements, const SynchronizationTag & /*tag*/) const {
   AKANTU_DEBUG_IN();
 
   UInt size = 0;
   UInt nb_nodes_per_element = 0;
 
   for (const Element & el : elements) {
     nb_nodes_per_element += Mesh::getNbNodesPerElement(el.type);
   }
 
   AKANTU_DEBUG_OUT();
   return size;
 }
 
 /* -------------------------------------------------------------------------- */
 void ContactMechanicsModel::packData(CommunicationBuffer & /*buffer*/,
                                      const Array<Element> & /*elements*/,
                                      const SynchronizationTag & /*tag*/) const {
   AKANTU_DEBUG_IN();
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void ContactMechanicsModel::unpackData(CommunicationBuffer & /*buffer*/,
                                        const Array<Element> & /*elements*/,
                                        const SynchronizationTag & /*tag*/) {
   AKANTU_DEBUG_IN();
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 UInt ContactMechanicsModel::getNbData(
     const Array<UInt> & dofs, const SynchronizationTag & /*tag*/) const {
   AKANTU_DEBUG_IN();
 
   UInt size = 0;
 
   AKANTU_DEBUG_OUT();
   return size * dofs.size();
 }
 
 /* -------------------------------------------------------------------------- */
 void ContactMechanicsModel::packData(CommunicationBuffer & /*buffer*/,
                                      const Array<UInt> & /*dofs*/,
                                      const SynchronizationTag & /*tag*/) const {
   AKANTU_DEBUG_IN();
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void ContactMechanicsModel::unpackData(CommunicationBuffer & /*buffer*/,
                                        const Array<UInt> & /*dofs*/,
                                        const SynchronizationTag & /*tag*/) {
   AKANTU_DEBUG_IN();
 
   AKANTU_DEBUG_OUT();
 }
 
 } // namespace akantu
diff --git a/src/model/contact_mechanics/contact_mechanics_model.hh b/src/model/contact_mechanics/contact_mechanics_model.hh
index b51a8cdb4..d0efb2b5d 100644
--- a/src/model/contact_mechanics/contact_mechanics_model.hh
+++ b/src/model/contact_mechanics/contact_mechanics_model.hh
@@ -1,379 +1,384 @@
 /**
  * @file   contact_mechanics_model.hh
  *
  * @author Mohit Pundir <mohit.pundir@epfl.ch>
  *
  * @date creation: Tue Jul 27 2010
  * @date last modification: Wed Feb 21 2018
  *
  * @brief  Model of Contact Mechanics
  *
  * @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 "boundary_condition.hh"
 #include "contact_detector.hh"
 #include "data_accessor.hh"
 #include "fe_engine.hh"
 #include "model.hh"
 /* -------------------------------------------------------------------------- */
 
 #ifndef __AKANTU_CONTACT_MECHANICS_MODEL_HH__
 #define __AKANTU_CONTACT_MECHANICS_MODEL_HH__
 
 namespace akantu {
 class Resolution;
 template <ElementKind kind, class IntegrationOrderFunctor>
 class IntegratorGauss;
 template <ElementKind kind> class ShapeLagrange;
 } // namespace akantu
 
 /* -------------------------------------------------------------------------- */
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 class ContactMechanicsModel : public Model,
                               public DataAccessor<Element>,
                               public DataAccessor<UInt>,
                               public BoundaryCondition<ContactMechanicsModel> {
 
   /* ------------------------------------------------------------------------ */
   /* Constructors/Destructors                                                 */
   /* ------------------------------------------------------------------------ */
 
   using MyFEEngineType = FEEngineTemplate<IntegratorGauss, ShapeLagrange>;
 
 public:
   ContactMechanicsModel(
       Mesh & mesh, UInt spatial_dimension = _all_dimensions,
-      const ID & id = "contact_mechanics_model", std::shared_ptr<DOFManager> dof_manager = nullptr,
+      const ID & id = "contact_mechanics_model",
+      std::shared_ptr<DOFManager> dof_manager = nullptr,
       const ModelType model_type = ModelType::_contact_mechanics_model);
 
   ~ContactMechanicsModel() override;
 
   /* ------------------------------------------------------------------------ */
   /* Methods                                                                  */
   /* ------------------------------------------------------------------------ */
 protected:
   /// initialize completely the model
   void initFullImpl(const ModelOptions & options) override;
 
   /// allocate all vectors
   void initSolver(TimeStepSolverType, NonLinearSolverType) override;
 
   /// initialize all internal arrays for resolutions
   void initResolutions();
 
   /// initialize the modelType
   void initModel() override;
 
   /// call back for the solver, computes the force residual
   void assembleResidual() override;
 
   /// get the type of matrix needed
   MatrixType getMatrixType(const ID & matrix_id) override;
 
   /// callback for the solver, this assembles different matrices
   void assembleMatrix(const ID & matrix_id) override;
 
   /// callback for the solver, this assembles the stiffness matrix
   void assembleLumpedMatrix(const ID & matrix_id) override;
 
   /// get some default values for derived classes
   std::tuple<ID, TimeStepSolverType>
   getDefaultSolverID(const AnalysisMethod & method) override;
 
   ModelSolverOptions
   getDefaultSolverOptions(const TimeStepSolverType & type) const;
 
   /// callback for the solver, this is called at beginning of solve
   void beforeSolveStep() override;
 
   /// callback for the solver, this is called at end of solve
   void afterSolveStep(bool converted = true) override;
 
   /// function to print the containt of the class
   void printself(std::ostream & stream, int indent = 0) const override;
 
   /* ------------------------------------------------------------------------ */
   /* Contact Detection                                                        */
   /* ------------------------------------------------------------------------ */
 public:
   void search();
 
   void computeNodalAreas(GhostType ghost_type = _not_ghost);
 
   /* ------------------------------------------------------------------------ */
   /* Contact Resolution                                                       */
   /* ------------------------------------------------------------------------ */
 public:
   /// register an empty contact resolution of a given type
   Resolution & registerNewResolution(const ID & res_name, const ID & res_type,
                                      const ID & opt_param);
 
 protected:
   /// register a resolution in the dynamic database
   Resolution & registerNewResolution(const ParserSection & res_section);
 
   /// read the resolution files to instantiate all the resolutions
   void instantiateResolutions();
 
   /// save the parameters from previous state
   void savePreviousState();
 
   /* ------------------------------------------------------------------------ */
   /* Solver Interface                                                         */
   /* ------------------------------------------------------------------------ */
 public:
   /// assembles the contact stiffness matrix
   virtual void assembleStiffnessMatrix();
 
   /// assembles the contant internal forces
   virtual void assembleInternalForces();
 
   /* ------------------------------------------------------------------------ */
   /* Accessors                                                                */
   /* ------------------------------------------------------------------------ */
 public:
   FEEngine & getFEEngineBoundary(const ID & name = "") override;
 
   /* ------------------------------------------------------------------------ */
   /* Dumpable interface                                                       */
   /* ------------------------------------------------------------------------ */
 public:
   std::shared_ptr<dumpers::Field>
   createNodalFieldReal(const std::string & field_name,
                        const std::string & group_name,
                        bool padding_flag) override;
 
+  std::shared_ptr<dumpers::Field>
+  createNodalFieldUInt(const std::string & field_name,
+                       const std::string & group_name,
+                       bool padding_flag) override;
+
   std::shared_ptr<dumpers::Field>
   createNodalFieldBool(const std::string & field_name,
                        const std::string & group_name,
                        bool padding_flag) override;
   void dump() override;
 
   virtual void dump(UInt step);
 
   virtual void dump(Real time, UInt step);
 
   virtual void dump(const std::string & dumper_name);
 
   virtual void dump(const std::string & dumper_name, UInt step);
 
   virtual void dump(const std::string & dumper_name, Real time, UInt step);
 
   /* ------------------------------------------------------------------------ */
   /* 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;
 
   UInt getNbData(const Array<UInt> & dofs,
                  const SynchronizationTag & tag) const override;
 
   void packData(CommunicationBuffer & buffer, const Array<UInt> & dofs,
                 const SynchronizationTag & tag) const override;
 
   void unpackData(CommunicationBuffer & buffer, const Array<UInt> & dofs,
                   const SynchronizationTag & tag) override;
 
 protected:
   /// contact detection class
   friend class ContactDetector;
 
   /// contact resolution class
   friend class Resolution;
 
   /* ------------------------------------------------------------------------ */
   /* Accessors                                                                */
   /* ------------------------------------------------------------------------ */
 public:
   /// return the dimension of the system space
   AKANTU_GET_MACRO(SpatialDimension, Model::spatial_dimension, UInt);
 
   /// get the ContactMechanicsModel::displacement vector
   AKANTU_GET_MACRO(Displacement, *displacement, Array<Real> &);
 
   /// get  the ContactMechanicsModel::increment  vector \warn  only  consistent
   /// if ContactMechanicsModel::setIncrementFlagOn has been called before
   AKANTU_GET_MACRO(Increment, *displacement_increment, Array<Real> &);
 
   /// get the ContactMechanics::internal_force vector (internal forces)
   AKANTU_GET_MACRO(InternalForce, *internal_force, Array<Real> &);
 
   /// get the ContactMechanicsModel::external_force vector (external forces)
   AKANTU_GET_MACRO(ExternalForce, *external_force, Array<Real> &);
 
   /// get the ContactMechanics::normal_force vector (normal forces)
   AKANTU_GET_MACRO(NormalForce, *normal_force, Array<Real> &);
 
   /// get the ContactMechanics::tangential_force vector (friction forces)
   AKANTU_GET_MACRO(TangentialForce, *tangential_force, Array<Real> &);
-  
+
   /// get the ContactMechanics::traction vector (friction traction)
   AKANTU_GET_MACRO(TangentialTractions, *tangential_tractions, Array<Real> &);
 
   /// get the ContactMechanics::previous_tangential_tractions vector
   AKANTU_GET_MACRO(PreviousTangentialTractions, *previous_tangential_tractions,
-		   Array<Real> &);
+                   Array<Real> &);
 
   /// get the ContactMechanicsModel::force vector (external forces)
   Array<Real> & getForce() {
     AKANTU_DEBUG_WARNING("getForce was maintained for backward compatibility, "
                          "use getExternalForce instead");
     return *external_force;
   }
 
   /// get the ContactMechanics::blocked_dofs vector
   AKANTU_GET_MACRO(BlockedDOFs, *blocked_dofs, Array<Real> &);
 
   /// get the ContactMechanics::gaps (contact gaps)
   AKANTU_GET_MACRO(Gaps, *gaps, Array<Real> &);
 
   /// get the ContactMechanics::normals (normals on slave nodes)
   AKANTU_GET_MACRO(Normals, *normals, Array<Real> &);
 
   /// get the ContactMechanics::tangents (tangents on slave nodes)
   AKANTU_GET_MACRO(Tangents, *tangents, Array<Real> &);
 
   /// get the ContactMechanics::previous_tangents (tangents on slave nodes)
   AKANTU_GET_MACRO(PreviousTangents, *previous_tangents, Array<Real> &);
-  
+
   /// get the ContactMechanics::areas (nodal areas)
   AKANTU_GET_MACRO(NodalArea, *nodal_area, Array<Real> &);
 
   /// get the ContactMechanics::previous_projections (previous_projections)
   AKANTU_GET_MACRO(PreviousProjections, *previous_projections, Array<Real> &);
 
   /// get the ContactMechanics::projections (projections)
   AKANTU_GET_MACRO(Projections, *projections, Array<Real> &);
-  
+
   /// get the ContactMechanics::contact_state vector (no_contact/stick/slip
   /// state)
-  AKANTU_GET_MACRO(ContactState, *contact_state, Array<Real> &);
+  AKANTU_GET_MACRO(ContactState, *contact_state, Array<ContactState> &);
 
   /// get the ContactMechanics::previous_master_elements
-  AKANTU_GET_MACRO(PreviousMasterElements, *previous_master_elements, Array<Element> &);
-  
+  AKANTU_GET_MACRO(PreviousMasterElements, *previous_master_elements,
+                   Array<Element> &);
+
   /// get contact detector
   AKANTU_GET_MACRO_NOT_CONST(ContactDetector, *detector, ContactDetector &);
 
   /// get the contact elements
   inline Array<ContactElement> & getContactElements() {
     return contact_elements;
   }
 
   /// get the current positions of the nodes
-  inline Array<Real> & getPositions() {
-    return detector->getPositions();
-  }
+  inline Array<Real> & getPositions() { return detector->getPositions(); }
 
   /* ------------------------------------------------------------------------ */
   /* Class Members                                                            */
   /* ------------------------------------------------------------------------ */
 private:
   /// tells if the resolutions are instantiated
   bool are_resolutions_instantiated;
 
   /// displacements array
   std::unique_ptr<Array<Real>> displacement;
 
   /// increment of displacement
   std::unique_ptr<Array<Real>> displacement_increment;
 
   /// contact forces array
   std::unique_ptr<Array<Real>> internal_force;
 
   /// external forces array
   std::unique_ptr<Array<Real>> external_force;
 
   /// normal force array
   std::unique_ptr<Array<Real>> normal_force;
 
   /// friction force array
   std::unique_ptr<Array<Real>> tangential_force;
 
   /// friction traction array
   std::unique_ptr<Array<Real>> tangential_tractions;
-  
+
   /// previous friction traction array
   std::unique_ptr<Array<Real>> previous_tangential_tractions;
-  
+
   /// boundary vector
   std::unique_ptr<Array<Real>> blocked_dofs;
 
   /// array to store gap between slave and master
   std::unique_ptr<Array<Real>> gaps;
- 
+
   /// array to store normals from master to slave
   std::unique_ptr<Array<Real>> normals;
 
   /// array to store tangents on the master element
   std::unique_ptr<Array<Real>> tangents;
 
   /// array to store previous tangents on the master element
   std::unique_ptr<Array<Real>> previous_tangents;
-  
+
   /// array to store nodal areas
   std::unique_ptr<Array<Real>> nodal_area;
 
   /// array to store stick/slip state :
-  std::unique_ptr<Array<Real>> contact_state;
+  std::unique_ptr<Array<ContactState>> contact_state;
 
   /// array to store previous projections in covariant basis
   std::unique_ptr<Array<Real>> previous_projections;
-  
+
   // array to store projections in covariant basis
   std::unique_ptr<Array<Real>> projections;
-  
+
   /// contact detection
   std::unique_ptr<ContactDetector> detector;
 
   /// list of contact resolutions
   std::vector<std::unique_ptr<Resolution>> resolutions;
 
   /// mapping between resolution name and resolution internal id
   std::map<std::string, UInt> resolutions_names_to_id;
 
   /// array to store contact elements
   Array<ContactElement> contact_elements;
 
   /// array to store previous master elements
   std::unique_ptr<Array<Element>> previous_master_elements;
 };
 
 } // namespace akantu
 
 /* ------------------------------------------------------------------------ */
 /* inline functions                                                         */
 /* ------------------------------------------------------------------------ */
 #include "parser.hh"
 #include "resolution.hh"
 /* ------------------------------------------------------------------------ */
 
 #endif /* __AKANTU_CONTACT_MECHANICS_MODEL_HH__ */
diff --git a/src/model/contact_mechanics/resolutions/resolution_penalty.cc b/src/model/contact_mechanics/resolutions/resolution_penalty.cc
index 2c349c683..0c952233a 100644
--- a/src/model/contact_mechanics/resolutions/resolution_penalty.cc
+++ b/src/model/contact_mechanics/resolutions/resolution_penalty.cc
@@ -1,839 +1,839 @@
 /**
  * @file   resolution_penalty.cc
  *
  * @author Mohit Pundir <mohit.pundir@epfl.ch>
  *
  * @date creation: Mon Jan 7 2019
  * @date last modification: Mon Jan 7 2019
  *
  * @brief  Specialization of the resolution class for the penalty method
  *
  * @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 "resolution_penalty.hh"
 #include "element_class_helper.hh"
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 ResolutionPenalty::ResolutionPenalty(ContactMechanicsModel & model,
                                      const ID & id)
     : Resolution(model, id) {
   AKANTU_DEBUG_IN();
   this->initialize();
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void ResolutionPenalty::initialize() {
   this->registerParam("epsilon_n", epsilon_n, Real(0.),
                       _pat_parsable | _pat_modifiable,
                       "Normal penalty parameter");
   this->registerParam("epsilon_t", epsilon_t, Real(0.),
                       _pat_parsable | _pat_modifiable,
                       "Tangential penalty parameter");
 }
 
 /* -------------------------------------------------------------------------- */
 Real ResolutionPenalty::computeNormalTraction(Real & gap) {
   return epsilon_n * macaulay(gap);
 }
 
 /* -------------------------------------------------------------------------- */
 void ResolutionPenalty::computeNormalForce(const ContactElement & element,
                                            Vector<Real> & force) {
 
   force.zero();
 
   auto & gaps = model.getGaps();
   auto & projections = model.getProjections();
   auto & normals = model.getNormals();
 
   auto surface_dimension = spatial_dimension - 1;
 
   Real gap(gaps.begin()[element.slave]);
   Vector<Real> normal(normals.begin(spatial_dimension)[element.slave]);
   Vector<Real> projection(projections.begin(surface_dimension)[element.slave]);
 
   auto & nodal_area = const_cast<Array<Real> &>(model.getNodalArea());
 
   // compute normal traction
   Real p_n = computeNormalTraction(gap);
   p_n *= nodal_area[element.slave];
 
   UInt nb_nodes_per_contact = element.getNbNodes();
   Matrix<Real> shape_matric(spatial_dimension,
                             spatial_dimension * nb_nodes_per_contact);
   ResolutionUtils::computeShapeFunctionMatric(element, projection,
                                               shape_matric);
 
   force.mul<true>(shape_matric, normal, p_n);
 }
 
 /* -------------------------------------------------------------------------- */
 void ResolutionPenalty::computeTangentialForce(const ContactElement & element,
                                                Vector<Real> & force) {
 
   if (mu == 0)
     return;
 
   force.zero();
 
   UInt surface_dimension = spatial_dimension - 1;
 
   // compute covariant basis
   auto & projections = model.getProjections();
   Vector<Real> projection(projections.begin(surface_dimension)[element.slave]);
 
   auto & normals = model.getNormals();
   Vector<Real> normal(normals.begin(spatial_dimension)[element.slave]);
 
   auto & tangents = model.getTangents();
   Matrix<Real> covariant_basis(
       tangents.begin(surface_dimension, spatial_dimension)[element.slave]);
 
   // check for no-contact to contact condition
   // need a better way to check if new node added is not presnt in the
   // previous master elemets
   auto & previous_master_elements = model.getPreviousMasterElements();
   if (element.slave >= previous_master_elements.size())
     return;
 
   auto & previous_element = previous_master_elements[element.slave];
   if (previous_element.type == _not_defined)
     return;
 
   // compute tangential traction using return map algorithm
   auto & tangential_tractions = model.getTangentialTractions();
   Vector<Real> tangential_traction(
       tangential_tractions.begin(surface_dimension)[element.slave]);
   this->computeTangentialTraction(element, covariant_basis,
                                   tangential_traction);
 
   UInt nb_nodes_per_contact = element.getNbNodes();
   Matrix<Real> shape_matric(spatial_dimension,
                             spatial_dimension * nb_nodes_per_contact);
   ResolutionUtils::computeShapeFunctionMatric(element, projection,
                                               shape_matric);
 
   auto contravariant_metric_tensor =
       GeometryUtils::contravariantMetricTensor(covariant_basis);
 
   auto & nodal_area = const_cast<Array<Real> &>(model.getNodalArea());
 
   for (auto && values1 : enumerate(covariant_basis.transpose())) {
     auto & alpha = std::get<0>(values1);
     auto & tangent_alpha = std::get<1>(values1);
     for (auto && values2 : enumerate(tangential_traction)) {
       auto & beta = std::get<0>(values2);
       auto & traction_beta = std::get<1>(values2);
       Vector<Real> tmp(force.size());
       tmp.mul<true>(shape_matric, tangent_alpha, traction_beta);
       tmp *=
           contravariant_metric_tensor(alpha, beta) * nodal_area[element.slave];
       force += tmp;
     }
   }
 }
 
 /* -------------------------------------------------------------------------- */
 void ResolutionPenalty::computeTangentialTraction(
     const ContactElement & element, const Matrix<Real> & covariant_basis,
     Vector<Real> & traction_tangential) {
 
   UInt surface_dimension = spatial_dimension - 1;
 
   auto & gaps = model.getGaps();
   auto & gap = gaps.begin()[element.slave];
 
   // Return map algorithm is employed
   // compute trial traction
   Vector<Real> traction_trial(surface_dimension);
   this->computeTrialTangentialTraction(element, covariant_basis,
                                        traction_trial);
 
   // compute norm of trial traction
   Real traction_trial_norm = 0;
   auto contravariant_metric_tensor =
       GeometryUtils::contravariantMetricTensor(covariant_basis);
   for (auto i : arange(surface_dimension)) {
     for (auto j : arange(surface_dimension)) {
       traction_trial_norm += traction_trial[i] * traction_trial[j] *
                              contravariant_metric_tensor(i, j);
     }
   }
   traction_trial_norm = sqrt(traction_trial_norm);
 
   // check stick or slip condition
   auto & contact_state = model.getContactState();
   auto & state = contact_state.begin()[element.slave];
 
   Real p_n = computeNormalTraction(gap);
-  bool stick = (traction_trial_norm <= mu * p_n) ? true : false;
+  bool stick = (traction_trial_norm <= mu * p_n);
 
   if (stick) {
     state = ContactState::_stick;
     computeStickTangentialTraction(element, traction_trial,
                                    traction_tangential);
   } else {
     state = ContactState::_slip;
     computeSlipTangentialTraction(element, covariant_basis, traction_trial,
                                   traction_tangential);
   }
 }
 
 /* -------------------------------------------------------------------------- */
 void ResolutionPenalty::computeTrialTangentialTraction(
     const ContactElement & element, const Matrix<Real> & covariant_basis,
     Vector<Real> & traction) {
 
   UInt surface_dimension = spatial_dimension - 1;
 
   auto & projections = model.getProjections();
   Vector<Real> current_projection(
       projections.begin(surface_dimension)[element.slave]);
 
   auto & previous_projections = model.getPreviousProjections();
   Vector<Real> previous_projection(
       previous_projections.begin(surface_dimension)[element.slave]);
 
   // method from Laursen et. al.
   /*auto covariant_metric_tensor =
   GeometryUtils::covariantMetricTensor(covariant_basis); auto
   increment_projection = current_projection - previous_projection;
 
   traction.mul<false>(covariant_metric_tensor, increment_projection, epsilon_t);
 
   auto & previous_tangential_tractions = model.getPreviousTangentialTractions();
   Vector<Real>
   previous_traction(previous_tangential_tractions.begin(surface_dimension)[element.slave]);
   traction = previous_traction + traction;*/
 
   // method from Schweizerhof
   auto covariant_metric_tensor =
       GeometryUtils::covariantMetricTensor(covariant_basis);
 
   auto & previous_tangential_tractions = model.getPreviousTangentialTractions();
   Vector<Real> previous_traction(
       previous_tangential_tractions.begin(surface_dimension)[element.slave]);
 
   auto & previous_tangents = model.getPreviousTangents();
   Matrix<Real> previous_covariant_basis(previous_tangents.begin(
       surface_dimension, spatial_dimension)[element.slave]);
   auto previous_contravariant_metric_tensor =
       GeometryUtils::contravariantMetricTensor(previous_covariant_basis);
 
   auto current_tangent = covariant_basis.transpose();
   auto previous_tangent = previous_covariant_basis.transpose();
 
   for (auto alpha : arange(surface_dimension)) {
     Vector<Real> tangent_alpha(current_tangent(alpha));
     for (auto gamma : arange(surface_dimension)) {
       for (auto beta : arange(surface_dimension)) {
         Vector<Real> tangent_beta(previous_tangent(beta));
         auto t_alpha_t_beta = tangent_beta.dot(tangent_alpha);
         traction[alpha] += previous_traction[gamma] *
                            previous_contravariant_metric_tensor(gamma, beta) *
                            t_alpha_t_beta;
       }
     }
   }
 
   auto & previous_master_elements = model.getPreviousMasterElements();
   auto & previous_element = previous_master_elements[element.slave];
 
   Vector<Real> previous_real_projection(spatial_dimension);
   GeometryUtils::realProjection(
       model.getMesh(), model.getContactDetector().getPositions(),
       previous_element, previous_projection, previous_real_projection);
 
   Vector<Real> current_real_projection(spatial_dimension);
   GeometryUtils::realProjection(
       model.getMesh(), model.getContactDetector().getPositions(),
       element.master, current_projection, current_real_projection);
 
   auto increment_real = current_real_projection - previous_real_projection;
   Vector<Real> increment_xi(surface_dimension);
 
   auto contravariant_metric_tensor =
       GeometryUtils::contravariantMetricTensor(covariant_basis);
 
   // increment in natural coordinate
   for (auto beta : arange(surface_dimension)) {
     for (auto gamma : arange(surface_dimension)) {
       auto temp = increment_real.dot(current_tangent(gamma));
       temp *= contravariant_metric_tensor(beta, gamma);
       increment_xi[beta] += temp;
     }
   }
 
   Vector<Real> temp(surface_dimension);
   temp.mul<false>(covariant_metric_tensor, increment_xi, epsilon_t);
 
   traction -= temp;
 }
 
 /* -------------------------------------------------------------------------- */
 void ResolutionPenalty::computeStickTangentialTraction(
     const ContactElement & /*element*/, Vector<Real> & traction_trial,
     Vector<Real> & traction_tangential) {
   traction_tangential = traction_trial;
 }
 
 /* -------------------------------------------------------------------------- */
 void ResolutionPenalty::computeSlipTangentialTraction(
     const ContactElement & element, const Matrix<Real> & covariant_basis,
     Vector<Real> & traction_trial, Vector<Real> & traction_tangential) {
   UInt surface_dimension = spatial_dimension - 1;
 
   auto & gaps = model.getGaps();
   auto & gap = gaps.begin()[element.slave];
 
   // compute norm of trial traction
   Real traction_trial_norm = 0;
   auto contravariant_metric_tensor =
       GeometryUtils::contravariantMetricTensor(covariant_basis);
 
   for (auto alpha : arange(surface_dimension)) {
     for (auto beta : arange(surface_dimension)) {
       traction_trial_norm += traction_trial[alpha] * traction_trial[beta] *
                              contravariant_metric_tensor(alpha, beta);
     }
   }
   traction_trial_norm = sqrt(traction_trial_norm);
 
   auto slip_direction = traction_trial;
   slip_direction /= traction_trial_norm;
 
   Real p_n = computeNormalTraction(gap);
   traction_tangential = slip_direction;
   traction_tangential *= mu * p_n;
 }
 
 /* -------------------------------------------------------------------------- */
 void ResolutionPenalty::computeNormalModuli(const ContactElement & element,
                                             Matrix<Real> & stiffness) {
 
   auto surface_dimension = spatial_dimension - 1;
 
   auto & gaps = model.getGaps();
   Real gap(gaps.begin()[element.slave]);
 
   auto & projections = model.getProjections();
   Vector<Real> projection(projections.begin(surface_dimension)[element.slave]);
 
   auto & nodal_areas = model.getNodalArea();
   auto & nodal_area = nodal_areas.begin()[element.slave];
 
   auto & normals = model.getNormals();
   Vector<Real> normal(normals.begin(spatial_dimension)[element.slave]);
 
   // method from Schweizerhof and A. Konyukhov, K. Schweizerhof
   // DOI 10.1007/s00466-004-0616-7 and DOI 10.1007/s00466-003-0515-3
 
   // construct A matrix
   const ElementType & type = element.master.type;
   auto && shapes = ElementClassHelper<_ek_regular>::getN(projection, type);
 
   UInt nb_nodes_per_contact = element.getNbNodes();
   Matrix<Real> A(spatial_dimension, spatial_dimension * nb_nodes_per_contact);
 
   for (auto i : arange(nb_nodes_per_contact)) {
     for (auto j : arange(spatial_dimension)) {
       if (i == 0) {
         A(j, i * spatial_dimension + j) = 1;
         continue;
       }
       A(j, i * spatial_dimension + j) = -shapes[i - 1];
     }
   }
 
   // construct the main part of normal matrix
   Matrix<Real> k_main(nb_nodes_per_contact * spatial_dimension,
                       nb_nodes_per_contact * spatial_dimension);
 
   Matrix<Real> n_outer_n(spatial_dimension, spatial_dimension);
   Matrix<Real> mat_n(normal.storage(), normal.size(), 1.);
   n_outer_n.mul<false, true>(mat_n, mat_n);
 
   Matrix<Real> tmp(spatial_dimension, spatial_dimension * nb_nodes_per_contact);
   tmp.mul<false, false>(n_outer_n, A);
 
   k_main.mul<true, false>(A, tmp);
   k_main *= epsilon_n * heaviside(gap) * nodal_area;
 
   // construct the rotational part of the normal matrix
   auto & tangents = model.getTangents();
   Matrix<Real> covariant_basis(
       tangents.begin(surface_dimension, spatial_dimension)[element.slave]);
 
   auto contravariant_metric_tensor =
       GeometryUtils::contravariantMetricTensor(covariant_basis);
 
   // computing shape derivatives
   auto && shape_derivatives =
       ElementClassHelper<_ek_regular>::getDNDS(projection, type);
 
   // consists of 2 rotational parts
   Matrix<Real> k_rot1(nb_nodes_per_contact * spatial_dimension,
                       nb_nodes_per_contact * spatial_dimension);
   Matrix<Real> k_rot2(nb_nodes_per_contact * spatial_dimension,
                       nb_nodes_per_contact * spatial_dimension);
   Matrix<Real> Aj(spatial_dimension, spatial_dimension * nb_nodes_per_contact);
 
   auto construct_Aj = [&](auto && dnds) {
     for (auto i : arange(nb_nodes_per_contact)) {
       for (auto j : arange(spatial_dimension)) {
         if (i == 0) {
           Aj(j, i * spatial_dimension + j) = 0;
           continue;
         }
         Aj(j, i * spatial_dimension + j) = dnds(i - 1);
       }
     }
   };
 
   for (auto && values1 : enumerate(covariant_basis.transpose())) {
     auto & alpha = std::get<0>(values1);
     auto & tangent = std::get<1>(values1);
 
     Matrix<Real> n_outer_t(spatial_dimension, spatial_dimension);
     Matrix<Real> mat_t(tangent.storage(), tangent.size(), 1.);
     n_outer_t.mul<false, true>(mat_n, mat_t);
 
     Matrix<Real> t_outer_n(spatial_dimension, spatial_dimension);
     t_outer_n.mul<false, true>(mat_t, mat_n);
 
     for (auto && values2 : enumerate(shape_derivatives.transpose())) {
       auto & beta = std::get<0>(values2);
       auto & dnds = std::get<1>(values2);
       // construct Aj from shape function wrt to jth natural
       // coordinate
       construct_Aj(dnds);
 
       Matrix<Real> tmp(spatial_dimension,
                        spatial_dimension * nb_nodes_per_contact);
       Matrix<Real> tmp1(nb_nodes_per_contact * spatial_dimension,
                         spatial_dimension * nb_nodes_per_contact);
       tmp.mul<false, false>(n_outer_t, A);
       tmp1.mul<true, false>(Aj, tmp);
       tmp1 *= contravariant_metric_tensor(alpha, beta);
       k_rot1 += tmp1;
 
       tmp.mul<false, false>(t_outer_n, Aj);
       tmp1.mul<true, false>(A, tmp);
       tmp1 *= contravariant_metric_tensor(alpha, beta);
       k_rot2 += tmp1;
     }
   }
 
   k_rot1 *= -epsilon_n * heaviside(gap) * gap * nodal_area;
   k_rot2 *= -epsilon_n * heaviside(gap) * gap * nodal_area;
 
   stiffness += k_main + k_rot1 + k_rot2;
 }
 
 /* -------------------------------------------------------------------------- */
 void ResolutionPenalty::computeTangentialModuli(const ContactElement & element,
                                                 Matrix<Real> & stiffness) {
-
-  if (mu == 0)
+  if (mu == 0) {
     return;
+  }
 
   stiffness.zero();
 
   auto & contact_state = model.getContactState();
-  UInt state = contact_state.begin()[element.slave];
+  auto state = contact_state.begin()[element.slave];
 
   switch (state) {
   case ContactState::_stick: {
     computeStickModuli(element, stiffness);
     break;
   }
   case ContactState::_slip: {
     computeSlipModuli(element, stiffness);
     break;
   }
   default:
     break;
   }
 }
 
 /* -------------------------------------------------------------------------- */
 void ResolutionPenalty::computeStickModuli(const ContactElement & element,
                                            Matrix<Real> & stiffness) {
 
   auto surface_dimension = spatial_dimension - 1;
 
   auto & projections = model.getProjections();
   Vector<Real> projection(projections.begin(surface_dimension)[element.slave]);
 
   auto & nodal_areas = model.getNodalArea();
   auto & nodal_area = nodal_areas.begin()[element.slave];
 
   // method from Schweizerhof and A. Konyukhov, K. Schweizerhof
   // DOI 10.1007/s00466-004-0616-7 and DOI 10.1007/s00466-003-0515-3
 
   // construct A matrix
   const ElementType & type = element.master.type;
   auto && shapes = ElementClassHelper<_ek_regular>::getN(projection, type);
 
   UInt nb_nodes_per_contact = element.getNbNodes();
   Matrix<Real> A(spatial_dimension, spatial_dimension * nb_nodes_per_contact);
 
   for (auto i : arange(nb_nodes_per_contact)) {
     for (auto j : arange(spatial_dimension)) {
       if (i == 0) {
         A(j, i * spatial_dimension + j) = 1;
         continue;
       }
       A(j, i * spatial_dimension + j) = -shapes[i - 1];
     }
   }
 
   // computing shape derivatives
   auto && shape_derivatives =
       ElementClassHelper<_ek_regular>::getDNDS(projection, type);
 
   Matrix<Real> Aj(spatial_dimension, spatial_dimension * nb_nodes_per_contact);
 
   auto construct_Aj = [&](auto && dnds) {
     for (auto i : arange(nb_nodes_per_contact)) {
       for (auto j : arange(spatial_dimension)) {
         if (i == 0) {
           Aj(j, i * spatial_dimension + j) = 0;
           continue;
         }
         Aj(j, i * spatial_dimension + j) = dnds(i - 1);
       }
     }
   };
 
   // tangents should have been calculated in normal modulii
   auto & tangents = model.getTangents();
   Matrix<Real> covariant_basis(
       tangents.begin(surface_dimension, spatial_dimension)[element.slave]);
 
   auto contravariant_metric_tensor =
       GeometryUtils::contravariantMetricTensor(covariant_basis);
 
   // construct 1st part of the stick modulii
   Matrix<Real> k_main(nb_nodes_per_contact * spatial_dimension,
                       nb_nodes_per_contact * spatial_dimension);
 
   for (auto && values1 : enumerate(covariant_basis.transpose())) {
     auto & alpha = std::get<0>(values1);
     auto & tangent_alpha = std::get<1>(values1);
 
     Matrix<Real> t_outer_t(spatial_dimension, spatial_dimension);
     Matrix<Real> mat_t_alpha(tangent_alpha.storage(), tangent_alpha.size(), 1.);
 
     for (auto && values2 : enumerate(covariant_basis.transpose())) {
       auto & beta = std::get<0>(values2);
       auto & tangent_beta = std::get<1>(values2);
 
       Matrix<Real> mat_t_beta(tangent_beta.storage(), tangent_beta.size(), 1.);
       t_outer_t.mul<false, true>(mat_t_alpha, mat_t_beta);
 
       Matrix<Real> tmp(spatial_dimension,
                        spatial_dimension * nb_nodes_per_contact);
       Matrix<Real> tmp1(nb_nodes_per_contact * spatial_dimension,
                         spatial_dimension * nb_nodes_per_contact);
       tmp.mul<false, false>(t_outer_t, A);
       tmp1.mul<true, false>(A, tmp);
       tmp1 *= contravariant_metric_tensor(alpha, beta);
       k_main += tmp1;
     }
   }
 
   k_main *= -epsilon_t;
 
   // construct 2nd part of the stick modulii
   auto & tangential_tractions = model.getTangentialTractions();
   Vector<Real> tangential_traction(
       tangential_tractions.begin(surface_dimension)[element.slave]);
 
   Matrix<Real> k_second(nb_nodes_per_contact * spatial_dimension,
                         nb_nodes_per_contact * spatial_dimension);
 
   for (auto alpha : arange(surface_dimension)) {
 
     Matrix<Real> k_sum(nb_nodes_per_contact * spatial_dimension,
                        nb_nodes_per_contact * spatial_dimension);
 
     for (auto && values1 : enumerate(shape_derivatives.transpose())) {
       auto & beta = std::get<0>(values1);
       auto & dnds = std::get<1>(values1);
       // construct Aj from shape function wrt to jth natural
       // coordinate
       construct_Aj(dnds);
       for (auto && values2 : enumerate(covariant_basis.transpose())) {
         auto & gamma = std::get<0>(values2);
         auto & tangent_gamma = std::get<1>(values2);
 
         Matrix<Real> t_outer_t(spatial_dimension, spatial_dimension);
         Matrix<Real> mat_t_gamma(tangent_gamma.storage(), tangent_gamma.size(),
                                  1.);
 
         for (auto && values3 : enumerate(covariant_basis.transpose())) {
           auto & theta = std::get<0>(values3);
           auto & tangent_theta = std::get<1>(values3);
 
           Matrix<Real> mat_t_theta(tangent_theta.storage(),
                                    tangent_theta.size(), 1.);
           t_outer_t.mul<false, true>(mat_t_gamma, mat_t_theta);
 
           Matrix<Real> tmp(spatial_dimension,
                            spatial_dimension * nb_nodes_per_contact);
           Matrix<Real> tmp1(nb_nodes_per_contact * spatial_dimension,
                             spatial_dimension * nb_nodes_per_contact);
           tmp.mul<false, false>(t_outer_t, Aj);
           tmp1.mul<true, false>(A, tmp);
           tmp1 *= contravariant_metric_tensor(alpha, theta) *
                   contravariant_metric_tensor(beta, gamma);
 
           Matrix<Real> tmp2(spatial_dimension,
                             spatial_dimension * nb_nodes_per_contact);
           Matrix<Real> tmp3(nb_nodes_per_contact * spatial_dimension,
                             spatial_dimension * nb_nodes_per_contact);
           tmp2.mul<false, false>(t_outer_t, A);
           tmp3.mul<true, false>(Aj, tmp2);
           tmp3 *= contravariant_metric_tensor(alpha, gamma) *
                   contravariant_metric_tensor(beta, theta);
 
           k_sum += tmp1 + tmp3;
         }
       }
     }
 
     k_second += tangential_traction[alpha] * k_sum;
   }
 
   stiffness += k_main * nodal_area - k_second * nodal_area;
 }
 
 /* -------------------------------------------------------------------------- */
 void ResolutionPenalty::computeSlipModuli(const ContactElement & element,
                                           Matrix<Real> & stiffness) {
 
   auto surface_dimension = spatial_dimension - 1;
 
   auto & gaps = model.getGaps();
   Real gap(gaps.begin()[element.slave]);
 
   auto & nodal_areas = model.getNodalArea();
   auto & nodal_area = nodal_areas.begin()[element.slave];
 
   // compute normal traction
   Real p_n = computeNormalTraction(gap);
 
   auto & projections = model.getProjections();
   Vector<Real> projection(projections.begin(surface_dimension)[element.slave]);
 
   auto & normals = model.getNormals();
   Vector<Real> normal(normals.begin(spatial_dimension)[element.slave]);
 
   // restructure normal as a matrix for an outer product
   Matrix<Real> mat_n(normal.storage(), normal.size(), 1.);
 
   // method from Schweizerhof and A. Konyukhov, K. Schweizerhof
   // DOI 10.1007/s00466-004-0616-7 and DOI 10.1007/s00466-003-0515-3
 
   // construct A matrix
   const ElementType & type = element.master.type;
   auto && shapes = ElementClassHelper<_ek_regular>::getN(projection, type);
 
   UInt nb_nodes_per_contact = element.getNbNodes();
   Matrix<Real> A(spatial_dimension, spatial_dimension * nb_nodes_per_contact);
 
   for (auto i : arange(nb_nodes_per_contact)) {
     for (auto j : arange(spatial_dimension)) {
       if (i == 0) {
         A(j, i * spatial_dimension + j) = 1;
         continue;
       }
       A(j, i * spatial_dimension + j) = -shapes[i - 1];
     }
   }
 
   // computing shape derivatives
   auto && shape_derivatives =
       ElementClassHelper<_ek_regular>::getDNDS(projection, type);
 
   Matrix<Real> Aj(spatial_dimension, spatial_dimension * nb_nodes_per_contact);
 
   auto construct_Aj = [&](auto && dnds) {
     for (auto i : arange(nb_nodes_per_contact)) {
       for (auto j : arange(spatial_dimension)) {
         if (i == 0) {
           Aj(j, i * spatial_dimension + j) = 0;
           continue;
         }
         Aj(j, i * spatial_dimension + j) = dnds(i - 1);
       }
     }
   };
 
   // tangents should have been calculated in normal modulii
   auto & tangents = model.getTangents();
   Matrix<Real> covariant_basis(
       tangents.begin(surface_dimension, spatial_dimension)[element.slave]);
 
   auto & tangential_tractions = model.getTangentialTractions();
   Vector<Real> tangential_traction(
       tangential_tractions.begin(surface_dimension)[element.slave]);
 
   // compute norm of trial traction
   Real traction_norm = 0;
   auto contravariant_metric_tensor =
       GeometryUtils::contravariantMetricTensor(covariant_basis);
 
   for (auto i : arange(surface_dimension)) {
     for (auto j : arange(surface_dimension)) {
       traction_norm += tangential_traction[i] * tangential_traction[j] *
                        contravariant_metric_tensor(i, j);
     }
   }
   traction_norm = sqrt(traction_norm);
 
   // construct four parts of stick modulii (eq 107,107a-c)
   Matrix<Real> k_first(nb_nodes_per_contact * spatial_dimension,
                        nb_nodes_per_contact * spatial_dimension);
   Matrix<Real> k_second(nb_nodes_per_contact * spatial_dimension,
                         nb_nodes_per_contact * spatial_dimension);
   Matrix<Real> k_third(nb_nodes_per_contact * spatial_dimension,
                        nb_nodes_per_contact * spatial_dimension);
   Matrix<Real> k_fourth(nb_nodes_per_contact * spatial_dimension,
                         nb_nodes_per_contact * spatial_dimension);
 
   for (auto && values1 : enumerate(covariant_basis.transpose())) {
     auto & alpha = std::get<0>(values1);
     auto & tangent_alpha = std::get<1>(values1);
 
     Matrix<Real> mat_t_alpha(tangent_alpha.storage(), tangent_alpha.size(), 1.);
 
     Matrix<Real> t_outer_n(spatial_dimension, spatial_dimension);
     Matrix<Real> t_outer_t(spatial_dimension, spatial_dimension);
 
     for (auto && values2 :
          zip(arange(surface_dimension), covariant_basis.transpose(),
              shape_derivatives.transpose())) {
       auto & beta = std::get<0>(values2);
       auto & tangent_beta = std::get<1>(values2);
       auto & dnds = std::get<2>(values2);
       // construct Aj from shape function wrt to jth natural
       // coordinate
       construct_Aj(dnds);
 
       // eq 107
       Matrix<Real> mat_t_beta(tangent_beta.storage(), tangent_beta.size(), 1.);
       t_outer_n.mul<false, true>(mat_t_beta, mat_n);
 
       Matrix<Real> tmp(spatial_dimension,
                        spatial_dimension * nb_nodes_per_contact);
       Matrix<Real> tmp1(nb_nodes_per_contact * spatial_dimension,
                         spatial_dimension * nb_nodes_per_contact);
       tmp.mul<false, false>(t_outer_n, A);
       tmp1.mul<true, false>(A, tmp);
 
       tmp1 *= epsilon_n * mu * tangential_traction[alpha] *
               contravariant_metric_tensor(alpha, beta);
       tmp1 /= traction_norm;
 
       k_first += tmp1 * nodal_area;
 
       // eq 107a
       t_outer_t.mul<false, true>(mat_t_alpha, mat_t_beta);
 
       tmp.mul<false, false>(t_outer_t, A);
       tmp1.mul<true, false>(A, tmp);
 
       tmp1 *= epsilon_t * mu * p_n * contravariant_metric_tensor(alpha, beta);
       tmp1 /= traction_norm;
 
       k_second += tmp1 * nodal_area;
 
       for (auto && values3 : enumerate(covariant_basis.transpose())) {
         auto & gamma = std::get<0>(values3);
         auto & tangent_gamma = std::get<1>(values3);
 
         Matrix<Real> mat_t_gamma(tangent_gamma.storage(), tangent_gamma.size(),
                                  1.);
 
         for (auto && values4 : enumerate(covariant_basis.transpose())) {
           auto & theta = std::get<0>(values4);
           auto & tangent_theta = std::get<1>(values4);
 
           Matrix<Real> mat_t_theta(tangent_theta.storage(),
                                    tangent_theta.size(), 1.);
           t_outer_t.mul<false, true>(mat_t_gamma, mat_t_theta);
 
           // eq 107b
           tmp.mul<false, false>(t_outer_t, A);
           tmp1.mul<true, false>(A, tmp);
 
           tmp1 *= epsilon_t * mu * p_n * tangential_traction[alpha] *
                   tangential_traction[beta];
           tmp1 *= contravariant_metric_tensor(alpha, gamma) *
                   contravariant_metric_tensor(beta, theta);
           tmp1 /= pow(traction_norm, 3);
 
           k_third += tmp1 * nodal_area;
 
           // eq 107c
           tmp.mul<false, false>(t_outer_t, Aj);
           tmp1.mul<true, false>(A, tmp);
           tmp1 *= contravariant_metric_tensor(alpha, theta) *
                   contravariant_metric_tensor(beta, gamma);
           tmp1 *= mu * p_n * tangential_traction[alpha];
           tmp1 /= traction_norm;
 
           Matrix<Real> tmp2(spatial_dimension,
                             spatial_dimension * nb_nodes_per_contact);
           Matrix<Real> tmp3(nb_nodes_per_contact * spatial_dimension,
                             spatial_dimension * nb_nodes_per_contact);
           tmp2.mul<false, false>(t_outer_t, A);
           tmp3.mul<true, false>(Aj, tmp2);
           tmp3 *= contravariant_metric_tensor(alpha, gamma) *
                   contravariant_metric_tensor(beta, theta);
           tmp3 *= mu * p_n * tangential_traction[alpha];
           tmp3 /= traction_norm;
 
           k_fourth += (tmp1 + tmp3) * nodal_area;
         }
       }
     }
   }
 
   stiffness += k_third + k_fourth - k_first - k_second;
 }
 
 /* -------------------------------------------------------------------------- */
 void ResolutionPenalty::beforeSolveStep() {}
 
 /* -------------------------------------------------------------------------- */
 void ResolutionPenalty::afterSolveStep(__attribute__((unused)) bool converged) {}
 
 INSTANTIATE_RESOLUTION(penalty_linear, ResolutionPenalty);
 
 } // namespace akantu
diff --git a/src/model/contact_mechanics/resolutions/resolution_penalty.hh b/src/model/contact_mechanics/resolutions/resolution_penalty.hh
index 4cae174f4..61f7ba197 100644
--- a/src/model/contact_mechanics/resolutions/resolution_penalty.hh
+++ b/src/model/contact_mechanics/resolutions/resolution_penalty.hh
@@ -1,126 +1,122 @@
 /**
  * @file   contact_resolution_penalty.hh
  *
  * @author Mohit Pundir <mohit.pundir@epfl.ch>
  *
  * @date creation: Fri Jun 18 2010
  * @date last modification: Mon Jan 29 2018
  *
  * @brief  Linear Penalty Resolution for Contact Mechanics Model
  *
  * @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 "aka_common.hh"
 #include "resolution.hh"
 /* -------------------------------------------------------------------------- */
 
 #ifndef __AKANTU_RESOLUTION_PENALTY_HH__
 #define __AKANTU_RESOLUTION_PENALTY_HH__
 
 namespace akantu {
 class ResolutionPenalty : public Resolution {
   /* ------------------------------------------------------------------------ */
   /* Constructors/Destructors                                                 */
   /* ------------------------------------------------------------------------ */
 public:
   ResolutionPenalty(ContactMechanicsModel & model, const ID & id = "");
 
   ~ResolutionPenalty() override = default;
 
   /* ------------------------------------------------------------------------ */
   /* Methods                                                                  */
   /* ------------------------------------------------------------------------ */
 protected:
   /// initialize the resolution
   void initialize();
 
-
   /* ------------------------------------------------------------------------ */
   /* Methods for stiffness computation                                        */
   /* ------------------------------------------------------------------------ */
 protected:
-  
   /// local computaion of stiffness matrix due to stick state
   void computeStickModuli(const ContactElement &, Matrix<Real> &);
 
-  /// local computation of stiffness matrix due to slip state 
+  /// local computation of stiffness matrix due to slip state
   void computeSlipModuli(const ContactElement &, Matrix<Real> &);
 
 public:
   /// local computation of tangent moduli due to normal traction
   void computeNormalModuli(const ContactElement &, Matrix<Real> &) override;
-  
+
   /// local computation of tangent moduli due to tangential traction
   void computeTangentialModuli(const ContactElement &, Matrix<Real> &) override;
-  
+
   /* ------------------------------------------------------------------------ */
   /* Methods for force computation                                            */
   /* ------------------------------------------------------------------------ */
 public:
   /// local computation of normal force due to normal contact
   void computeNormalForce(const ContactElement &, Vector<Real> &) override;
-  
-  /// local computation of tangential force due to frictional traction 
+
+  /// local computation of tangential force due to frictional traction
   void computeTangentialForce(const ContactElement &, Vector<Real> &) override;
 
 protected:
   /// local computation of normal traction due to penetration
   Real computeNormalTraction(Real &);
-  
+
   /// local computation of trial tangential traction due to friction
-  void computeTrialTangentialTraction(const ContactElement &, const Matrix<Real> &,
-				      Vector<Real> &);
+  void computeTrialTangentialTraction(const ContactElement &,
+                                      const Matrix<Real> &, Vector<Real> &);
 
-  /// local computation of tangential traction due to stick 
+  /// local computation of tangential traction due to stick
   void computeStickTangentialTraction(const ContactElement &, Vector<Real> &,
-				      Vector<Real> &);
+                                      Vector<Real> &);
 
   /// local computation of tangential traction due to slip
-  void computeSlipTangentialTraction(const ContactElement &, const Matrix<Real> &,
-				     Vector<Real> &, Vector<Real> &);
+  void computeSlipTangentialTraction(const ContactElement &,
+                                     const Matrix<Real> &, Vector<Real> &,
+                                     Vector<Real> &);
 
   /// local computation of tangential traction due to friction
   void computeTangentialTraction(const ContactElement &, const Matrix<Real> &,
-				 Vector<Real> &);
+                                 Vector<Real> &);
 
 public:
-
   void beforeSolveStep() override;
 
   void afterSolveStep(bool converged = true) override;
-  
+
   /* ------------------------------------------------------------------------ */
   /* Class Members                                                            */
   /* ------------------------------------------------------------------------ */
 protected:
   /// penalty parameter for normal traction
   Real epsilon_n;
 
   /// penalty parameter for tangential traction
   Real epsilon_t;
 };
-  
-
-} // akantu
 
+} // namespace akantu
 
 #endif /* __AKANTU_RESOLUTION_PENALTY_HH__  */
diff --git a/src/model/contact_mechanics/resolutions/resolution_penalty_quadratic.cc b/src/model/contact_mechanics/resolutions/resolution_penalty_quadratic.cc
index f0fe8e7e4..615d71fab 100644
--- a/src/model/contact_mechanics/resolutions/resolution_penalty_quadratic.cc
+++ b/src/model/contact_mechanics/resolutions/resolution_penalty_quadratic.cc
@@ -1,832 +1,832 @@
 /**
  * @file   resolution_penalty_quadratic.cc
  *
  * @author Mohit Pundir <mohit.pundir@epfl.ch>
  *
  * @date creation: Sun Aug 2 2020
  * @date last modification: Sun Aug 2 2020
  *
  * @brief  Specialization of the resolution class for the quadratic penalty
  * method
  *
  * @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 "resolution_penalty_quadratic.hh"
 #include "element_class_helper.hh"
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 ResolutionPenaltyQuadratic::ResolutionPenaltyQuadratic(
     ContactMechanicsModel & model, const ID & id)
     : Parent(model, id) {
   AKANTU_DEBUG_IN();
   this->initialize();
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void ResolutionPenaltyQuadratic::initialize() {}
 
 /* -------------------------------------------------------------------------- */
 Real ResolutionPenaltyQuadratic::computeNormalTraction(Real & gap) {
   return epsilon_n * (macaulay(gap) * macaulay(gap) + macaulay(gap));
 }
 
 /* -------------------------------------------------------------------------- */
 void ResolutionPenaltyQuadratic::computeNormalForce(
     const ContactElement & element, Vector<Real> & force) {
   force.zero();
 
   auto & gaps = model.getGaps();
   auto & projections = model.getProjections();
   auto & normals = model.getNormals();
 
   auto surface_dimension = spatial_dimension - 1;
 
   Real gap(gaps.begin()[element.slave]);
   Vector<Real> normal(normals.begin(spatial_dimension)[element.slave]);
   Vector<Real> projection(projections.begin(surface_dimension)[element.slave]);
 
   auto & nodal_area = const_cast<Array<Real> &>(model.getNodalArea());
 
   // compute normal traction
   Real p_n = computeNormalTraction(gap);
   p_n *= nodal_area[element.slave];
 
   UInt nb_nodes_per_contact = element.getNbNodes();
   Matrix<Real> shape_matric(spatial_dimension,
                             spatial_dimension * nb_nodes_per_contact);
   ResolutionUtils::computeShapeFunctionMatric(element, projection,
                                               shape_matric);
 
   force.mul<true>(shape_matric, normal, p_n);
 }
 
 /* -------------------------------------------------------------------------- */
 void ResolutionPenaltyQuadratic::computeTangentialForce(
     const ContactElement & element, Vector<Real> & force) {
 
   if (mu == 0)
     return;
 
   force.zero();
 
   UInt surface_dimension = spatial_dimension - 1;
 
   // compute tangents
   auto & projections = model.getProjections();
   Vector<Real> projection(projections.begin(surface_dimension)[element.slave]);
 
   auto & normals = model.getNormals();
   Vector<Real> normal(normals.begin(spatial_dimension)[element.slave]);
 
   auto & tangents = model.getTangents();
   Matrix<Real> covariant_basis(
       tangents.begin(surface_dimension, spatial_dimension)[element.slave]);
 
   // check for no-contact to contact condition
   // need a better way to check if new node added is not presnt in the
   // previous master elemets
   auto & previous_master_elements = model.getPreviousMasterElements();
   if (element.slave >= previous_master_elements.size())
     return;
 
   auto & previous_element = previous_master_elements[element.slave];
   if (previous_element.type == _not_defined)
     return;
 
   // compute tangential traction using return map algorithm
   auto & tangential_tractions = model.getTangentialTractions();
   Vector<Real> tangential_traction(
       tangential_tractions.begin(surface_dimension)[element.slave]);
   this->computeTangentialTraction(element, covariant_basis,
                                   tangential_traction);
 
   UInt nb_nodes_per_contact = element.getNbNodes();
   Matrix<Real> shape_matric(spatial_dimension,
                             spatial_dimension * nb_nodes_per_contact);
   ResolutionUtils::computeShapeFunctionMatric(element, projection,
                                               shape_matric);
 
   auto contravariant_metric_tensor =
       GeometryUtils::contravariantMetricTensor(covariant_basis);
 
   auto & nodal_area = const_cast<Array<Real> &>(model.getNodalArea());
 
   for (auto && values1 : enumerate(covariant_basis.transpose())) {
     auto & alpha = std::get<0>(values1);
     auto & tangent_alpha = std::get<1>(values1);
     for (auto && values2 : enumerate(tangential_traction)) {
       auto & beta = std::get<0>(values2);
       auto & traction_beta = std::get<1>(values2);
       Vector<Real> tmp(force.size());
       tmp.mul<true>(shape_matric, tangent_alpha, traction_beta);
       tmp *=
           contravariant_metric_tensor(alpha, beta) * nodal_area[element.slave];
       force += tmp;
     }
   }
 }
 
 /* -------------------------------------------------------------------------- */
 void ResolutionPenaltyQuadratic::computeTangentialTraction(
     const ContactElement & element, const Matrix<Real> & covariant_basis,
     Vector<Real> & traction_tangential) {
 
   UInt surface_dimension = spatial_dimension - 1;
 
   auto & gaps = model.getGaps();
   auto & gap = gaps.begin()[element.slave];
 
   // Return map algorithm is employed
   // compute trial traction
   Vector<Real> traction_trial(surface_dimension);
   this->computeTrialTangentialTraction(element, covariant_basis,
                                        traction_trial);
 
   // compute norm of trial traction
   Real traction_trial_norm = 0;
   auto contravariant_metric_tensor =
       GeometryUtils::contravariantMetricTensor(covariant_basis);
   for (auto i : arange(surface_dimension)) {
     for (auto j : arange(surface_dimension)) {
       traction_trial_norm += traction_trial[i] * traction_trial[j] *
                              contravariant_metric_tensor(i, j);
     }
   }
   traction_trial_norm = sqrt(traction_trial_norm);
 
   // check stick or slip condition
   auto & contact_state = model.getContactState();
   auto & state = contact_state.begin()[element.slave];
 
   Real p_n = computeNormalTraction(gap);
   bool stick = (traction_trial_norm <= mu * p_n) ? true : false;
 
   if (stick) {
     state = ContactState::_stick;
     computeStickTangentialTraction(element, traction_trial,
                                    traction_tangential);
   } else {
     state = ContactState::_slip;
     computeSlipTangentialTraction(element, covariant_basis, traction_trial,
                                   traction_tangential);
   }
 }
 
 /* -------------------------------------------------------------------------- */
 void ResolutionPenaltyQuadratic::computeTrialTangentialTraction(
     const ContactElement & element, const Matrix<Real> & covariant_basis,
     Vector<Real> & traction) {
 
   UInt surface_dimension = spatial_dimension - 1;
 
   auto & projections = model.getProjections();
   Vector<Real> current_projection(
       projections.begin(surface_dimension)[element.slave]);
 
   auto & previous_projections = model.getPreviousProjections();
   Vector<Real> previous_projection(
       previous_projections.begin(surface_dimension)[element.slave]);
 
   // method from Laursen et. al.
   /*auto covariant_metric_tensor =
   GeometryUtils::covariantMetricTensor(covariant_basis); auto
   increment_projection = current_projection - previous_projection;
 
   traction.mul<false>(covariant_metric_tensor, increment_projection, epsilon_t);
 
   auto & previous_tangential_tractions = model.getPreviousTangentialTractions();
   Vector<Real>
   previous_traction(previous_tangential_tractions.begin(surface_dimension)[element.slave]);
   traction = previous_traction + traction;*/
 
   // method from Schweizerhof
   auto covariant_metric_tensor =
       GeometryUtils::covariantMetricTensor(covariant_basis);
 
   auto & previous_tangential_tractions = model.getPreviousTangentialTractions();
   Vector<Real> previous_traction(
       previous_tangential_tractions.begin(surface_dimension)[element.slave]);
 
   auto & previous_tangents = model.getPreviousTangents();
   Matrix<Real> previous_covariant_basis(previous_tangents.begin(
       surface_dimension, spatial_dimension)[element.slave]);
   auto previous_contravariant_metric_tensor =
       GeometryUtils::contravariantMetricTensor(previous_covariant_basis);
 
   auto current_tangent = covariant_basis.transpose();
   auto previous_tangent = previous_covariant_basis.transpose();
 
   for (auto alpha : arange(surface_dimension)) {
     Vector<Real> tangent_alpha(current_tangent(alpha));
     for (auto gamma : arange(surface_dimension)) {
       for (auto beta : arange(surface_dimension)) {
         Vector<Real> tangent_beta(previous_tangent(beta));
         auto t_alpha_t_beta = tangent_beta.dot(tangent_alpha);
         traction[alpha] += previous_traction[gamma] *
                            previous_contravariant_metric_tensor(gamma, beta) *
                            t_alpha_t_beta;
       }
     }
   }
 
   auto & previous_master_elements = model.getPreviousMasterElements();
   auto & previous_element = previous_master_elements[element.slave];
 
   Vector<Real> previous_real_projection(spatial_dimension);
   GeometryUtils::realProjection(
       model.getMesh(), model.getContactDetector().getPositions(),
       previous_element, previous_projection, previous_real_projection);
 
   Vector<Real> current_real_projection(spatial_dimension);
   GeometryUtils::realProjection(
       model.getMesh(), model.getContactDetector().getPositions(),
       element.master, current_projection, current_real_projection);
 
   auto increment_real = current_real_projection - previous_real_projection;
   Vector<Real> increment_xi(surface_dimension);
 
   auto contravariant_metric_tensor =
       GeometryUtils::contravariantMetricTensor(covariant_basis);
 
   // increment in natural coordinate
   for (auto beta : arange(surface_dimension)) {
     for (auto gamma : arange(surface_dimension)) {
       auto temp = increment_real.dot(current_tangent(gamma));
       temp *= contravariant_metric_tensor(beta, gamma);
       increment_xi[beta] += temp;
     }
   }
 
   Vector<Real> temp(surface_dimension);
   temp.mul<false>(covariant_metric_tensor, increment_xi, epsilon_t);
 
   traction -= temp;
 }
 
 /* -------------------------------------------------------------------------- */
 void ResolutionPenaltyQuadratic::computeStickTangentialTraction(
     const ContactElement & /*element*/, Vector<Real> & traction_trial,
     Vector<Real> & traction_tangential) {
   traction_tangential = traction_trial;
 }
 
 /* -------------------------------------------------------------------------- */
 void ResolutionPenaltyQuadratic::computeSlipTangentialTraction(
     const ContactElement & element, const Matrix<Real> & covariant_basis,
     Vector<Real> & traction_trial, Vector<Real> & traction_tangential) {
   UInt surface_dimension = spatial_dimension - 1;
 
   auto & gaps = model.getGaps();
   auto & gap = gaps.begin()[element.slave];
 
   // compute norm of trial traction
   Real traction_trial_norm = 0;
   auto contravariant_metric_tensor =
       GeometryUtils::contravariantMetricTensor(covariant_basis);
   for (auto i : arange(surface_dimension)) {
     for (auto j : arange(surface_dimension)) {
       traction_trial_norm += traction_trial[i] * traction_trial[j] *
                              contravariant_metric_tensor(i, j);
     }
   }
   traction_trial_norm = sqrt(traction_trial_norm);
 
   auto slip_direction = traction_trial;
   slip_direction /= traction_trial_norm;
 
   Real p_n = computeNormalTraction(gap);
   traction_tangential = slip_direction;
   traction_tangential *= mu * p_n;
 }
 
 /* -------------------------------------------------------------------------- */
 void ResolutionPenaltyQuadratic::computeNormalModuli(
     const ContactElement & element, Matrix<Real> & stiffness) {
 
   auto surface_dimension = spatial_dimension - 1;
 
   auto & gaps = model.getGaps();
   Real gap(gaps.begin()[element.slave]);
 
   auto & projections = model.getProjections();
   Vector<Real> projection(projections.begin(surface_dimension)[element.slave]);
 
   auto & nodal_areas = model.getNodalArea();
   auto & nodal_area = nodal_areas.begin()[element.slave];
 
   auto & normals = model.getNormals();
   Vector<Real> normal(normals.begin(spatial_dimension)[element.slave]);
 
   // method from Schweizerhof and A. Konyukhov, K. Schweizerhof
   // DOI 10.1007/s00466-004-0616-7 and DOI 10.1007/s00466-003-0515-3
 
   // construct A matrix
   const ElementType & type = element.master.type;
   auto && shapes = ElementClassHelper<_ek_regular>::getN(projection, type);
 
   UInt nb_nodes_per_contact = element.getNbNodes();
   Matrix<Real> A(spatial_dimension, spatial_dimension * nb_nodes_per_contact);
 
   for (auto i : arange(nb_nodes_per_contact)) {
     for (auto j : arange(spatial_dimension)) {
       if (i == 0) {
         A(j, i * spatial_dimension + j) = 1;
         continue;
       }
       A(j, i * spatial_dimension + j) = -shapes[i - 1];
     }
   }
 
   // construct the main part of normal matrix
   Matrix<Real> k_main(nb_nodes_per_contact * spatial_dimension,
                       nb_nodes_per_contact * spatial_dimension);
 
   Matrix<Real> n_outer_n(spatial_dimension, spatial_dimension);
   Matrix<Real> mat_n(normal.storage(), normal.size(), 1.);
   n_outer_n.mul<false, true>(mat_n, mat_n);
 
   Matrix<Real> tmp(spatial_dimension, spatial_dimension * nb_nodes_per_contact);
   tmp.mul<false, false>(n_outer_n, A);
 
   k_main.mul<true, false>(A, tmp);
   k_main *= epsilon_n * heaviside(gap) * (2 * gap + 1) * nodal_area;
 
   // construct the rotational part of the normal matrix
   auto & tangents = model.getTangents();
   Matrix<Real> covariant_basis(
       tangents.begin(surface_dimension, spatial_dimension)[element.slave]);
 
   auto contravariant_metric_tensor =
       GeometryUtils::contravariantMetricTensor(covariant_basis);
 
   // computing shape derivatives
   auto && shape_derivatives =
       ElementClassHelper<_ek_regular>::getDNDS(projection, type);
 
   // consists of 2 rotational parts
   Matrix<Real> k_rot1(nb_nodes_per_contact * spatial_dimension,
                       nb_nodes_per_contact * spatial_dimension);
   Matrix<Real> k_rot2(nb_nodes_per_contact * spatial_dimension,
                       nb_nodes_per_contact * spatial_dimension);
   Matrix<Real> Aj(spatial_dimension, spatial_dimension * nb_nodes_per_contact);
 
   auto construct_Aj = [&](auto && dnds) {
     for (auto i : arange(nb_nodes_per_contact)) {
       for (auto j : arange(spatial_dimension)) {
         if (i == 0) {
           Aj(j, i * spatial_dimension + j) = 0;
           continue;
         }
         Aj(j, i * spatial_dimension + j) = dnds(i - 1);
       }
     }
   };
 
   for (auto && values1 : enumerate(covariant_basis.transpose())) {
     auto & alpha = std::get<0>(values1);
     auto & tangent = std::get<1>(values1);
 
     Matrix<Real> n_outer_t(spatial_dimension, spatial_dimension);
     Matrix<Real> mat_t(tangent.storage(), tangent.size(), 1.);
     n_outer_t.mul<false, true>(mat_n, mat_t);
 
     Matrix<Real> t_outer_n(spatial_dimension, spatial_dimension);
     t_outer_n.mul<false, true>(mat_t, mat_n);
 
     for (auto && values2 : enumerate(shape_derivatives.transpose())) {
       auto & beta = std::get<0>(values2);
       auto & dnds = std::get<1>(values2);
       // construct Aj from shape function wrt to jth natural
       // coordinate
       construct_Aj(dnds);
 
       Matrix<Real> tmp(spatial_dimension,
                        spatial_dimension * nb_nodes_per_contact);
       Matrix<Real> tmp1(nb_nodes_per_contact * spatial_dimension,
                         spatial_dimension * nb_nodes_per_contact);
       tmp.mul<false, false>(n_outer_t, A);
       tmp1.mul<true, false>(Aj, tmp);
       tmp1 *= contravariant_metric_tensor(alpha, beta);
       k_rot1 += tmp1;
 
       tmp.mul<false, false>(t_outer_n, Aj);
       tmp1.mul<true, false>(A, tmp);
       tmp1 *= contravariant_metric_tensor(alpha, beta);
       k_rot2 += tmp1;
     }
   }
 
   k_rot1 *= -epsilon_n * heaviside(gap) * (gap * gap + gap) * nodal_area;
   k_rot2 *= -epsilon_n * heaviside(gap) * (gap * gap + gap) * nodal_area;
 
   stiffness += k_main + k_rot1 + k_rot2;
 }
 
 /* -------------------------------------------------------------------------- */
 void ResolutionPenaltyQuadratic::computeTangentialModuli(
     const ContactElement & element, Matrix<Real> & stiffness) {
-
-  if (mu == 0)
+  if (mu == 0) {
     return;
+  }
 
   stiffness.zero();
 
   auto & contact_state = model.getContactState();
-  UInt state = contact_state.begin()[element.slave];
+  auto state = contact_state.begin()[element.slave];
 
   switch (state) {
   case ContactState::_stick: {
     computeStickModuli(element, stiffness);
     break;
   }
   case ContactState::_slip: {
     computeSlipModuli(element, stiffness);
     break;
   }
   default:
     break;
   }
 }
 
 /* -------------------------------------------------------------------------- */
 void ResolutionPenaltyQuadratic::computeStickModuli(
     const ContactElement & element, Matrix<Real> & stiffness) {
 
   auto surface_dimension = spatial_dimension - 1;
 
   auto & projections = model.getProjections();
   Vector<Real> projection(projections.begin(surface_dimension)[element.slave]);
 
   auto & nodal_areas = model.getNodalArea();
   auto & nodal_area = nodal_areas.begin()[element.slave];
 
   // method from Schweizerhof and A. Konyukhov, K. Schweizerhof
   // DOI 10.1007/s00466-004-0616-7 and DOI 10.1007/s00466-003-0515-3
 
   // construct A matrix
   const ElementType & type = element.master.type;
   auto && shapes = ElementClassHelper<_ek_regular>::getN(projection, type);
 
   UInt nb_nodes_per_contact = element.getNbNodes();
   Matrix<Real> A(spatial_dimension, spatial_dimension * nb_nodes_per_contact);
 
   for (auto i : arange(nb_nodes_per_contact)) {
     for (auto j : arange(spatial_dimension)) {
       if (i == 0) {
         A(j, i * spatial_dimension + j) = 1;
         continue;
       }
       A(j, i * spatial_dimension + j) = -shapes[i - 1];
     }
   }
 
   // computing shape derivatives
   auto && shape_derivatives =
       ElementClassHelper<_ek_regular>::getDNDS(projection, type);
 
   Matrix<Real> Aj(spatial_dimension, spatial_dimension * nb_nodes_per_contact);
 
   auto construct_Aj = [&](auto && dnds) {
     for (auto i : arange(nb_nodes_per_contact)) {
       for (auto j : arange(spatial_dimension)) {
         if (i == 0) {
           Aj(j, i * spatial_dimension + j) = 0;
           continue;
         }
         Aj(j, i * spatial_dimension + j) = dnds(i - 1);
       }
     }
   };
 
   // tangents should have been calculated in normal modulii
   auto & tangents = model.getTangents();
   Matrix<Real> covariant_basis(
       tangents.begin(surface_dimension, spatial_dimension)[element.slave]);
 
   auto contravariant_metric_tensor =
       GeometryUtils::contravariantMetricTensor(covariant_basis);
 
   // construct 1st part of the stick modulii
   Matrix<Real> k_main(nb_nodes_per_contact * spatial_dimension,
                       nb_nodes_per_contact * spatial_dimension);
 
   for (auto && values1 : enumerate(covariant_basis.transpose())) {
     auto & alpha = std::get<0>(values1);
     auto & tangent_alpha = std::get<1>(values1);
 
     Matrix<Real> t_outer_t(spatial_dimension, spatial_dimension);
     Matrix<Real> mat_t_alpha(tangent_alpha.storage(), tangent_alpha.size(), 1.);
 
     for (auto && values2 : enumerate(covariant_basis.transpose())) {
       auto & beta = std::get<0>(values2);
       auto & tangent_beta = std::get<1>(values2);
 
       Matrix<Real> mat_t_beta(tangent_beta.storage(), tangent_beta.size(), 1.);
       t_outer_t.mul<false, true>(mat_t_alpha, mat_t_beta);
 
       Matrix<Real> tmp(spatial_dimension,
                        spatial_dimension * nb_nodes_per_contact);
       Matrix<Real> tmp1(nb_nodes_per_contact * spatial_dimension,
                         spatial_dimension * nb_nodes_per_contact);
       tmp.mul<false, false>(t_outer_t, A);
       tmp1.mul<true, false>(A, tmp);
       tmp1 *= contravariant_metric_tensor(alpha, beta);
       k_main += tmp1;
     }
   }
 
   k_main *= -epsilon_t;
 
   // construct 2nd part of the stick modulii
   auto & tangential_tractions = model.getTangentialTractions();
   Vector<Real> tangential_traction(
       tangential_tractions.begin(surface_dimension)[element.slave]);
 
   Matrix<Real> k_second(nb_nodes_per_contact * spatial_dimension,
                         nb_nodes_per_contact * spatial_dimension);
 
   for (auto alpha : arange(surface_dimension)) {
 
     Matrix<Real> k_sum(nb_nodes_per_contact * spatial_dimension,
                        nb_nodes_per_contact * spatial_dimension);
 
     for (auto && values1 : enumerate(shape_derivatives.transpose())) {
       auto & beta = std::get<0>(values1);
       auto & dnds = std::get<1>(values1);
       // construct Aj from shape function wrt to jth natural
       // coordinate
       construct_Aj(dnds);
       for (auto && values2 : enumerate(covariant_basis.transpose())) {
         auto & gamma = std::get<0>(values2);
         auto & tangent_gamma = std::get<1>(values2);
 
         Matrix<Real> t_outer_t(spatial_dimension, spatial_dimension);
         Matrix<Real> mat_t_gamma(tangent_gamma.storage(), tangent_gamma.size(),
                                  1.);
 
         for (auto && values3 : enumerate(covariant_basis.transpose())) {
           auto & theta = std::get<0>(values3);
           auto & tangent_theta = std::get<1>(values3);
 
           Matrix<Real> mat_t_theta(tangent_theta.storage(),
                                    tangent_theta.size(), 1.);
           t_outer_t.mul<false, true>(mat_t_gamma, mat_t_theta);
 
           Matrix<Real> tmp(spatial_dimension,
                            spatial_dimension * nb_nodes_per_contact);
           Matrix<Real> tmp1(nb_nodes_per_contact * spatial_dimension,
                             spatial_dimension * nb_nodes_per_contact);
           tmp.mul<false, false>(t_outer_t, Aj);
           tmp1.mul<true, false>(A, tmp);
           tmp1 *= contravariant_metric_tensor(alpha, theta) *
                   contravariant_metric_tensor(beta, gamma);
 
           Matrix<Real> tmp2(spatial_dimension,
                             spatial_dimension * nb_nodes_per_contact);
           Matrix<Real> tmp3(nb_nodes_per_contact * spatial_dimension,
                             spatial_dimension * nb_nodes_per_contact);
           tmp2.mul<false, false>(t_outer_t, A);
           tmp3.mul<true, false>(Aj, tmp2);
           tmp3 *= contravariant_metric_tensor(alpha, gamma) *
                   contravariant_metric_tensor(beta, theta);
 
           k_sum += tmp1 + tmp3;
         }
       }
     }
 
     k_second += tangential_traction[alpha] * k_sum;
   }
 
   stiffness += k_main * nodal_area - k_second * nodal_area;
 }
 
 /* -------------------------------------------------------------------------- */
 void ResolutionPenaltyQuadratic::computeSlipModuli(
     const ContactElement & element, Matrix<Real> & stiffness) {
 
   auto surface_dimension = spatial_dimension - 1;
 
   auto & gaps = model.getGaps();
   Real gap(gaps.begin()[element.slave]);
 
   auto & nodal_areas = model.getNodalArea();
   auto & nodal_area = nodal_areas.begin()[element.slave];
 
   // compute normal traction
   Real p_n = computeNormalTraction(gap);
 
   auto & projections = model.getProjections();
   Vector<Real> projection(projections.begin(surface_dimension)[element.slave]);
 
   auto & normals = model.getNormals();
   Vector<Real> normal(normals.begin(spatial_dimension)[element.slave]);
 
   // restructure normal as a matrix for an outer product
   Matrix<Real> mat_n(normal.storage(), normal.size(), 1.);
 
   // method from Schweizerhof and A. Konyukhov, K. Schweizerhof
   // DOI 10.1007/s00466-004-0616-7 and DOI 10.1007/s00466-003-0515-3
 
   // construct A matrix
   const ElementType & type = element.master.type;
   auto && shapes = ElementClassHelper<_ek_regular>::getN(projection, type);
 
   UInt nb_nodes_per_contact = element.getNbNodes();
   Matrix<Real> A(spatial_dimension, spatial_dimension * nb_nodes_per_contact);
 
   for (auto i : arange(nb_nodes_per_contact)) {
     for (auto j : arange(spatial_dimension)) {
       if (i == 0) {
         A(j, i * spatial_dimension + j) = 1;
         continue;
       }
       A(j, i * spatial_dimension + j) = -shapes[i - 1];
     }
   }
 
   // computing shape derivatives
   auto && shape_derivatives =
       ElementClassHelper<_ek_regular>::getDNDS(projection, type);
 
   Matrix<Real> Aj(spatial_dimension, spatial_dimension * nb_nodes_per_contact);
 
   auto construct_Aj = [&](auto && dnds) {
     for (auto i : arange(nb_nodes_per_contact)) {
       for (auto j : arange(spatial_dimension)) {
         if (i == 0) {
           Aj(j, i * spatial_dimension + j) = 0;
           continue;
         }
         Aj(j, i * spatial_dimension + j) = dnds(i - 1);
       }
     }
   };
 
   // tangents should have been calculated in normal modulii
   auto & tangents = model.getTangents();
   Matrix<Real> covariant_basis(
       tangents.begin(surface_dimension, spatial_dimension)[element.slave]);
 
   auto & tangential_tractions = model.getTangentialTractions();
   Vector<Real> tangential_traction(
       tangential_tractions.begin(surface_dimension)[element.slave]);
 
   // compute norm of trial traction
   Real traction_norm = 0;
   auto contravariant_metric_tensor =
       GeometryUtils::contravariantMetricTensor(covariant_basis);
 
   for (auto i : arange(surface_dimension)) {
     for (auto j : arange(surface_dimension)) {
       traction_norm += tangential_traction[i] * tangential_traction[j] *
                        contravariant_metric_tensor(i, j);
     }
   }
   traction_norm = sqrt(traction_norm);
 
   // construct four parts of stick modulii (eq 107,107a-c)
   Matrix<Real> k_first(nb_nodes_per_contact * spatial_dimension,
                        nb_nodes_per_contact * spatial_dimension);
   Matrix<Real> k_second(nb_nodes_per_contact * spatial_dimension,
                         nb_nodes_per_contact * spatial_dimension);
   Matrix<Real> k_third(nb_nodes_per_contact * spatial_dimension,
                        nb_nodes_per_contact * spatial_dimension);
   Matrix<Real> k_fourth(nb_nodes_per_contact * spatial_dimension,
                         nb_nodes_per_contact * spatial_dimension);
 
   for (auto && values1 : enumerate(covariant_basis.transpose())) {
     auto & alpha = std::get<0>(values1);
     auto & tangent_alpha = std::get<1>(values1);
 
     Matrix<Real> mat_t_alpha(tangent_alpha.storage(), tangent_alpha.size(), 1.);
 
     Matrix<Real> t_outer_n(spatial_dimension, spatial_dimension);
     Matrix<Real> t_outer_t(spatial_dimension, spatial_dimension);
 
     for (auto && values2 :
          zip(arange(surface_dimension), covariant_basis.transpose(),
              shape_derivatives.transpose())) {
       auto & beta = std::get<0>(values2);
       auto & tangent_beta = std::get<1>(values2);
       auto & dnds = std::get<2>(values2);
       // construct Aj from shape function wrt to jth natural
       // coordinate
       construct_Aj(dnds);
 
       // eq 107
       Matrix<Real> mat_t_beta(tangent_beta.storage(), tangent_beta.size(), 1.);
       t_outer_n.mul<false, true>(mat_t_beta, mat_n);
 
       Matrix<Real> tmp(spatial_dimension,
                        spatial_dimension * nb_nodes_per_contact);
       Matrix<Real> tmp1(nb_nodes_per_contact * spatial_dimension,
                         spatial_dimension * nb_nodes_per_contact);
       tmp.mul<false, false>(t_outer_n, A);
       tmp1.mul<true, false>(A, tmp);
 
       tmp1 *= epsilon_n * mu * tangential_traction[alpha] *
               contravariant_metric_tensor(alpha, beta);
       tmp1 /= traction_norm;
 
       k_first += tmp1 * nodal_area;
 
       // eq 107a
       t_outer_t.mul<false, true>(mat_t_alpha, mat_t_beta);
 
       tmp.mul<false, false>(t_outer_t, A);
       tmp1.mul<true, false>(A, tmp);
 
       tmp1 *= epsilon_t * mu * p_n * contravariant_metric_tensor(alpha, beta);
       tmp1 /= traction_norm;
 
       k_second += tmp1 * nodal_area;
 
       for (auto && values3 : enumerate(covariant_basis.transpose())) {
         auto & gamma = std::get<0>(values3);
         auto & tangent_gamma = std::get<1>(values3);
 
         Matrix<Real> mat_t_gamma(tangent_gamma.storage(), tangent_gamma.size(),
                                  1.);
 
         for (auto && values4 : enumerate(covariant_basis.transpose())) {
           auto & theta = std::get<0>(values4);
           auto & tangent_theta = std::get<1>(values4);
 
           Matrix<Real> mat_t_theta(tangent_theta.storage(),
                                    tangent_theta.size(), 1.);
           t_outer_t.mul<false, true>(mat_t_gamma, mat_t_theta);
 
           // eq 107b
           tmp.mul<false, false>(t_outer_t, A);
           tmp1.mul<true, false>(A, tmp);
 
           tmp1 *= epsilon_t * mu * p_n * tangential_traction[alpha] *
                   tangential_traction[beta];
           tmp1 *= contravariant_metric_tensor(alpha, gamma) *
                   contravariant_metric_tensor(beta, theta);
           tmp1 /= pow(traction_norm, 3);
 
           k_third += tmp1 * nodal_area;
 
           // eq 107c
           tmp.mul<false, false>(t_outer_t, Aj);
           tmp1.mul<true, false>(A, tmp);
           tmp1 *= contravariant_metric_tensor(alpha, theta) *
                   contravariant_metric_tensor(beta, gamma);
           tmp1 *= mu * p_n * tangential_traction[alpha];
           tmp1 /= traction_norm;
 
           Matrix<Real> tmp2(spatial_dimension,
                             spatial_dimension * nb_nodes_per_contact);
           Matrix<Real> tmp3(nb_nodes_per_contact * spatial_dimension,
                             spatial_dimension * nb_nodes_per_contact);
           tmp2.mul<false, false>(t_outer_t, A);
           tmp3.mul<true, false>(Aj, tmp2);
           tmp3 *= contravariant_metric_tensor(alpha, gamma) *
                   contravariant_metric_tensor(beta, theta);
           tmp3 *= mu * p_n * tangential_traction[alpha];
           tmp3 /= traction_norm;
 
           k_fourth += (tmp1 + tmp3) * nodal_area;
         }
       }
     }
   }
 
   stiffness += k_third + k_fourth - k_first - k_second;
 }
 
 /* -------------------------------------------------------------------------- */
 void ResolutionPenaltyQuadratic::beforeSolveStep() {}
 
 /* -------------------------------------------------------------------------- */
 void ResolutionPenaltyQuadratic::afterSolveStep(
     __attribute__((unused)) bool converged) {}
 
 INSTANTIATE_RESOLUTION(penalty_quadratic, ResolutionPenaltyQuadratic);
 
 } // namespace akantu
diff --git a/src/model/solid_mechanics/solid_mechanics_model_io.cc b/src/model/solid_mechanics/solid_mechanics_model_io.cc
index b6fc9c8da..f6d6d5d50 100644
--- a/src/model/solid_mechanics/solid_mechanics_model_io.cc
+++ b/src/model/solid_mechanics/solid_mechanics_model_io.cc
@@ -1,338 +1,337 @@
 /**
  * @file   solid_mechanics_model_io.cc
  *
  * @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
  * @author David Simon Kammer <david.kammer@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Sun Jul 09 2017
  * @date last modification: Sun Dec 03 2017
  *
  * @brief  Dumpable part of the SolidMechnicsModel
  *
  *
  * Copyright (©) 2016-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.hh"
 
 #include "group_manager_inline_impl.hh"
 
 #include "dumpable_inline_impl.hh"
 #ifdef AKANTU_USE_IOHELPER
 #include "dumper_element_partition.hh"
 #include "dumper_elemental_field.hh"
 #include "dumper_field.hh"
 #include "dumper_homogenizing_field.hh"
 #include "dumper_internal_material_field.hh"
 #include "dumper_iohelper.hh"
 #include "dumper_material_padders.hh"
 #include "dumper_paraview.hh"
 #endif
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 bool SolidMechanicsModel::isInternal(const std::string & field_name,
                                      ElementKind element_kind) {
   /// check if at least one material contains field_id as an internal
   for (auto & material : materials) {
     bool is_internal = material->isInternal<Real>(field_name, element_kind);
     if (is_internal) {
       return true;
     }
   }
 
   return false;
 }
 
 /* -------------------------------------------------------------------------- */
 ElementTypeMap<UInt>
 SolidMechanicsModel::getInternalDataPerElem(const std::string & field_name,
                                             ElementKind element_kind) {
-
   if (!(this->isInternal(field_name, element_kind))) {
     AKANTU_EXCEPTION("unknown internal " << field_name);
   }
 
   for (auto & material : materials) {
     if (material->isInternal<Real>(field_name, element_kind)) {
       return material->getInternalDataPerElem<Real>(field_name, element_kind);
     }
   }
 
   return ElementTypeMap<UInt>();
 }
 
 /* -------------------------------------------------------------------------- */
 ElementTypeMapArray<Real> &
 SolidMechanicsModel::flattenInternal(const std::string & field_name,
                                      ElementKind kind,
                                      const GhostType ghost_type) {
   auto key = std::make_pair(field_name, kind);
 
   ElementTypeMapArray<Real> * internal_flat;
 
   auto it = this->registered_internals.find(key);
   if (it == this->registered_internals.end()) {
     auto internal = std::make_unique<ElementTypeMapArray<Real>>(
         field_name, this->id);
 
     internal_flat = internal.get();
     this->registered_internals[key] = std::move(internal);
   } else {
     internal_flat = it->second.get();
   }
 
   for (auto type :
        mesh.elementTypes(Model::spatial_dimension, ghost_type, kind)) {
     if (internal_flat->exists(type, ghost_type)) {
       auto & internal = (*internal_flat)(type, ghost_type);
       internal.resize(0);
     }
   }
 
   for (auto & material : materials) {
     if (material->isInternal<Real>(field_name, kind)) {
       material->flattenInternal(field_name, *internal_flat, ghost_type, kind);
     }
   }
 
   return *internal_flat;
 }
 
 /* -------------------------------------------------------------------------- */
 void SolidMechanicsModel::flattenAllRegisteredInternals(
     ElementKind kind) {
   ElementKind _kind;
   ID _id;
 
   for (auto & internal : this->registered_internals) {
     std::tie(_id, _kind) = internal.first;
     if (kind == _kind) {
       this->flattenInternal(_id, kind);
     }
   }
 }
 
 /* -------------------------------------------------------------------------- */
 void SolidMechanicsModel::onDump() {
   this->flattenAllRegisteredInternals(_ek_regular);
 }
 
 /* -------------------------------------------------------------------------- */
 #ifdef AKANTU_USE_IOHELPER
 std::shared_ptr<dumpers::Field> SolidMechanicsModel::createElementalField(
     const std::string & field_name, const std::string & group_name,
     bool padding_flag, UInt spatial_dimension,
     ElementKind kind) {
 
   std::shared_ptr<dumpers::Field> field;
 
   if (field_name == "partitions") {
     field = mesh.createElementalField<UInt, dumpers::ElementPartitionField>(
         mesh.getConnectivities(), group_name, spatial_dimension, kind);
   } else if (field_name == "material_index") {
     field = mesh.createElementalField<UInt, Vector, dumpers::ElementalField>(
         material_index, group_name, spatial_dimension, kind);
   } else {
     // this copy of field_name is used to compute derivated data such as
     // strain and von mises stress that are based on grad_u and stress
     std::string field_name_copy(field_name);
 
     if (field_name == "strain" || field_name == "Green strain" ||
         field_name == "principal strain" ||
         field_name == "principal Green strain") {
       field_name_copy = "grad_u";
     } else if (field_name == "Von Mises stress") {
       field_name_copy = "stress";
     }
 
     bool is_internal = this->isInternal(field_name_copy, kind);
 
     if (is_internal) {
       auto nb_data_per_elem =
           this->getInternalDataPerElem(field_name_copy, kind);
       auto & internal_flat = this->flattenInternal(field_name_copy, kind);
 
       field = mesh.createElementalField<Real, dumpers::InternalMaterialField>(
           internal_flat, group_name, spatial_dimension, kind, nb_data_per_elem);
 
       std::unique_ptr<dumpers::ComputeFunctorInterface> func;
       if (field_name == "strain") {
         func = std::make_unique<dumpers::ComputeStrain<false>>(*this);
       } else if (field_name == "Von Mises stress") {
         func = std::make_unique<dumpers::ComputeVonMisesStress>(*this);
       } else if (field_name == "Green strain") {
         func = std::make_unique<dumpers::ComputeStrain<true>>(*this);
       } else if (field_name == "principal strain") {
         func = std::make_unique<dumpers::ComputePrincipalStrain<false>>(*this);
       } else if (field_name == "principal Green strain") {
         func = std::make_unique<dumpers::ComputePrincipalStrain<true>>(*this);
       }
 
       if (func) {
         field = dumpers::FieldComputeProxy::createFieldCompute(field,
                                                               std::move(func));
       }
       // treat the paddings
       if (padding_flag) {
         if (field_name == "stress") {
           if (spatial_dimension == 2) {
             auto foo = std::make_unique<dumpers::StressPadder<2>>(*this);
             field = dumpers::FieldComputeProxy::createFieldCompute(
                 field, std::move(foo));
           }
         } else if (field_name == "strain" || field_name == "Green strain") {
           if (spatial_dimension == 2) {
             auto foo = std::make_unique<dumpers::StrainPadder<2>>(*this);
             field = dumpers::FieldComputeProxy::createFieldCompute(
                 field, std::move(foo));
           }
         }
       }
 
       // homogenize the field
       auto foo = dumpers::HomogenizerProxy::createHomogenizer(*field);
 
       field =
           dumpers::FieldComputeProxy::createFieldCompute(field, std::move(foo));
     }
   }
   return field;
 }
 
 /* -------------------------------------------------------------------------- */
 std::shared_ptr<dumpers::Field>
 SolidMechanicsModel::createNodalFieldReal(const std::string & field_name,
                                           const std::string & group_name,
                                           bool padding_flag) {
 
   std::map<std::string, Array<Real> *> real_nodal_fields;
   real_nodal_fields["displacement"] = this->displacement.get();
   real_nodal_fields["mass"] = this->mass.get();
   real_nodal_fields["velocity"] = this->velocity.get();
   real_nodal_fields["acceleration"] = this->acceleration.get();
   real_nodal_fields["external_force"] = this->external_force.get();
   real_nodal_fields["internal_force"] = this->internal_force.get();
   real_nodal_fields["increment"] = this->displacement_increment.get();
 
   if (field_name == "force") {
     AKANTU_EXCEPTION("The 'force' field has been renamed in 'external_force'");
   } else if (field_name == "residual") {
     AKANTU_EXCEPTION(
         "The 'residual' field has been replaced by 'internal_force'");
   }
 
   std::shared_ptr<dumpers::Field> field;
   if (padding_flag) {
     field = this->mesh.createNodalField(real_nodal_fields[field_name],
                                         group_name, 3);
   } else {
     field =
         this->mesh.createNodalField(real_nodal_fields[field_name], group_name);
   }
 
   return field;
 }
 
 /* -------------------------------------------------------------------------- */
 std::shared_ptr<dumpers::Field> SolidMechanicsModel::createNodalFieldBool(
     const std::string & field_name, const std::string & group_name,
     __attribute__((unused)) bool padding_flag) {
 
   std::map<std::string, Array<bool> *> uint_nodal_fields;
   uint_nodal_fields["blocked_dofs"] = blocked_dofs.get();
 
   std::shared_ptr<dumpers::Field> field;
   field = mesh.createNodalField(uint_nodal_fields[field_name], group_name);
   return field;
 }
 /* -------------------------------------------------------------------------- */
 #else
 /* -------------------------------------------------------------------------- */
 std::shared_ptr<dumpers::Field>
 SolidMechanicsModel::createElementalField(const std::string &,
                                           const std::string &, bool,
                                           const UInt &, ElementKind) {
   return nullptr;
 }
 /* --------------------------------------------------------------------------
  */
 std::shaed_ptr<dumpers::Field>
 SolidMechanicsModel::createNodalFieldReal(const std::string &,
                                           const std::string &, bool) {
   return nullptr;
 }
 
 /* --------------------------------------------------------------------------
  */
 std::shared_ptr<dumpers::Field>
 SolidMechanicsModel::createNodalFieldBool(const std::string &,
                                           const std::string &, bool) {
   return nullptr;
 }
 
 #endif
 /* -------------------------------------------------------------------------- */
 void SolidMechanicsModel::dump(const std::string & dumper_name) {
   this->onDump();
   EventManager::sendEvent(SolidMechanicsModelEvent::BeforeDumpEvent());
   mesh.dump(dumper_name);
 }
 
 /* -------------------------------------------------------------------------- */
 void SolidMechanicsModel::dump(const std::string & dumper_name, UInt step) {
   this->onDump();
   EventManager::sendEvent(SolidMechanicsModelEvent::BeforeDumpEvent());
   mesh.dump(dumper_name, step);
 }
 
 /* -------------------------------------------------------------------------- */
 void SolidMechanicsModel::dump(const std::string & dumper_name, Real time,
                                UInt step) {
   this->onDump();
   EventManager::sendEvent(SolidMechanicsModelEvent::BeforeDumpEvent());
   mesh.dump(dumper_name, time, step);
 }
 
 /* -------------------------------------------------------------------------- */
 void SolidMechanicsModel::dump() {
   this->onDump();
   EventManager::sendEvent(SolidMechanicsModelEvent::BeforeDumpEvent());
   mesh.dump();
 }
 
 /* -------------------------------------------------------------------------- */
 void SolidMechanicsModel::dump(UInt step) {
   this->onDump();
   EventManager::sendEvent(SolidMechanicsModelEvent::BeforeDumpEvent());
   mesh.dump(step);
 }
 
 /* -------------------------------------------------------------------------- */
 void SolidMechanicsModel::dump(Real time, UInt step) {
   this->onDump();
   EventManager::sendEvent(SolidMechanicsModelEvent::BeforeDumpEvent());
   mesh.dump(time, step);
 }
 
 } // namespace akantu