diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index c3ec182d4..ff42532cc 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -1,216 +1,207 @@
 #===============================================================================
 # @file   CMakeLists.txt
 #
 # @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
 # @author Nicolas Richart <nicolas.richart@epfl.ch>
 #
 # @date creation: Mon Jun 14 2010
-# @date last modification: Wed Jan 20 2016
+# @date last modification: Tue Feb 13 2018
 #
 # @brief  CMake file for the library
 #
 # @section LICENSE
 #
-# Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
-# Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
-# Solides)
+# 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 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.
+# 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/>.
+# You should  have received  a copy  of the GNU  Lesser General  Public License along with Akantu. If not, see <http://www.gnu.org/licenses/>.
 #
 #===============================================================================
 
 #===============================================================================
 # Package Management
 #===============================================================================
 package_get_all_source_files(
   AKANTU_LIBRARY_SRCS
   AKANTU_LIBRARY_PUBLIC_HDRS
   AKANTU_LIBRARY_PRIVATE_HDRS
   )
 
 package_get_all_include_directories(
   AKANTU_LIBRARY_INCLUDE_DIRS
   )
 
 package_get_all_external_informations(
   PRIVATE_INCLUDE AKANTU_PRIVATE_EXTERNAL_INCLUDE_DIR
   INTERFACE_INCLUDE AKANTU_INTERFACE_EXTERNAL_INCLUDE_DIR
   LIBRARIES AKANTU_EXTERNAL_LIBRARIES
   )
 
 package_get_all_compilation_flags(CXX _cxx_flags)
 set(AKANTU_EXTRA_CXX_FLAGS
   "${_cxx_flags}" CACHE STRING "Extra flags defined by loaded packages" FORCE)
 mark_as_advanced(AKANTU_EXTRA_CXX_FLAGS)
 
 foreach(src_ ${AKANTU_SPIRIT_SOURCES})
   set_property(SOURCE ${src_} PROPERTY COMPILE_FLAGS "-g0 -Werror")
 endforeach()
 
 #===========================================================================
 # header for blas/lapack (any other fortran libraries)
 #===========================================================================
 package_is_activated(BLAS _blas_activated)
 package_is_activated(LAPACK _lapack_activated)
 
 if(_blas_activated OR _lapack_activated)
   if(CMAKE_Fortran_COMPILER)
     # ugly hack
     set(CMAKE_Fortran_COMPILER_LOADED TRUE)
   endif()
 
   include(FortranCInterface)
   FortranCInterface_HEADER(
     "${CMAKE_CURRENT_BINARY_DIR}/aka_fortran_mangling.hh"
     MACRO_NAMESPACE "AKA_FC_")
   mark_as_advanced(CDEFS)
 endif()
 
 list(APPEND AKANTU_LIBRARY_INCLUDE_DIRS "${CMAKE_CURRENT_BINARY_DIR}")
 set(AKANTU_INCLUDE_DIRS
   ${CMAKE_CURRENT_BINARY_DIR} ${AKANTU_LIBRARY_INCLUDE_DIRS}
   CACHE INTERNAL "Internal include directories to link with Akantu as a subproject")
 
 #===========================================================================
 # configurations
 #===========================================================================
 package_get_all_material_includes(AKANTU_MATERIAL_INCLUDES)
 package_get_all_material_lists(AKANTU_MATERIAL_LISTS)
 configure_file(model/solid_mechanics/material_list.hh.in
   "${CMAKE_CURRENT_BINARY_DIR}/material_list.hh" @ONLY)
 
 package_get_element_lists()
 configure_file(common/aka_element_classes_info.hh.in
   "${CMAKE_CURRENT_BINARY_DIR}/aka_element_classes_info.hh" @ONLY)
 
 configure_file(common/aka_config.hh.in
   "${CMAKE_CURRENT_BINARY_DIR}/aka_config.hh" @ONLY)
 
 #===============================================================================
 # Debug infos
 #===============================================================================
 set(AKANTU_GDB_DIR ${PROJECT_SOURCE_DIR}/cmake)
 if(UNIX)
   string(TOUPPER "${CMAKE_BUILD_TYPE}" _u_build_type)
   if(_u_build_type STREQUAL "DEBUG" OR _u_build_type STREQUAL "RELWITHDEBINFO")
     configure_file(${PROJECT_SOURCE_DIR}/cmake/libakantu-gdb.py.in
       "${PROJECT_BINARY_DIR}/libakantu-gdb.py"
       @ONLY)
     configure_file(${PROJECT_SOURCE_DIR}/cmake/akantu-debug.cc.in
       "${PROJECT_BINARY_DIR}/akantu-debug.cc" @ONLY)
 
     list(APPEND AKANTU_LIBRARY_SRCS ${PROJECT_BINARY_DIR}/akantu-debug.cc)
   endif()
 else()
   find_program(GDB_EXECUTABLE gdb)
 
   if(GDB_EXECUTABLE)
     execute_process(COMMAND
       ${GDB_EXECUTABLE} --batch -x "${PROJECT_SOURCE_DIR}/cmake/gdb_python_path"
       OUTPUT_VARIABLE AKANTU_PYTHON_GDB_DIR
       ERROR_QUIET
       RESULT_VARIABLE _res)
 
     if(_res EQUAL 0 AND UNIX)
       set(GDB_USER_CONFIG $ENV{HOME}/.gdb/auto-load)
       file(MAKE_DIRECTORY ${GDB_USER_CONFIG})
 
       configure_file(${PROJECT_SOURCE_DIR}/cmake/libakantu-gdb.py.in
         "${GDB_USER_CONFIG}/${CMAKE_SHARED_LIBRARY_PREFIX}akantu${CMAKE_SHARED_LIBRARY_SUFFIX}.${AKANTU_VERSION}-gdb.py"
         @ONLY)
     endif()
   endif()
 endif()
 
 #===============================================================================
 # Library generation
 #===============================================================================
 add_library(akantu ${AKANTU_LIBRARY_SRCS})
 
 target_include_directories(akantu
   PRIVATE   $<BUILD_INTERFACE:${AKANTU_INCLUDE_DIRS}>
   INTERFACE $<INSTALL_INTERFACE:include/akantu>
   )
 
 # small trick for build includes in public
 set_property(TARGET akantu APPEND PROPERTY INTERFACE_INCLUDE_DIRECTORIES
   $<BUILD_INTERFACE:${AKANTU_INCLUDE_DIRS}>)
 
 target_include_directories(akantu SYSTEM
   PUBLIC ${AKANTU_INTERFACE_EXTERNAL_INCLUDE_DIR}
   )
 
 target_include_directories(akantu SYSTEM
   PRIVATE ${AKANTU_PRIVATE_EXTERNAL_INCLUDE_DIR}
   )
 
 target_link_libraries(akantu ${AKANTU_EXTERNAL_LIBRARIES})
 
 set_target_properties(akantu
   PROPERTIES
     ${AKANTU_LIBRARY_PROPERTIES} # this contains the version
     COMPILE_FLAGS "${_cxx_flags}"
 
     )
 
 if(NOT CMAKE_VERSION VERSION_LESS 3.1)
   package_get_all_features_public(_PUBLIC_features)
   package_get_all_features_private(_PRIVATE_features)
   foreach(_type PRIVATE PUBLIC)
     if(_${_type}_features)
       target_compile_features(akantu ${_type} ${_${_type}_features})
     endif()
   endforeach()
 else()
   set_target_properties(akantu
     PROPERTIES
     CXX_STANDARD 14
     )
 endif()
 
 package_get_all_extra_dependencies(_extra_target_dependencies)
 if(_extra_target_dependencies)
   # This only adding todo: find a solution for when a dependency was add the is removed...
   add_dependencies(akantu ${_extra_target_dependencies})
 endif()
 
 package_get_all_export_list(AKANTU_EXPORT_LIST)
 list(APPEND AKANTU_EXPORT_LIST akantu)
 
 # TODO separate public from private headers
 install(TARGETS akantu
   EXPORT ${AKANTU_TARGETS_EXPORT}
   LIBRARY DESTINATION lib COMPONENT lib
   ARCHIVE DESTINATION lib COMPONENT lib
   RUNTIME DESTINATION bin COMPONENT bin
   PUBLIC_HEADER DESTINATION include/akantu/ COMPONENT dev
   )
 
 if("${AKANTU_TARGETS_EXPORT}" STREQUAL "AkantuTargets")
   install(EXPORT AkantuTargets DESTINATION share/cmake/${PROJECT_NAME}
     COMPONENT dev)
 
   #Export for build tree
   export(EXPORT AkantuTargets
     FILE "${CMAKE_BINARY_DIR}/AkantuTargets.cmake")
   export(PACKAGE Akantu)
 endif()
 
 
 
 
 # print out the list of materials
 generate_material_list()
 
 register_target_to_tidy(akantu)
diff --git a/src/common/aka_array.cc b/src/common/aka_array.cc
index d014ca3ab..9c273ed17 100644
--- a/src/common/aka_array.cc
+++ b/src/common/aka_array.cc
@@ -1,124 +1,123 @@
 /**
  * @file   aka_array.cc
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Fri Jun 18 2010
- * @date last modification: Tue Aug 18 2015
+ * @date last modification: Tue Feb 20 2018
  *
  * @brief  Implementation of akantu::Array
  *
  * @section LICENSE
  *
- * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
- * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
- * Solides)
+ * 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
+ * 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
+ * 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 <memory>
 #include <utility>
 
 /* -------------------------------------------------------------------------- */
 #include "aka_array.hh"
 #include "aka_common.hh"
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 /* Functions ArrayBase                                                       */
 /* -------------------------------------------------------------------------- */
 ArrayBase::ArrayBase(ID id)
     : id(std::move(id)), allocated_size(0), size_(0), nb_component(1),
       size_of_type(0) {}
 
 /* -------------------------------------------------------------------------- */
 ArrayBase::~ArrayBase() = default;
 
 /* -------------------------------------------------------------------------- */
 void ArrayBase::printself(std::ostream & stream, int indent) const {
   std::string space;
   for (Int i = 0; i < indent; i++, space += AKANTU_INDENT)
     ;
   stream << space << "ArrayBase [" << std::endl;
   stream << space << " + size             : " << size_ << std::endl;
   stream << space << " + nb component     : " << nb_component << std::endl;
   stream << space << " + allocated size   : " << allocated_size << std::endl;
   Real mem_size = (allocated_size * nb_component * size_of_type) / 1024.;
   stream << space << " + size of type     : " << size_of_type << "B"
          << std::endl;
   stream << space << " + memory allocated : " << mem_size << "kB" << std::endl;
   stream << space << "]" << std::endl;
 }
 
 /* -------------------------------------------------------------------------- */
 template <> UInt Array<Real>::find(const Real & elem) const {
   AKANTU_DEBUG_IN();
 
   Real epsilon = std::numeric_limits<Real>::epsilon();
   auto it = std::find_if(begin(), end(), [&elem, &epsilon](auto && a) {
     return std::abs(a - elem) <= epsilon;
   });
 
   AKANTU_DEBUG_OUT();
   return (it != end()) ? end() - it : UInt(-1);
 }
 
 /* -------------------------------------------------------------------------- */
 template <>
 Array<ElementType> & Array<ElementType>::operator*=(__attribute__((unused))
                                                     const ElementType & alpha) {
   AKANTU_TO_IMPLEMENT();
   return *this;
 }
 
 template <>
 Array<ElementType> & Array<ElementType>::
 operator-=(__attribute__((unused)) const Array<ElementType> & vect) {
   AKANTU_TO_IMPLEMENT();
   return *this;
 }
 
 template <>
 Array<ElementType> & Array<ElementType>::
 operator+=(__attribute__((unused)) const Array<ElementType> & vect) {
   AKANTU_TO_IMPLEMENT();
   return *this;
 }
 
 template <>
 Array<char> & Array<char>::operator*=(__attribute__((unused))
                                       const char & alpha) {
   AKANTU_TO_IMPLEMENT();
   return *this;
 }
 
 template <>
 Array<char> & Array<char>::operator-=(__attribute__((unused))
                                       const Array<char> & vect) {
   AKANTU_TO_IMPLEMENT();
   return *this;
 }
 
 template <>
 Array<char> & Array<char>::operator+=(__attribute__((unused))
                                       const Array<char> & vect) {
   AKANTU_TO_IMPLEMENT();
   return *this;
 }
 
 } // namespace akantu
diff --git a/src/common/aka_array.hh b/src/common/aka_array.hh
index 518b2b062..a75bd18ed 100644
--- a/src/common/aka_array.hh
+++ b/src/common/aka_array.hh
@@ -1,372 +1,371 @@
 /**
  * @file   aka_array.hh
  *
  * @author Till Junge <till.junge@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Fri Jun 18 2010
- * @date last modification: Fri Jan 22 2016
+ * @date last modification: Tue Jan 16 2018
  *
  * @brief  Array container for Akantu
  * This container differs from the std::vector from the fact it as 2 dimensions
  * a main dimension and the size stored per entries
  *
  * @section LICENSE
  *
- * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
- * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
- * Solides)
+ * 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
+ * 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
+ * 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_VECTOR_HH__
 #define __AKANTU_VECTOR_HH__
 
 /* -------------------------------------------------------------------------- */
 #include "aka_common.hh"
 /* -------------------------------------------------------------------------- */
 #include <typeinfo>
 #include <vector>
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 
 /// class that afford to store vectors in static memory
 class ArrayBase {
   /* ------------------------------------------------------------------------ */
   /* Constructors/Destructors                                                 */
   /* ------------------------------------------------------------------------ */
 public:
   explicit ArrayBase(ID id = "");
 
   virtual ~ArrayBase();
 
   /* ------------------------------------------------------------------------ */
   /* Methods                                                                  */
   /* ------------------------------------------------------------------------ */
 public:
   /// get the amount of space allocated in bytes
   inline UInt getMemorySize() const;
 
   /// set the size to zero without freeing the allocated space
   inline void empty();
 
   /// function to print the containt of the class
   virtual void printself(std::ostream & stream, int indent = 0) const;
 
   /* ------------------------------------------------------------------------ */
   /* Accessors */
   /* ------------------------------------------------------------------------ */
 public:
   /// Get the real size allocated in memory
   AKANTU_GET_MACRO(AllocatedSize, allocated_size, UInt);
   /// Get the Size of the Array
   UInt getSize() const __attribute__((deprecated)) { return size_; }
   UInt size() const { return size_; }
   /// Get the number of components
   AKANTU_GET_MACRO(NbComponent, nb_component, UInt);
   /// Get the name of th array
   AKANTU_GET_MACRO(ID, id, const ID &);
   /// Set the name of th array
   AKANTU_SET_MACRO(ID, id, const ID &);
 
   /* ------------------------------------------------------------------------ */
   /* Class Members                                                            */
   /* ------------------------------------------------------------------------ */
 protected:
   /// id of the vector
   ID id;
 
   /// the size allocated
   UInt allocated_size{0};
 
   /// the size used
   UInt size_{0};
 
   /// number of components
   UInt nb_component{1};
 
   /// size of the stored type
   UInt size_of_type{0};
 };
 
 /* -------------------------------------------------------------------------- */
 namespace {
   template <std::size_t dim, typename T> struct IteratorHelper {};
 
   template <typename T> struct IteratorHelper<0, T> { using type = T; };
   template <typename T> struct IteratorHelper<1, T> { using type = Vector<T>; };
   template <typename T> struct IteratorHelper<2, T> { using type = Matrix<T>; };
   template <typename T> struct IteratorHelper<3, T> {
     using type = Tensor3<T>;
   };
 
   template <std::size_t dim, typename T>
   using IteratorHelper_t = typename IteratorHelper<dim, T>::type;
 } // namespace
 
 /* -------------------------------------------------------------------------- */
 template <typename T, bool is_scal> class Array : public ArrayBase {
   /* ------------------------------------------------------------------------ */
   /* Constructors/Destructors                                                 */
   /* ------------------------------------------------------------------------ */
 public:
   using value_type = T;
   using reference = value_type &;
   using pointer_type = value_type *;
   using const_reference = const value_type &;
 
   /// Allocation of a new vector
   explicit inline Array(UInt size = 0, UInt nb_component = 1,
                         const ID & id = "");
 
   /// Allocation of a new vector with a default value
   Array(UInt size, UInt nb_component, const value_type def_values[],
         const ID & id = "");
 
   /// Allocation of a new vector with a default value
   Array(UInt size, UInt nb_component, const_reference value,
         const ID & id = "");
 
   /// Copy constructor (deep copy if deep=true)
   Array(const Array<value_type, is_scal> & vect, bool deep = true,
         const ID & id = "");
 
 #ifndef SWIG
   /// Copy constructor (deep copy)
   explicit Array(const std::vector<value_type> & vect);
 #endif
 
   inline ~Array() override;
 
   Array & operator=(const Array & a) {
     /// this is to let STL allocate and copy arrays in the case of
     /// std::vector::resize
     AKANTU_DEBUG_ASSERT(this->size_ == 0, "Cannot copy akantu::Array");
     return const_cast<Array &>(a);
   }
 
 #ifndef SWIG
   /* ------------------------------------------------------------------------ */
   /* Iterator                                                                 */
   /* ------------------------------------------------------------------------ */
   /// \todo protected: does not compile with intel  check why
 public:
   template <class R, class it, class IR = R,
             bool is_tensor_ = is_tensor<R>::value>
   class iterator_internal;
 
 public:
   /* ------------------------------------------------------------------------ */
 
   /* ------------------------------------------------------------------------ */
   template <typename R = T> class const_iterator;
   template <typename R = T> class iterator;
 
   /* ------------------------------------------------------------------------ */
 
   /// iterator for Array of nb_component = 1
   using scalar_iterator = iterator<T>;
   /// const_iterator for Array of nb_component = 1
   using const_scalar_iterator = const_iterator<T>;
 
   /// iterator returning Vectors of size n  on entries of Array with
   /// nb_component = n
   using vector_iterator = iterator<Vector<T>>;
   /// const_iterator returning Vectors of n size on entries of Array with
   /// nb_component = n
   using const_vector_iterator = const_iterator<Vector<T>>;
 
   /// iterator returning Matrices of size (m, n) on entries of Array with
   /// nb_component = m*n
   using matrix_iterator = iterator<Matrix<T>>;
   /// const iterator returning Matrices of size (m, n) on entries of Array with
   /// nb_component = m*n
   using const_matrix_iterator = const_iterator<Matrix<T>>;
 
   /// iterator returning Tensor3 of size (m, n, k) on entries of Array with
   /// nb_component = m*n*k
   using tensor3_iterator = iterator<Tensor3<T>>;
   /// const iterator returning Tensor3 of size (m, n, k) on entries of Array
   /// with nb_component = m*n*k
   using const_tensor3_iterator = const_iterator<Tensor3<T>>;
 
   /* ------------------------------------------------------------------------ */
   template <typename... Ns> inline decltype(auto) begin(Ns &&... n);
   template <typename... Ns> inline decltype(auto) end(Ns &&... n);
 
   template <typename... Ns> inline decltype(auto) begin(Ns &&... n) const;
   template <typename... Ns> inline decltype(auto) end(Ns &&... n) const;
 
   template <typename... Ns> inline decltype(auto) begin_reinterpret(Ns &&... n);
   template <typename... Ns> inline decltype(auto) end_reinterpret(Ns &&... n);
 
   template <typename... Ns>
   inline decltype(auto) begin_reinterpret(Ns &&... n) const;
   template <typename... Ns>
   inline decltype(auto) end_reinterpret(Ns &&... n) const;
 #endif // SWIG
 
   /* ------------------------------------------------------------------------ */
   /* Methods                                                                  */
   /* ------------------------------------------------------------------------ */
 public:
   /// append a tuple of size nb_component containing value
   inline void push_back(const_reference value);
 /// append a vector
 // inline void push_back(const value_type new_elem[]);
 
 #ifndef SWIG
   /// append a Vector or a Matrix
   template <template <typename> class C,
             typename = std::enable_if_t<is_tensor<C<T>>::value>>
   inline void push_back(const C<T> & new_elem);
   /// append the value of the iterator
   template <typename Ret> inline void push_back(const iterator<Ret> & it);
 
   /// erase the value at position i
   inline void erase(UInt i);
   /// ask Nico, clarify
   template <typename R> inline iterator<R> erase(const iterator<R> & it);
 #endif
 
   /// changes the allocated size but not the size
   virtual void reserve(UInt size);
 
   /// change the size of the Array
   virtual void resize(UInt size);
 
   /// change the size of the Array and initialize the values
   virtual void resize(UInt size, const T & val);
 
   /// change the number of components by interlacing data
   /// @param multiplicator number of interlaced components add
   /// @param block_size blocks of data in the array
   /// Examaple for block_size = 2, multiplicator = 2
   /// array = oo oo oo -> new array = oo nn nn oo nn nn oo nn nn
   void extendComponentsInterlaced(UInt multiplicator, UInt stride);
 
   /// search elem in the vector, return  the position of the first occurrence or
   /// -1 if not found
   UInt find(const_reference elem) const;
 
   /// @see Array::find(const_reference elem) const
   UInt find(T elem[]) const;
 
 #ifndef SWIG
   /// @see Array::find(const_reference elem) const
   template <template <typename> class C,
             typename = std::enable_if_t<is_tensor<C<T>>::value>>
   inline UInt find(const C<T> & elem);
 #endif
 
   /// set all entries of the array to 0
   inline void clear() { std::fill_n(values, size_ * nb_component, T()); }
 
   /// set all entries of the array to the value t
   /// @param t value to fill the array with
   inline void set(T t) { std::fill_n(values, size_ * nb_component, t); }
 
 #ifndef SWIG
   /// set all tuples of the array to a given vector or matrix
   /// @param vm Matrix or Vector to fill the array with
   template <template <typename> class C,
             typename = std::enable_if_t<is_tensor<C<T>>::value>>
   inline void set(const C<T> & vm);
 #endif
 
   /// Append the content of the other array to the current one
   void append(const Array<T> & other);
 
   /// copy another Array in the current Array, the no_sanity_check allows you to
   /// force the copy in cases where you know what you do with two non matching
   /// Arrays in terms of n
   void copy(const Array<T, is_scal> & other, bool no_sanity_check = false);
 
   /// give the address of the memory allocated for this vector
   T * storage() const { return values; };
 
   /// function to print the containt of the class
   void printself(std::ostream & stream, int indent = 0) const override;
 
 protected:
   /// perform the allocation for the constructors
   void allocate(UInt size, UInt nb_component = 1);
 
   /// resize initializing with uninitialized_fill if fill is set
   void resizeUnitialized(UInt new_size, bool fill, const T & val = T());
 
   /* ------------------------------------------------------------------------ */
   /* Operators                                                                */
   /* ------------------------------------------------------------------------ */
 public:
   /// substraction entry-wise
   Array<T, is_scal> & operator-=(const Array<T, is_scal> & other);
   /// addition entry-wise
   Array<T, is_scal> & operator+=(const Array<T, is_scal> & other);
   /// multiply evry entry by alpha
   Array<T, is_scal> & operator*=(const T & alpha);
 
   /// check if the array are identical entry-wise
   bool operator==(const Array<T, is_scal> & other) const;
   /// @see Array::operator==(const Array<T, is_scal> & other) const
   bool operator!=(const Array<T, is_scal> & other) const;
 
   /// return a reference to the j-th entry of the i-th tuple
   inline reference operator()(UInt i, UInt j = 0);
   /// return a const reference to the j-th entry of the i-th tuple
   inline const_reference operator()(UInt i, UInt j = 0) const;
 
   /// return a reference to the ith component of the 1D array
   inline reference operator[](UInt i);
   /// return a const reference to the ith component of the 1D array
   inline const_reference operator[](UInt i) const;
 
   /* ------------------------------------------------------------------------ */
   /* Class Members                                                            */
   /* ------------------------------------------------------------------------ */
 protected:
   /// array of values
   T * values; // /!\ very dangerous
 };
 
 /* -------------------------------------------------------------------------- */
 /* Inline Functions Array<T, is_scal>                                         */
 /* -------------------------------------------------------------------------- */
 template <typename T, bool is_scal>
 inline std::ostream & operator<<(std::ostream & stream,
                                  const Array<T, is_scal> & _this) {
   _this.printself(stream);
   return stream;
 }
 
 /* -------------------------------------------------------------------------- */
 /* Inline Functions ArrayBase                                                 */
 /* -------------------------------------------------------------------------- */
 inline std::ostream & operator<<(std::ostream & stream,
                                  const ArrayBase & _this) {
   _this.printself(stream);
   return stream;
 }
 
 } // namespace akantu
 
 #include "aka_array_tmpl.hh"
 #include "aka_types.hh"
 
 #endif /* __AKANTU_VECTOR_HH__ */
diff --git a/src/common/aka_array_tmpl.hh b/src/common/aka_array_tmpl.hh
index 624536626..e5145384e 100644
--- a/src/common/aka_array_tmpl.hh
+++ b/src/common/aka_array_tmpl.hh
@@ -1,1278 +1,1278 @@
 /**
  * @file   aka_array_tmpl.hh
  *
+ * @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Thu Jul 15 2010
- * @date last modification: Fri Jan 22 2016
+ * @date last modification: Tue Feb 20 2018
  *
  * @brief  Inline functions of the classes Array<T> and ArrayBase
  *
  * @section LICENSE
  *
- * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
- * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
- * Solides)
+ * 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
+ * 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
+ * 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/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 /* Inline Functions Array<T>                                                 */
 /* -------------------------------------------------------------------------- */
 #include "aka_array.hh"
 /* -------------------------------------------------------------------------- */
 #include <memory>
 /* -------------------------------------------------------------------------- */
 
 #ifndef __AKANTU_AKA_ARRAY_TMPL_HH__
 #define __AKANTU_AKA_ARRAY_TMPL_HH__
 
 namespace akantu {
 
 namespace debug {
   struct ArrayException : public Exception {};
 } // namespace debug
 
 /* -------------------------------------------------------------------------- */
 template <class T, bool is_scal>
 inline T & Array<T, is_scal>::operator()(UInt i, UInt j) {
   AKANTU_DEBUG_ASSERT(size_ > 0, "The array \"" << id << "\" is empty");
   AKANTU_DEBUG_ASSERT((i < size_) && (j < nb_component),
                       "The value at position ["
                           << i << "," << j << "] is out of range in array \""
                           << id << "\"");
   return values[i * nb_component + j];
 }
 
 /* -------------------------------------------------------------------------- */
 template <class T, bool is_scal>
 inline const T & Array<T, is_scal>::operator()(UInt i, UInt j) const {
   AKANTU_DEBUG_ASSERT(size_ > 0, "The array \"" << id << "\" is empty");
   AKANTU_DEBUG_ASSERT((i < size_) && (j < nb_component),
                       "The value at position ["
                           << i << "," << j << "] is out of range in array \""
                           << id << "\"");
   return values[i * nb_component + j];
 }
 
 template <class T, bool is_scal>
 inline T & Array<T, is_scal>::operator[](UInt i) {
   AKANTU_DEBUG_ASSERT(size_ > 0, "The array \"" << id << "\" is empty");
   AKANTU_DEBUG_ASSERT((i < size_ * nb_component),
                       "The value at position ["
                           << i << "] is out of range in array \"" << id
                           << "\"");
   return values[i];
 }
 
 /* -------------------------------------------------------------------------- */
 template <class T, bool is_scal>
 inline const T & Array<T, is_scal>::operator[](UInt i) const {
   AKANTU_DEBUG_ASSERT(size_ > 0, "The array \"" << id << "\" is empty");
   AKANTU_DEBUG_ASSERT((i < size_ * nb_component),
                       "The value at position ["
                           << i << "] is out of range in array \"" << id
                           << "\"");
   return values[i];
 }
 
 /* -------------------------------------------------------------------------- */
 /**
  * append a tuple to the array with the value value for all components
  * @param value the new last tuple or the array will contain nb_component copies
  * of value
  */
 template <class T, bool is_scal>
 inline void Array<T, is_scal>::push_back(const T & value) {
   resizeUnitialized(size_ + 1, true, value);
 }
 
 /* -------------------------------------------------------------------------- */
 /**
  * append a tuple to the array
  * @param new_elem a C-array containing the values to be copied to the end of
  * the array */
 // template <class T, bool is_scal>
 // inline void Array<T, is_scal>::push_back(const T new_elem[]) {
 //   UInt pos = size_;
 
 //   resizeUnitialized(size_ + 1, false);
 
 //   T * tmp = values + nb_component * pos;
 //   std::uninitialized_copy(new_elem, new_elem + nb_component, tmp);
 // }
 
 /* -------------------------------------------------------------------------- */
 #ifndef SWIG
 /**
  * append a matrix or a vector to the array
  * @param new_elem a reference to a Matrix<T> or Vector<T> */
 template <class T, bool is_scal>
 template <template <typename> class C, typename>
 inline void Array<T, is_scal>::push_back(const C<T> & new_elem) {
   AKANTU_DEBUG_ASSERT(
       nb_component == new_elem.size(),
       "The vector("
           << new_elem.size()
           << ") as not a size compatible with the Array (nb_component="
           << nb_component << ").");
   UInt pos = size_;
   resizeUnitialized(size_ + 1, false);
 
   T * tmp = values + nb_component * pos;
   std::uninitialized_copy(new_elem.storage(), new_elem.storage() + nb_component,
                           tmp);
 }
 
 /* -------------------------------------------------------------------------- */
 /**
  * append a tuple to the array
  * @param it an iterator to the tuple to be copied to the end of the array */
 template <class T, bool is_scal>
 template <class Ret>
 inline void
 Array<T, is_scal>::push_back(const Array<T, is_scal>::iterator<Ret> & it) {
   UInt pos = size_;
 
   resizeUnitialized(size_ + 1, false);
 
   T * tmp = values + nb_component * pos;
   T * new_elem = it.data();
   std::uninitialized_copy(new_elem, new_elem + nb_component, tmp);
 }
 #endif
 /* -------------------------------------------------------------------------- */
 /**
  * erase an element. If the erased element is not the last of the array, the
  * last element is moved into the hole in order to maintain contiguity. This
  * may invalidate existing iterators (For instance an iterator obtained by
  * Array::end() is no longer correct) and will change the order of the
  * elements.
  * @param i index of element to erase
  */
 template <class T, bool is_scal> inline void Array<T, is_scal>::erase(UInt i) {
   AKANTU_DEBUG_IN();
   AKANTU_DEBUG_ASSERT((size_ > 0), "The array is empty");
   AKANTU_DEBUG_ASSERT((i < size_),
                       "The element at position [" << i << "] is out of range ("
                                                   << i << ">=" << size_ << ")");
 
   if (i != (size_ - 1)) {
     for (UInt j = 0; j < nb_component; ++j) {
       values[i * nb_component + j] = values[(size_ - 1) * nb_component + j];
     }
   }
 
   resize(size_ - 1);
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 /**
  * Subtract another array entry by entry from this array in place. Both arrays
  * must
  * have the same size and nb_component. If the arrays have different shapes,
  * code compiled in debug mode will throw an expeption and optimised code
  * will behave in an unpredicted manner
  * @param other array to subtract from this
  * @return reference to modified this
  */
 template <class T, bool is_scal>
 Array<T, is_scal> & Array<T, is_scal>::
 operator-=(const Array<T, is_scal> & vect) {
   AKANTU_DEBUG_ASSERT((size_ == vect.size_) &&
                           (nb_component == vect.nb_component),
                       "The too array don't have the same sizes");
 
   T * a = values;
   T * b = vect.storage();
   for (UInt i = 0; i < size_ * nb_component; ++i) {
     *a -= *b;
     ++a;
     ++b;
   }
 
   return *this;
 }
 
 /* -------------------------------------------------------------------------- */
 /**
  * Add another array entry by entry to this array in place. Both arrays must
  * have the same size and nb_component. If the arrays have different shapes,
  * code compiled in debug mode will throw an expeption and optimised code
  * will behave in an unpredicted manner
  * @param other array to add to this
  * @return reference to modified this
  */
 template <class T, bool is_scal>
 Array<T, is_scal> & Array<T, is_scal>::
 operator+=(const Array<T, is_scal> & vect) {
   AKANTU_DEBUG_ASSERT((size_ == vect.size()) &&
                           (nb_component == vect.nb_component),
                       "The too array don't have the same sizes");
 
   T * a = values;
   T * b = vect.storage();
   for (UInt i = 0; i < size_ * nb_component; ++i) {
     *a++ += *b++;
   }
 
   return *this;
 }
 
 /* -------------------------------------------------------------------------- */
 /**
  * Multiply all entries of this array by a scalar in place
  * @param alpha scalar multiplicant
  * @return reference to modified this
  */
 
 #ifndef SWIG
 template <class T, bool is_scal>
 Array<T, is_scal> & Array<T, is_scal>::operator*=(const T & alpha) {
   T * a = values;
   for (UInt i = 0; i < size_ * nb_component; ++i) {
     *a++ *= alpha;
   }
 
   return *this;
 }
 #endif
 
 /* -------------------------------------------------------------------------- */
 /**
  * Compare this array element by element to another.
  * @param other array to compare to
  * @return true it all element are equal and arrays have the same shape, else
  * false
  */
 template <class T, bool is_scal>
 bool Array<T, is_scal>::operator==(const Array<T, is_scal> & array) const {
   bool equal = nb_component == array.nb_component && size_ == array.size_ &&
                id == array.id;
   if (!equal)
     return false;
 
   if (values == array.storage())
     return true;
   else
     return std::equal(values, values + size_ * nb_component, array.storage());
 }
 
 /* -------------------------------------------------------------------------- */
 template <class T, bool is_scal>
 bool Array<T, is_scal>::operator!=(const Array<T, is_scal> & array) const {
   return !operator==(array);
 }
 
 /* -------------------------------------------------------------------------- */
 #ifndef SWIG
 /**
  * set all tuples of the array to a given vector or matrix
  * @param vm Matrix or Vector to fill the array with
  */
 template <class T, bool is_scal>
 template <template <typename> class C, typename>
 inline void Array<T, is_scal>::set(const C<T> & vm) {
   AKANTU_DEBUG_ASSERT(
       nb_component == vm.size(),
       "The size of the object does not match the number of components");
   for (T * it = values; it < values + nb_component * size_;
        it += nb_component) {
     std::copy(vm.storage(), vm.storage() + nb_component, it);
   }
 }
 #endif
 /* -------------------------------------------------------------------------- */
 template <class T, bool is_scal>
 void Array<T, is_scal>::append(const Array<T> & other) {
   AKANTU_DEBUG_ASSERT(
       nb_component == other.nb_component,
       "Cannot append an array with a different number of component");
   UInt old_size = this->size_;
   this->resizeUnitialized(this->size_ + other.size(), false);
 
   T * tmp = values + nb_component * old_size;
   std::uninitialized_copy(other.storage(),
                           other.storage() + other.size() * nb_component, tmp);
 }
 
 /* -------------------------------------------------------------------------- */
 /* Functions Array<T, is_scal>                                                */
 /* -------------------------------------------------------------------------- */
 template <class T, bool is_scal>
 Array<T, is_scal>::Array(UInt size, UInt nb_component, const ID & id)
     : ArrayBase(id), values(nullptr) {
   AKANTU_DEBUG_IN();
   allocate(size, nb_component);
 
   if (!is_scal) {
     T val = T();
     std::uninitialized_fill(values, values + size * nb_component, val);
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <class T, bool is_scal>
 Array<T, is_scal>::Array(UInt size, UInt nb_component, const T def_values[],
                          const ID & id)
     : ArrayBase(id), values(NULL) {
   AKANTU_DEBUG_IN();
   allocate(size, nb_component);
 
   T * tmp = values;
 
   for (UInt i = 0; i < size; ++i) {
     tmp = values + nb_component * i;
     std::uninitialized_copy(def_values, def_values + nb_component, tmp);
   }
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <class T, bool is_scal>
 Array<T, is_scal>::Array(UInt size, UInt nb_component, const T & value,
                          const ID & id)
     : ArrayBase(id), values(nullptr) {
   AKANTU_DEBUG_IN();
   allocate(size, nb_component);
 
   std::uninitialized_fill_n(values, size * nb_component, value);
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <class T, bool is_scal>
 Array<T, is_scal>::Array(const Array<T, is_scal> & vect, bool deep,
                          const ID & id)
     : ArrayBase(vect) {
   AKANTU_DEBUG_IN();
   this->id = (id == "") ? vect.id : id;
 
   if (deep) {
     allocate(vect.size_, vect.nb_component);
     T * tmp = values;
     std::uninitialized_copy(vect.storage(),
                             vect.storage() + size_ * nb_component, tmp);
   } else {
     this->values = vect.storage();
     this->size_ = vect.size_;
     this->nb_component = vect.nb_component;
     this->allocated_size = vect.allocated_size;
     this->size_of_type = vect.size_of_type;
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 #ifndef SWIG
 template <class T, bool is_scal>
 Array<T, is_scal>::Array(const std::vector<T> & vect) {
   AKANTU_DEBUG_IN();
   this->id = "";
 
   allocate(vect.size(), 1);
   T * tmp = values;
   std::uninitialized_copy(&(vect[0]), &(vect[size_ - 1]), tmp);
 
   AKANTU_DEBUG_OUT();
 }
 #endif
 
 /* -------------------------------------------------------------------------- */
 template <class T, bool is_scal> Array<T, is_scal>::~Array() {
   AKANTU_DEBUG_IN();
   AKANTU_DEBUG(dblAccessory,
                "Freeing " << printMemorySize<T>(allocated_size * nb_component)
                           << " (" << id << ")");
 
   if (values) {
     if (!is_scal)
       for (UInt i = 0; i < size_ * nb_component; ++i) {
         T * obj = values + i;
         obj->~T();
       }
     free(values);
   }
   size_ = allocated_size = 0;
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 /**
  * perform the allocation for the constructors
  * @param size is the size of the array
  * @param nb_component is the number of component of the array
  */
 template <class T, bool is_scal>
 void Array<T, is_scal>::allocate(UInt size, UInt nb_component) {
   AKANTU_DEBUG_IN();
   if (size == 0) {
     values = nullptr;
   } else {
     values = static_cast<T *>(malloc(nb_component * size * sizeof(T)));
     AKANTU_DEBUG_ASSERT(values != nullptr,
                         "Cannot allocate "
                             << printMemorySize<T>(size * nb_component) << " ("
                             << id << ")");
   }
 
   if (values == nullptr) {
     this->size_ = this->allocated_size = 0;
   } else {
     AKANTU_DEBUG(dblAccessory,
                  "Allocated " << printMemorySize<T>(size * nb_component) << " ("
                               << id << ")");
     this->size_ = this->allocated_size = size;
   }
 
   this->size_of_type = sizeof(T);
   this->nb_component = nb_component;
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <class T, bool is_scal>
 void Array<T, is_scal>::reserve(UInt new_size) {
   UInt tmp_size = this->size_;
   resizeUnitialized(new_size, false);
   this->size_ = tmp_size;
 }
 
 /* -------------------------------------------------------------------------- */
 /**
  * change the size of the array and allocate or free memory if needed. If the
  * size increases, the new tuples are filled with zeros
  * @param new_size new number of tuples contained in the array */
 template <class T, bool is_scal> void Array<T, is_scal>::resize(UInt new_size) {
   resizeUnitialized(new_size, !is_scal);
 }
 
 /* -------------------------------------------------------------------------- */
 /**
  * change the size of the array and allocate or free memory if needed. If the
  * size increases, the new tuples are filled with zeros
  * @param new_size new number of tuples contained in the array */
 template <class T, bool is_scal>
 void Array<T, is_scal>::resize(UInt new_size, const T & val) {
   this->resizeUnitialized(new_size, true, val);
 }
 
 /* -------------------------------------------------------------------------- */
 /**
  * change the size of the array and allocate or free memory if needed.
  * @param new_size new number of tuples contained in the array */
 template <class T, bool is_scal>
 void Array<T, is_scal>::resizeUnitialized(UInt new_size, bool fill,
                                           const T & val) {
   //  AKANTU_DEBUG_IN();
   // free some memory
   if (new_size <= allocated_size) {
     if (!is_scal) {
       T * old_values = values;
       if (new_size < size_) {
         for (UInt i = new_size * nb_component; i < size_ * nb_component; ++i) {
           T * obj = old_values + i;
           obj->~T();
         }
       }
     }
 
     if (allocated_size - new_size > AKANTU_MIN_ALLOCATION) {
       AKANTU_DEBUG(dblAccessory,
                    "Freeing " << printMemorySize<T>((allocated_size - size_) *
                                                     nb_component)
                               << " (" << id << ")");
 
       // Normally there are no allocation problem when reducing an array
       if (new_size == 0) {
         free(values);
         values = nullptr;
       } else {
         auto * tmp_ptr = static_cast<T *>(
             realloc(values, new_size * nb_component * sizeof(T)));
 
         if (tmp_ptr == nullptr) {
           AKANTU_EXCEPTION("Cannot free data ("
                            << id << ")"
                            << " [current allocated size : " << allocated_size
                            << " | "
                            << "requested size : " << new_size << "]");
         }
         values = tmp_ptr;
       }
       allocated_size = new_size;
     }
   } else {
     // allocate more memory
     UInt size_to_alloc = (new_size - allocated_size < AKANTU_MIN_ALLOCATION)
                              ? allocated_size + AKANTU_MIN_ALLOCATION
                              : new_size;
 
     auto * tmp_ptr = static_cast<T *>(
         realloc(values, size_to_alloc * nb_component * sizeof(T)));
     AKANTU_DEBUG_ASSERT(
         tmp_ptr != nullptr,
         "Cannot allocate " << printMemorySize<T>(size_to_alloc * nb_component));
     if (tmp_ptr == nullptr) {
       AKANTU_ERROR("Cannot allocate more data ("
                    << id << ")"
                    << " [current allocated size : " << allocated_size << " | "
                    << "requested size : " << new_size << "]");
     }
 
     AKANTU_DEBUG(dblAccessory,
                  "Allocating " << printMemorySize<T>(
                      (size_to_alloc - allocated_size) * nb_component));
 
     allocated_size = size_to_alloc;
     values = tmp_ptr;
   }
 
   if (fill && this->size_ < new_size) {
     std::uninitialized_fill(values + size_ * nb_component,
                             values + new_size * nb_component, val);
   }
 
   size_ = new_size;
   //  AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 /**
  * change the number of components by interlacing data
  * @param multiplicator number of interlaced components add
  * @param block_size blocks of data in the array
  * Examaple for block_size = 2, multiplicator = 2
  * array = oo oo oo -> new array = oo nn nn oo nn nn oo nn nn */
 template <class T, bool is_scal>
 void Array<T, is_scal>::extendComponentsInterlaced(UInt multiplicator,
                                                    UInt block_size) {
   AKANTU_DEBUG_IN();
 
   if (multiplicator == 1)
     return;
 
   AKANTU_DEBUG_ASSERT(multiplicator > 1, "invalid multiplicator");
   AKANTU_DEBUG_ASSERT(nb_component % block_size == 0,
                       "stride must divide actual number of components");
 
   values = static_cast<T *>(
       realloc(values, nb_component * multiplicator * size_ * sizeof(T)));
 
   UInt new_component = nb_component / block_size * multiplicator;
 
   for (UInt i = 0, k = size_ - 1; i < size_; ++i, --k) {
     for (UInt j = 0; j < new_component; ++j) {
       UInt m = new_component - j - 1;
       UInt n = m / multiplicator;
       for (UInt l = 0, p = block_size - 1; l < block_size; ++l, --p) {
         values[k * nb_component * multiplicator + m * block_size + p] =
             values[k * nb_component + n * block_size + p];
       }
     }
   }
 
   nb_component = nb_component * multiplicator;
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 /**
  * search elem in the array, return  the position of the first occurrence or
  * -1 if not found
  *  @param elem the element to look for
  *  @return index of the first occurrence of elem or -1 if elem is not present
  */
 template <class T, bool is_scal>
 UInt Array<T, is_scal>::find(const T & elem) const {
   AKANTU_DEBUG_IN();
 
   auto begin = this->begin();
   auto end = this->end();
   auto it = std::find(begin, end, elem);
 
   AKANTU_DEBUG_OUT();
   return (it != end) ? it - begin : UInt(-1);
 }
 
 /* -------------------------------------------------------------------------- */
 template <class T, bool is_scal> UInt Array<T, is_scal>::find(T elem[]) const {
   AKANTU_DEBUG_IN();
   T * it = values;
   UInt i = 0;
   for (; i < size_; ++i) {
     if (*it == elem[0]) {
       T * cit = it;
       UInt c = 0;
       for (; (c < nb_component) && (*cit == elem[c]); ++c, ++cit)
         ;
       if (c == nb_component) {
         AKANTU_DEBUG_OUT();
         return i;
       }
     }
     it += nb_component;
   }
   return UInt(-1);
 }
 
 /* -------------------------------------------------------------------------- */
 template <class T, bool is_scal>
 template <template <typename> class C, typename>
 inline UInt Array<T, is_scal>::find(const C<T> & elem) {
   AKANTU_DEBUG_ASSERT(elem.size() == nb_component,
                       "Cannot find an element with a wrong size ("
                           << elem.size() << ") != " << nb_component);
   return this->find(elem.storage());
 }
 
 /* -------------------------------------------------------------------------- */
 /**
  * copy the content of another array. This overwrites the current content.
  * @param other Array to copy into this array. It has to have the same
  * nb_component as this. If compiled in debug mode, an incorrect other will
  * result in an exception being thrown. Optimised code may result in
  * unpredicted behaviour.
  */
 template <class T, bool is_scal>
 void Array<T, is_scal>::copy(const Array<T, is_scal> & vect,
                              bool no_sanity_check) {
   AKANTU_DEBUG_IN();
 
   if (!no_sanity_check)
     if (vect.nb_component != nb_component)
       AKANTU_ERROR("The two arrays do not have the same number of components");
 
   resize((vect.size_ * vect.nb_component) / nb_component);
 
   T * tmp = values;
   std::uninitialized_copy(vect.storage(), vect.storage() + size_ * nb_component,
                           tmp);
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <bool is_scal> class ArrayPrintHelper {
 public:
   template <typename T>
   static void print_content(const Array<T> & vect, std::ostream & stream,
                             int indent) {
     if (AKANTU_DEBUG_TEST(dblDump) || AKANTU_DEBUG_LEVEL_IS_TEST()) {
       std::string space;
       for (Int i = 0; i < indent; i++, space += AKANTU_INDENT)
         ;
 
       stream << space << " + values         : {";
       for (UInt i = 0; i < vect.size(); ++i) {
         stream << "{";
         for (UInt j = 0; j < vect.getNbComponent(); ++j) {
           stream << vect(i, j);
           if (j != vect.getNbComponent() - 1)
             stream << ", ";
         }
         stream << "}";
         if (i != vect.size() - 1)
           stream << ", ";
       }
       stream << "}" << std::endl;
     }
   }
 };
 
 template <> class ArrayPrintHelper<false> {
 public:
   template <typename T>
   static void print_content(__attribute__((unused)) const Array<T> & vect,
                             __attribute__((unused)) std::ostream & stream,
                             __attribute__((unused)) int indent) {}
 };
 
 /* -------------------------------------------------------------------------- */
 template <class T, bool is_scal>
 void Array<T, is_scal>::printself(std::ostream & stream, int indent) const {
   std::string space;
   for (Int i = 0; i < indent; i++, space += AKANTU_INDENT)
     ;
 
   std::streamsize prec = stream.precision();
   std::ios_base::fmtflags ff = stream.flags();
 
   stream.setf(std::ios_base::showbase);
   stream.precision(2);
 
   stream << space << "Array<" << debug::demangle(typeid(T).name()) << "> ["
          << std::endl;
   stream << space << " + id             : " << this->id << std::endl;
   stream << space << " + size           : " << this->size_ << std::endl;
   stream << space << " + nb_component   : " << this->nb_component << std::endl;
   stream << space << " + allocated size : " << this->allocated_size
          << std::endl;
   stream << space << " + memory size    : "
          << printMemorySize<T>(allocated_size * nb_component) << std::endl;
   if (!AKANTU_DEBUG_LEVEL_IS_TEST())
     stream << space << " + address        : " << std::hex << this->values
            << std::dec << std::endl;
 
   stream.precision(prec);
   stream.flags(ff);
 
   ArrayPrintHelper<is_scal>::print_content(*this, stream, indent);
 
   stream << space << "]" << std::endl;
 }
 
 /* -------------------------------------------------------------------------- */
 /* Inline Functions ArrayBase                                                */
 /* -------------------------------------------------------------------------- */
 
 inline UInt ArrayBase::getMemorySize() const {
   return allocated_size * nb_component * size_of_type;
 }
 
 inline void ArrayBase::empty() { size_ = 0; }
 
 #ifndef SWIG
 /* -------------------------------------------------------------------------- */
 /* Iterators                                                                  */
 /* -------------------------------------------------------------------------- */
 template <class T, bool is_scal>
 template <class R, class daughter, class IR, bool is_tensor>
 class Array<T, is_scal>::iterator_internal {
 public:
   using value_type = R;
   using pointer = R *;
   using reference = R &;
   using proxy = typename R::proxy;
   using const_proxy = const typename R::proxy;
   using const_reference = const R &;
   using internal_value_type = IR;
   using internal_pointer = IR *;
   using difference_type = std::ptrdiff_t;
   using iterator_category = std::random_access_iterator_tag;
 
 public:
   iterator_internal() = default;
 
   iterator_internal(pointer_type data, UInt _offset)
       : _offset(_offset), initial(data), ret(nullptr), ret_ptr(data) {
     AKANTU_ERROR(
         "The constructor should never be called it is just an ugly trick...");
   }
 
   iterator_internal(std::unique_ptr<internal_value_type> && wrapped)
       : _offset(wrapped->size()), initial(wrapped->storage()),
         ret(std::move(wrapped)), ret_ptr(ret->storage()) {}
 
   iterator_internal(const iterator_internal & it) {
     if (this != &it) {
       this->_offset = it._offset;
       this->initial = it.initial;
       this->ret_ptr = it.ret_ptr;
       this->ret = std::make_unique<internal_value_type>(*it.ret, false);
     }
   }
 
   iterator_internal(iterator_internal && it) = default;
 
   virtual ~iterator_internal() = default;
 
   inline iterator_internal & operator=(const iterator_internal & it) {
     if (this != &it) {
       this->_offset = it._offset;
       this->initial = it.initial;
       this->ret_ptr = it.ret_ptr;
       if (this->ret)
         this->ret->shallowCopy(*it.ret);
       else
         this->ret = std::make_unique<internal_value_type>(*it.ret, false);
     }
     return *this;
   }
 
   UInt getCurrentIndex() {
     return (this->ret_ptr - this->initial) / this->_offset;
   };
 
   inline reference operator*() {
     ret->values = ret_ptr;
     return *ret;
   };
   inline const_reference operator*() const {
     ret->values = ret_ptr;
     return *ret;
   };
   inline pointer operator->() {
     ret->values = ret_ptr;
     return ret.get();
   };
   inline daughter & operator++() {
     ret_ptr += _offset;
     return static_cast<daughter &>(*this);
   };
   inline daughter & operator--() {
     ret_ptr -= _offset;
     return static_cast<daughter &>(*this);
   };
 
   inline daughter & operator+=(const UInt n) {
     ret_ptr += _offset * n;
     return static_cast<daughter &>(*this);
   }
   inline daughter & operator-=(const UInt n) {
     ret_ptr -= _offset * n;
     return static_cast<daughter &>(*this);
   }
 
   inline proxy operator[](const UInt n) {
     ret->values = ret_ptr + n * _offset;
     return proxy(*ret);
   }
   inline const_proxy operator[](const UInt n) const {
     ret->values = ret_ptr + n * _offset;
     return const_proxy(*ret);
   }
 
   inline bool operator==(const iterator_internal & other) const {
     return this->ret_ptr == other.ret_ptr;
   }
   inline bool operator!=(const iterator_internal & other) const {
     return this->ret_ptr != other.ret_ptr;
   }
   inline bool operator<(const iterator_internal & other) const {
     return this->ret_ptr < other.ret_ptr;
   }
   inline bool operator<=(const iterator_internal & other) const {
     return this->ret_ptr <= other.ret_ptr;
   }
   inline bool operator>(const iterator_internal & other) const {
     return this->ret_ptr > other.ret_ptr;
   }
   inline bool operator>=(const iterator_internal & other) const {
     return this->ret_ptr >= other.ret_ptr;
   }
 
   inline daughter operator+(difference_type n) {
     daughter tmp(static_cast<daughter &>(*this));
     tmp += n;
     return tmp;
   }
   inline daughter operator-(difference_type n) {
     daughter tmp(static_cast<daughter &>(*this));
     tmp -= n;
     return tmp;
   }
 
   inline difference_type operator-(const iterator_internal & b) {
     return (this->ret_ptr - b.ret_ptr) / _offset;
   }
 
   inline pointer_type data() const { return ret_ptr; }
   inline difference_type offset() const { return _offset; }
 
 protected:
   UInt _offset{0};
   pointer_type initial{nullptr};
   std::unique_ptr<internal_value_type> ret{nullptr};
   pointer_type ret_ptr{nullptr};
 };
 
 /* -------------------------------------------------------------------------- */
 /**
  * Specialization for scalar types
  */
 template <class T, bool is_scal>
 template <class R, class daughter, class IR>
 class Array<T, is_scal>::iterator_internal<R, daughter, IR, false> {
 public:
   using value_type = R;
   using pointer = R *;
   using reference = R &;
   using const_reference = const R &;
   using internal_value_type = IR;
   using internal_pointer = IR *;
   using difference_type = std::ptrdiff_t;
   using iterator_category = std::random_access_iterator_tag;
 
 public:
   iterator_internal(pointer data = nullptr) : ret(data), initial(data){};
   iterator_internal(const iterator_internal & it) = default;
   iterator_internal(iterator_internal && it) = default;
 
   virtual ~iterator_internal() = default;
 
   inline iterator_internal & operator=(const iterator_internal & it) = default;
 
   UInt getCurrentIndex() { return (this->ret - this->initial); };
 
   inline reference operator*() { return *ret; };
   inline const_reference operator*() const { return *ret; };
   inline pointer operator->() { return ret; };
   inline daughter & operator++() {
     ++ret;
     return static_cast<daughter &>(*this);
   };
   inline daughter & operator--() {
     --ret;
     return static_cast<daughter &>(*this);
   };
 
   inline daughter & operator+=(const UInt n) {
     ret += n;
     return static_cast<daughter &>(*this);
   }
   inline daughter & operator-=(const UInt n) {
     ret -= n;
     return static_cast<daughter &>(*this);
   }
 
   inline reference operator[](const UInt n) { return ret[n]; }
 
   inline bool operator==(const iterator_internal & other) const {
     return ret == other.ret;
   }
   inline bool operator!=(const iterator_internal & other) const {
     return ret != other.ret;
   }
   inline bool operator<(const iterator_internal & other) const {
     return ret < other.ret;
   }
   inline bool operator<=(const iterator_internal & other) const {
     return ret <= other.ret;
   }
   inline bool operator>(const iterator_internal & other) const {
     return ret > other.ret;
   }
   inline bool operator>=(const iterator_internal & other) const {
     return ret >= other.ret;
   }
 
   inline daughter operator-(difference_type n) { return daughter(ret - n); }
   inline daughter operator+(difference_type n) { return daughter(ret + n); }
 
   inline difference_type operator-(const iterator_internal & b) {
     return ret - b.ret;
   }
 
   inline pointer data() const { return ret; }
 
 protected:
   pointer ret{nullptr};
   pointer initial{nullptr};
 };
 
 /* -------------------------------------------------------------------------- */
 /* Begin/End functions implementation                                         */
 /* -------------------------------------------------------------------------- */
 namespace detail {
   template <class Tuple, size_t... Is>
   constexpr auto take_front_impl(Tuple && t, std::index_sequence<Is...>) {
     return std::make_tuple(std::get<Is>(std::forward<Tuple>(t))...);
   }
 
   template <size_t N, class Tuple> constexpr auto take_front(Tuple && t) {
     return take_front_impl(std::forward<Tuple>(t),
                            std::make_index_sequence<N>{});
   }
 
   template <typename... V> constexpr auto product_all(V &&... v) {
     std::common_type_t<int, V...> result = 1;
     (void)std::initializer_list<int>{(result *= v, 0)...};
     return result;
   }
 
   template <typename... T> std::string to_string_all(T &&... t) {
     if (sizeof...(T) == 0)
       return "";
 
     std::stringstream ss;
     bool noComma = true;
     ss << "(";
     (void)std::initializer_list<bool>{
         (ss << (noComma ? "" : ", ") << t, noComma = false)...};
     ss << ")";
     return ss.str();
   }
 
   template <std::size_t N> struct InstantiationHelper {
     template <typename type, typename T, typename... Ns>
     static auto instantiate(T && data, Ns... ns) {
       return std::make_unique<type>(data, ns...);
     }
   };
 
   template <> struct InstantiationHelper<0> {
     template <typename type, typename T> static auto instantiate(T && data) {
       return data;
     }
   };
 
   template <typename Arr, typename T, typename... Ns>
   decltype(auto) get_iterator(Arr && array, T * data, Ns &&... ns) {
     using type = IteratorHelper_t<sizeof...(Ns) - 1, T>;
     using array_type = std::decay_t<Arr>;
     using iterator =
         std::conditional_t<std::is_const<std::remove_reference_t<Arr>>::value,
                            typename array_type::template const_iterator<type>,
                            typename array_type::template iterator<type>>;
     static_assert(sizeof...(Ns), "You should provide a least one size");
 
     if (array.getNbComponent() * array.size() !=
         product_all(std::forward<Ns>(ns)...)) {
       AKANTU_CUSTOM_EXCEPTION_INFO(
           debug::ArrayException(),
           "The iterator on "
               << debug::demangle(typeid(Arr).name())
               << to_string_all(array.size(), array.getNbComponent())
               << "is not compatible with the type "
               << debug::demangle(typeid(type).name()) << to_string_all(ns...));
     }
 
     auto && wrapped = aka::apply(
         [&](auto... n) {
           return InstantiationHelper<sizeof...(n)>::template instantiate<type>(
               data, n...);
         },
         take_front<sizeof...(Ns) - 1>(std::make_tuple(ns...)));
 
     return iterator(std::move(wrapped));
   }
 } // namespace detail
 
 /* -------------------------------------------------------------------------- */
 template <class T, bool is_scal>
 template <typename... Ns>
 inline decltype(auto) Array<T, is_scal>::begin(Ns &&... ns) {
   return detail::get_iterator(*this, values, std::forward<Ns>(ns)..., size_);
 }
 
 template <class T, bool is_scal>
 template <typename... Ns>
 inline decltype(auto) Array<T, is_scal>::end(Ns &&... ns) {
   return detail::get_iterator(*this, values + nb_component * size_,
                               std::forward<Ns>(ns)..., size_);
 }
 
 template <class T, bool is_scal>
 template <typename... Ns>
 inline decltype(auto) Array<T, is_scal>::begin(Ns &&... ns) const {
   return detail::get_iterator(*this, values, std::forward<Ns>(ns)..., size_);
 }
 
 template <class T, bool is_scal>
 template <typename... Ns>
 inline decltype(auto) Array<T, is_scal>::end(Ns &&... ns) const {
   return detail::get_iterator(*this, values + nb_component * size_,
                               std::forward<Ns>(ns)..., size_);
 }
 
 template <class T, bool is_scal>
 template <typename... Ns>
 inline decltype(auto) Array<T, is_scal>::begin_reinterpret(Ns &&... ns) {
   return detail::get_iterator(*this, values, std::forward<Ns>(ns)...);
 }
 
 template <class T, bool is_scal>
 template <typename... Ns>
 inline decltype(auto) Array<T, is_scal>::end_reinterpret(Ns &&... ns) {
   return detail::get_iterator(
       *this, values + detail::product_all(std::forward<Ns>(ns)...),
       std::forward<Ns>(ns)...);
 }
 
 template <class T, bool is_scal>
 template <typename... Ns>
 inline decltype(auto) Array<T, is_scal>::begin_reinterpret(Ns &&... ns) const {
   return detail::get_iterator(*this, values, std::forward<Ns>(ns)...);
 }
 
 template <class T, bool is_scal>
 template <typename... Ns>
 inline decltype(auto) Array<T, is_scal>::end_reinterpret(Ns &&... ns) const {
   return detail::get_iterator(
       *this, values + detail::product_all(std::forward<Ns>(ns)...),
       std::forward<Ns>(ns)...);
 }
 
 /* -------------------------------------------------------------------------- */
 /* Views                                                                      */
 /* -------------------------------------------------------------------------- */
 namespace detail {
   template <typename Array, typename... Ns> class ArrayView {
     using tuple = std::tuple<Ns...>;
 
   public:
     ArrayView(Array && array, Ns... ns)
         : array(std::forward<Array>(array)), sizes(std::move(ns)...) {}
 
     ArrayView(ArrayView && array_view) = default;
 
     ArrayView & operator=(const ArrayView & array_view) = default;
     ArrayView & operator=(ArrayView && array_view) = default;
 
     decltype(auto) begin() {
       return aka::apply(
           [&](auto &&... ns) { return array.begin_reinterpret(ns...); }, sizes);
     }
 
     decltype(auto) begin() const {
       return aka::apply(
           [&](auto &&... ns) { return array.begin_reinterpret(ns...); }, sizes);
     }
 
     decltype(auto) end() {
       return aka::apply(
           [&](auto &&... ns) { return array.end_reinterpret(ns...); }, sizes);
     }
 
     decltype(auto) end() const {
       return aka::apply(
           [&](auto &&... ns) { return array.end_reinterpret(ns...); }, sizes);
     }
 
     decltype(auto) size() const {
       return std::get<std::tuple_size<tuple>::value - 1>(sizes);
     }
 
     decltype(auto) dims() const { return std::tuple_size<tuple>::value - 1; }
 
   private:
     Array array;
     tuple sizes;
   };
 } // namespace detail
 
 /* -------------------------------------------------------------------------- */
 template <typename Array, typename... Ns>
 decltype(auto) make_view(Array && array, Ns... ns) {
   static_assert(aka::conjunction<std::is_integral<std::decay_t<Ns>>...>::value,
                 "Ns should be integral types");
   auto size = std::forward<decltype(array)>(array).size() *
               std::forward<decltype(array)>(array).getNbComponent() /
               detail::product_all(ns...);
 
   return detail::ArrayView<Array, std::common_type_t<size_t, Ns>...,
                            std::common_type_t<size_t, decltype(size)>>(
       std::forward<Array>(array), std::move(ns)..., size);
 }
 
 /* -------------------------------------------------------------------------- */
 template <class T, bool is_scal>
 template <typename R>
 class Array<T, is_scal>::const_iterator
     : public iterator_internal<const R, Array<T, is_scal>::const_iterator<R>,
                                R> {
 public:
   using parent = iterator_internal<const R, const_iterator, R>;
   using value_type = typename parent::value_type;
   using pointer = typename parent::pointer;
   using reference = typename parent::reference;
   using difference_type = typename parent::difference_type;
   using iterator_category = typename parent::iterator_category;
 
 public:
   const_iterator() : parent(){};
   // const_iterator(pointer_type data, UInt offset) : parent(data, offset) {}
   // const_iterator(pointer warped) : parent(warped) {}
   // const_iterator(const parent & it) : parent(it) {}
 
   const_iterator(const const_iterator & it) = default;
   const_iterator(const_iterator && it) = default;
 
   template <typename P, typename = std::enable_if_t<not is_tensor<P>::value>>
   const_iterator(P * data) : parent(data) {}
 
   template <typename UP_P,
             typename =
                 std::enable_if_t<is_tensor<typename UP_P::element_type>::value>>
   const_iterator(UP_P && tensor) : parent(std::forward<UP_P>(tensor)) {}
 
   const_iterator & operator=(const const_iterator & it) = default;
 };
 
 template <class T, class R, bool is_tensor_ = is_tensor<R>::value>
 struct ConstConverterIteratorHelper {
   using const_iterator = typename Array<T>::template const_iterator<R>;
   using iterator = typename Array<T>::template iterator<R>;
 
   static inline const_iterator convert(const iterator & it) {
     return const_iterator(std::unique_ptr<R>(new R(*it, false)));
   }
 };
 
 template <class T, class R> struct ConstConverterIteratorHelper<T, R, false> {
   using const_iterator = typename Array<T>::template const_iterator<R>;
   using iterator = typename Array<T>::template iterator<R>;
   static inline const_iterator convert(const iterator & it) {
     return const_iterator(it.data());
   }
 };
 
 template <class T, bool is_scal>
 template <typename R>
 class Array<T, is_scal>::iterator
     : public iterator_internal<R, Array<T, is_scal>::iterator<R>> {
 public:
   using parent = iterator_internal<R, iterator>;
   using value_type = typename parent::value_type;
   using pointer = typename parent::pointer;
   using reference = typename parent::reference;
   using difference_type = typename parent::difference_type;
   using iterator_category = typename parent::iterator_category;
 
 public:
   iterator() : parent(){};
   iterator(const iterator & it) = default;
   iterator(iterator && it) = default;
 
   template <typename P, typename = std::enable_if_t<not is_tensor<P>::value>>
   iterator(P * data) : parent(data) {}
 
   template <typename UP_P,
             typename =
                 std::enable_if_t<is_tensor<typename UP_P::element_type>::value>>
   iterator(UP_P && tensor) : parent(std::forward<UP_P>(tensor)) {}
 
   iterator & operator=(const iterator & it) = default;
 
   operator const_iterator<R>() {
     return ConstConverterIteratorHelper<T, R>::convert(*this);
   }
 };
 
 /* -------------------------------------------------------------------------- */
 template <class T, bool is_scal>
 template <typename R>
 inline typename Array<T, is_scal>::template iterator<R>
 Array<T, is_scal>::erase(const iterator<R> & it) {
   T * curr = it.data();
   UInt pos = (curr - values) / nb_component;
   erase(pos);
   iterator<R> rit = it;
   return --rit;
 }
 #endif
 
 } // namespace akantu
 
 #endif /* __AKANTU_AKA_ARRAY_TMPL_HH__ */
diff --git a/src/common/aka_blas_lapack.hh b/src/common/aka_blas_lapack.hh
index 55ba9a8c4..76a244310 100644
--- a/src/common/aka_blas_lapack.hh
+++ b/src/common/aka_blas_lapack.hh
@@ -1,343 +1,343 @@
 /**
  * @file   aka_blas_lapack.hh
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Wed Mar 06 2013
- * @date last modification: Mon Jan 18 2016
+ * @date last modification: Tue Feb 20 2018
  *
  * @brief  Interface of the Fortran BLAS/LAPACK libraries
  *
  * @section LICENSE
  *
- * Copyright  (©)  2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de Lausanne)
+ * 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
+ * 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
+ * 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_AKA_BLAS_LAPACK_HH__
 #define __AKANTU_AKA_BLAS_LAPACK_HH__
 
 /* -------------------------------------------------------------------------- */
 #ifdef AKANTU_USE_BLAS
 #include "aka_fortran_mangling.hh"
 extern "C" {
 
 /* ------------------------------------------------------------------------ */
 /* Double precision                                                         */
 /* ------------------------------------------------------------------------ */
 // LEVEL 1
 double AKA_FC_GLOBAL(ddot, DDOT)(int *, double *, int *, double *, int *);
 void AKA_FC_GLOBAL(daxpy, DAXPY)(int *, double *, double *, int *, double *,
                                  int *);
 
 // LEVEL 2
 void AKA_FC_GLOBAL(dgemv, DGEMV)(char *, int *, int *, double *, double *,
                                  int *, double *, int *, double *, double *,
                                  int *);
 // LEVEL 3
 void AKA_FC_GLOBAL(dgemm, DGEMM)(char *, char *, int *, int *, int *, double *,
                                  double *, int *, double *, int *, double *,
                                  double *, int *);
 /* ------------------------------------------------------------------------ */
 /* Simple precision                                                         */
 /* ------------------------------------------------------------------------ */
 // LEVEL 1
 float AKA_FC_GLOBAL(sdot, SDOT)(int *, float *, int *, float *, int *);
 void AKA_FC_GLOBAL(saxpy, SAXPY)(int *, float *, float *, int *, float *,
                                  int *);
 
 // LEVEL 2
 void AKA_FC_GLOBAL(sgemv, SGEMV)(char *, int *, int *, float *, float *, int *,
                                  float *, int *, float *, float *, int *);
 // LEVEL 3
 void AKA_FC_GLOBAL(sgemm, SGEMM)(char *, char *, int *, int *, int *, float *,
                                  float *, int *, float *, int *, float *,
                                  float *, int *);
 }
 #endif
 
 namespace akantu {
 
 #define AKANTU_WARNING_IGNORE_UNUSED_PARAMETER
 #include "aka_warning.hh"
 
 /// Wrapper around the S/DDOT BLAS function that returns the dot product of two
 /// vectors
 template <typename T>
 inline T aka_dot(int * n, T * x, int * incx, T * y, int * incy) {
   AKANTU_ERROR(debug::demangle(typeid(T).name())
                << "is not a type recognized, or you didn't activated "
                   "BLAS in the compilation options!");
 }
 
 /// Wrapper around the S/DAXPY BLAS function that computes \f$y := \alpha x +
 /// y\f$
 template <typename T>
 inline void aka_axpy(int * n, T * alpha, T * x, int * incx, T * y, int * incy) {
   AKANTU_ERROR(debug::demangle(typeid(T).name())
                << "is not a type recognized, or you didn't activated "
                   "BLAS in the compilation options!");
 }
 
 /// Wrapper around the S/DGEMV BLAS function that computes matrix-vector product
 /// \f$y := \alpha A^{(T)}x + \beta y \f$
 template <typename T>
 inline void aka_gemv(char * trans, int * m, int * n, T * alpha, T * a,
                      int * lda, T * x, int * incx, T * beta, T * y,
                      int * incy) {
   AKANTU_ERROR(debug::demangle(typeid(T).name())
                << "is not a type recognized, or you didn't activated "
                   "BLAS in the compilation options!");
 }
 
 /// Wrapper around the S/DGEMM BLAS function that computes the product of two
 /// matrices \f$C := \alpha A^{(T)} B^{(T)} + \beta C \f$
 template <typename T>
 inline void aka_gemm(char * transa, char * transb, int * m, int * n, int * k,
                      T * alpha, T * a, int * lda, T * b, int * ldb, T * beta,
                      T * c, int * ldc) {
   AKANTU_ERROR(debug::demangle(typeid(T).name())
                << "is not a type recognized, or you didn't activated "
                   "BLAS in the compilation options!");
 }
 
 #if defined(AKANTU_USE_BLAS)
 template <>
 inline double aka_dot<double>(int * n, double * x, int * incx, double * y,
                               int * incy) {
   return AKA_FC_GLOBAL(ddot, DDOT)(n, x, incx, y, incy);
 }
 
 template <>
 inline void aka_axpy(int * n, double * alpha, double * x, int * incx,
                      double * y, int * incy) {
   return AKA_FC_GLOBAL(daxpy, DAXPY)(n, alpha, x, incx, y, incy);
 }
 
 template <>
 inline void aka_gemv<double>(char * trans, int * m, int * n, double * alpha,
                              double * a, int * lda, double * x, int * incx,
                              double * beta, double * y, int * incy) {
   return AKA_FC_GLOBAL(dgemv, DGEMV)(trans, m, n, alpha, a, lda, x, incx, beta,
                                      y, incy);
 }
 
 template <>
 inline void aka_gemm<double>(char * transa, char * transb, int * m, int * n,
                              int * k, double * alpha, double * a, int * lda,
                              double * b, int * ldb, double * beta, double * c,
                              int * ldc) {
   AKA_FC_GLOBAL(dgemm, DGEMM)
   (transa, transb, m, n, k, alpha, a, lda, b, ldb, beta, c, ldc);
 }
 
 /* -------------------------------------------------------------------------- */
 /* -------------------------------------------------------------------------- */
 
 template <>
 inline float aka_dot<float>(int * n, float * x, int * incx, float * y,
                             int * incy) {
   return AKA_FC_GLOBAL(sdot, SDOT)(n, x, incx, y, incy);
 }
 
 template <>
 inline void aka_axpy(int * n, float * alpha, float * x, int * incx, float * y,
                      int * incy) {
   return AKA_FC_GLOBAL(daxpy, DAXPY)(n, alpha, x, incx, y, incy);
 }
 
 template <>
 inline void aka_gemv<float>(char * trans, int * m, int * n, float * alpha,
                             float * a, int * lda, float * x, int * incx,
                             float * beta, float * y, int * incy) {
   AKA_FC_GLOBAL(sgemv, SGEMV)
   (trans, m, n, alpha, a, lda, x, incx, beta, y, incy);
 }
 
 template <>
 inline void aka_gemm<float>(char * transa, char * transb, int * m, int * n,
                             int * k, float * alpha, float * a, int * lda,
                             float * b, int * ldb, float * beta, float * c,
                             int * ldc) {
   AKA_FC_GLOBAL(sgemm, SGEMM)
   (transa, transb, m, n, k, alpha, a, lda, b, ldb, beta, c, ldc);
 }
 
 #endif
 
 } // akantu
 
 #ifdef AKANTU_USE_LAPACK
 #include "aka_fortran_mangling.hh"
 extern "C" {
 /* ------------------------------------------------------------------------ */
 /* Double general matrix                                                    */
 /* ------------------------------------------------------------------------ */
 /// compute the eigenvalues/vectors
 void AKA_FC_GLOBAL(dgeev, DGEEV)(char * jobvl, char * jobvr, int * n,
                                  double * a, int * lda, double * wr,
                                  double * wi, double * vl, int * ldvl,
                                  double * vr, int * ldvr, double * work,
                                  int * lwork, int * info);
 
 /// LU decomposition of a general matrix
 void AKA_FC_GLOBAL(dgetrf, DGETRF)(int * m, int * n, double * a, int * lda,
                                    int * ipiv, int * info);
 
 /// generate inverse of a matrix given its LU decomposition
 void AKA_FC_GLOBAL(dgetri, DGETRI)(int * n, double * a, int * lda, int * ipiv,
                                    double * work, int * lwork, int * info);
 
 /// solving A x = b using a LU factorization
 void AKA_FC_GLOBAL(dgetrs, DGETRS)(char * trans, int * n, int * nrhs,
                                    double * A, int * lda, int * ipiv,
                                    double * b, int * ldb, int * info);
 
 /* ------------------------------------------------------------------------ */
 /* Simple general matrix                                                    */
 /* ------------------------------------------------------------------------ */
 /// compute the eigenvalues/vectors
 void AKA_FC_GLOBAL(sgeev, SGEEV)(char * jobvl, char * jobvr, int * n, float * a,
                                  int * lda, float * wr, float * wi, float * vl,
                                  int * ldvl, float * vr, int * ldvr,
                                  float * work, int * lwork, int * info);
 
 /// LU decomposition of a general matrix
 void AKA_FC_GLOBAL(sgetrf, SGETRF)(int * m, int * n, float * a, int * lda,
                                    int * ipiv, int * info);
 
 /// generate inverse of a matrix given its LU decomposition
 void AKA_FC_GLOBAL(sgetri, SGETRI)(int * n, float * a, int * lda, int * ipiv,
                                    float * work, int * lwork, int * info);
 
 /// solving A x = b using a LU factorization
 void AKA_FC_GLOBAL(sgetrs, SGETRS)(char * trans, int * n, int * nrhs, float * A,
                                    int * lda, int * ipiv, float * b, int * ldb,
                                    int * info);
 }
 #endif // AKANTU_USE_LAPACK
 
 namespace akantu {
 
 /// Wrapper around the S/DGEEV BLAS function that computes the eigenvalues and
 /// eigenvectors of a matrix
 template <typename T>
 inline void aka_geev(char * jobvl, char * jobvr, int * n, T * a, int * lda,
                      T * wr, T * wi, T * vl, int * ldvl, T * vr, int * ldvr,
                      T * work, int * lwork, int * info) {
   AKANTU_ERROR(debug::demangle(typeid(T).name())
                << "is not a type recognized, or you didn't activated "
                   "LAPACK in the compilation options!");
 }
 
 /// Wrapper around the S/DGETRF BLAS function that computes the LU decomposition
 /// of a matrix
 template <typename T>
 inline void aka_getrf(int * m, int * n, T * a, int * lda, int * ipiv,
                       int * info) {
   AKANTU_ERROR(debug::demangle(typeid(T).name())
                << "is not a type recognized, or you didn't activated "
                   "LAPACK in the compilation options!");
 }
 
 /// Wrapper around the S/DGETRI BLAS function that computes the inverse of a
 /// matrix given its LU decomposition
 template <typename T>
 inline void aka_getri(int * n, T * a, int * lda, int * ipiv, T * work,
                       int * lwork, int * info) {
   AKANTU_ERROR(debug::demangle(typeid(T).name())
                << "is not a type recognized, or you didn't activated "
                   "LAPACK in the compilation options!");
 }
 
 /// Wrapper around the S/DGETRS BLAS function that solves \f$A^{(T)}x = b\f$
 /// using LU decomposition
 template <typename T>
 inline void aka_getrs(char * trans, int * n, int * nrhs, T * A, int * lda,
                       int * ipiv, T * b, int * ldb, int * info) {
   AKANTU_ERROR(debug::demangle(typeid(T).name())
                << "is not a type recognized, or you didn't activated "
                   "LAPACK in the compilation options!");
 }
 
 #include "aka_warning_restore.hh"
 
 #ifdef AKANTU_USE_LAPACK
 template <>
 inline void aka_geev<double>(char * jobvl, char * jobvr, int * n, double * a,
                              int * lda, double * wr, double * wi, double * vl,
                              int * ldvl, double * vr, int * ldvr, double * work,
                              int * lwork, int * info) {
   AKA_FC_GLOBAL(dgeev, DGEEV)
   (jobvl, jobvr, n, a, lda, wr, wi, vl, ldvl, vr, ldvr, work, lwork, info);
 }
 
 template <>
 inline void aka_getrf<double>(int * m, int * n, double * a, int * lda,
                               int * ipiv, int * info) {
   AKA_FC_GLOBAL(dgetrf, DGETRF)(m, n, a, lda, ipiv, info);
 }
 
 template <>
 inline void aka_getri<double>(int * n, double * a, int * lda, int * ipiv,
                               double * work, int * lwork, int * info) {
   AKA_FC_GLOBAL(dgetri, DGETRI)(n, a, lda, ipiv, work, lwork, info);
 }
 
 template <>
 inline void aka_getrs<double>(char * trans, int * n, int * nrhs, double * A,
                               int * lda, int * ipiv, double * b, int * ldb,
                               int * info) {
   AKA_FC_GLOBAL(dgetrs, DGETRS)(trans, n, nrhs, A, lda, ipiv, b, ldb, info);
 }
 
 /* -------------------------------------------------------------------------- */
 /* -------------------------------------------------------------------------- */
 template <>
 inline void aka_geev<float>(char * jobvl, char * jobvr, int * n, float * a,
                             int * lda, float * wr, float * wi, float * vl,
                             int * ldvl, float * vr, int * ldvr, float * work,
                             int * lwork, int * info) {
   AKA_FC_GLOBAL(sgeev, SGEEV)
   (jobvl, jobvr, n, a, lda, wr, wi, vl, ldvl, vr, ldvr, work, lwork, info);
 }
 
 template <>
 inline void aka_getrf<float>(int * m, int * n, float * a, int * lda, int * ipiv,
                              int * info) {
   AKA_FC_GLOBAL(sgetrf, SGETRF)(m, n, a, lda, ipiv, info);
 }
 
 template <>
 inline void aka_getri<float>(int * n, float * a, int * lda, int * ipiv,
                              float * work, int * lwork, int * info) {
   AKA_FC_GLOBAL(sgetri, SGETRI)(n, a, lda, ipiv, work, lwork, info);
 }
 
 template <>
 inline void aka_getrs<float>(char * trans, int * n, int * nrhs, float * A,
                              int * lda, int * ipiv, float * b, int * ldb,
                              int * info) {
   AKA_FC_GLOBAL(sgetrs, SGETRS)(trans, n, nrhs, A, lda, ipiv, b, ldb, info);
 }
 #endif
 
 } // akantu
 
 #endif /* __AKANTU_AKA_BLAS_LAPACK_HH__ */
diff --git a/src/common/aka_circular_array.hh b/src/common/aka_circular_array.hh
index 7b9972b38..442967ff9 100644
--- a/src/common/aka_circular_array.hh
+++ b/src/common/aka_circular_array.hh
@@ -1,130 +1,129 @@
 /**
  * @file   aka_circular_array.hh
  *
  * @author David Simon Kammer <david.kammer@epfl.ch>
  *
  * @date creation: Fri Jun 18 2010
- * @date last modification: Sun Oct 19 2014
+ * @date last modification: Sun Aug 13 2017
  *
  * @brief  class of circular array
  *
  * @section LICENSE
  *
- * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
- * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
- * Solides)
+ * 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
+ * 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
+ * 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_AKA_CIRCULAR_ARRAY_HH__
 #define __AKANTU_AKA_CIRCULAR_ARRAY_HH__
 
 /* -------------------------------------------------------------------------- */
 #include <typeinfo>
 
 /* -------------------------------------------------------------------------- */
 #include "aka_array.hh"
 #include "aka_common.hh"
 
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 
 template <class T> class CircularArray : protected Array<T> {
   /* ------------------------------------------------------------------------ */
   /* Constructors/Destructors                                                 */
   /* ------------------------------------------------------------------------ */
 public:
   typedef typename Array<T>::value_type value_type;
   typedef typename Array<T>::reference reference;
   typedef typename Array<T>::pointer_type pointer_type;
   typedef typename Array<T>::const_reference const_reference;
 
   /// Allocation of a new array with a default value
   CircularArray(UInt size, UInt nb_component = 1,
                 const_reference value = value_type(), const ID & id = "")
       : Array<T>(size, nb_component, value, id), start_position(0),
         end_position(size - 1) {
     AKANTU_DEBUG_IN();
 
     AKANTU_DEBUG_OUT();
   };
 
   virtual ~CircularArray() {
     AKANTU_DEBUG_IN();
 
     AKANTU_DEBUG_OUT();
   };
 
   /* ------------------------------------------------------------------------ */
   /* Methods                                                                  */
   /* ------------------------------------------------------------------------ */
 public:
   /**
      advance start and end position by one:
      the first element is now at the end of the array
   **/
   inline void makeStep();
 
   /// function to print the contain of the class
   virtual void printself(std::ostream & stream, int indent = 0) const;
 
 private:
   /* ------------------------------------------------------------------------ */
   /* Operators                                                                */
   /* ------------------------------------------------------------------------ */
 public:
   inline reference operator()(UInt i, UInt j = 0);
   inline const_reference operator()(UInt i, UInt j = 0) const;
 
   /* ------------------------------------------------------------------------ */
   /* Accessors                                                                */
   /* ------------------------------------------------------------------------ */
 public:
   UInt size() const { return this->size_; };
 
   /* ------------------------------------------------------------------------ */
   /* Class Members                                                            */
   /* ------------------------------------------------------------------------ */
 private:
   /// indice of first element in this circular array
   UInt start_position;
 
   /// indice of last element in this circular array
   UInt end_position;
 };
 
 /* -------------------------------------------------------------------------- */
 /* inline functions                                                           */
 /* -------------------------------------------------------------------------- */
 
 #if defined(AKANTU_INCLUDE_INLINE_IMPL)
 #include "aka_circular_array_inline_impl.cc"
 #endif
 
 /// standard output stream operator
 template <typename T>
 inline std::ostream & operator<<(std::ostream & stream,
                                  const CircularArray<T> & _this) {
   _this.printself(stream);
   return stream;
 }
 
 } // akantu
 
 #endif /* __AKANTU_AKA_CIRCULAR_ARRAY_HH__ */
diff --git a/src/common/aka_circular_array_inline_impl.cc b/src/common/aka_circular_array_inline_impl.cc
index 8ebf880dc..98be1e402 100644
--- a/src/common/aka_circular_array_inline_impl.cc
+++ b/src/common/aka_circular_array_inline_impl.cc
@@ -1,99 +1,98 @@
 /**
  * @file   aka_circular_array_inline_impl.cc
  *
  * @author David Simon Kammer <david.kammer@epfl.ch>
  *
  * @date creation: Fri Nov 11 2011
- * @date last modification: Sun Oct 19 2014
+ * @date last modification: Wed Feb 03 2016
  *
  * @brief  implementation of circular array
  *
  * @section LICENSE
  *
- * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
- * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
- * Solides)
+ * 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
+ * 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
+ * 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/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 /* Inline Functions Array<T>                                                 */
 /* -------------------------------------------------------------------------- */
 
 /* -------------------------------------------------------------------------- */
 template <class T>
 inline typename CircularArray<T>::reference CircularArray<T>::
 operator()(UInt i, UInt j) {
   AKANTU_DEBUG_ASSERT(end_position != start_position,
                       "The array \"" << this->id << "\" is empty");
   AKANTU_DEBUG_ASSERT(
       (i < (end_position - start_position + this->allocated_size) %
                    this->allocated_size +
                1) &&
           (j < this->nb_component),
       "The value at position [" << i << "," << j
                                 << "] is out of range in array \"" << this->id
                                 << "\"");
   return this->values[((i + start_position) % this->allocated_size) *
                           this->nb_component +
                       j];
 }
 
 /* -------------------------------------------------------------------------- */
 template <typename T>
 inline typename CircularArray<T>::const_reference CircularArray<T>::
 operator()(UInt i, UInt j) const {
   AKANTU_DEBUG_ASSERT(end_position != start_position,
                       "The array \"" << this->id << "\" is empty");
   AKANTU_DEBUG_ASSERT(
       (i < (end_position - start_position + this->allocated_size) %
                    this->allocated_size +
                1) &&
           (j < this->nb_component),
       "The value at position [" << i << "," << j
                                 << "] is out of range in array \"" << this->id
                                 << "\"");
   return this->values[((i + start_position) % this->allocated_size) *
                           this->nb_component +
                       j];
 }
 
 /* -------------------------------------------------------------------------- */
 template <class T> inline void CircularArray<T>::makeStep() {
   AKANTU_DEBUG_IN();
 
   start_position = (start_position + 1) % this->allocated_size;
   end_position = (end_position + 1) % this->allocated_size;
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <class T>
 void CircularArray<T>::printself(std::ostream & stream, int indent) const {
   std::string space;
   for (Int i = 0; i < indent; i++, space += AKANTU_INDENT)
     ;
 
   stream << space << "CircularArray<" << debug::demangle(typeid(T).name())
          << "> [" << std::endl;
   stream << space << " + start_position : " << this->start_position
          << std::endl;
   stream << space << " + end_position   : " << this->end_position << std::endl;
   Array<T>::printself(stream, indent + 1);
 
   stream << space << "]" << std::endl;
 }
diff --git a/src/common/aka_common.cc b/src/common/aka_common.cc
index 4449190bc..9faaab7c6 100644
--- a/src/common/aka_common.cc
+++ b/src/common/aka_common.cc
@@ -1,153 +1,152 @@
 /**
  * @file   aka_common.cc
  *
  * @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Mon Jun 14 2010
- * @date last modification: Tue Jan 19 2016
+ * @date last modification: Mon Feb 05 2018
  *
  * @brief  Initialization of global variables
  *
  * @section LICENSE
  *
- * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
- * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
- * Solides)
+ * 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
+ * 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
+ * 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 "aka_random_generator.hh"
 #include "aka_static_memory.hh"
 #include "communicator.hh"
 
 #include "cppargparse.hh"
 #include "parser.hh"
 
 #include "communication_tag.hh"
 /* -------------------------------------------------------------------------- */
 #include <ctime>
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 void initialize(int & argc, char **& argv) {
   AKANTU_DEBUG_IN();
 
   initialize("", argc, argv);
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void initialize(const std::string & input_file, int & argc, char **& argv) {
   AKANTU_DEBUG_IN();
   StaticMemory::getStaticMemory();
   Communicator & comm = Communicator::getStaticCommunicator(argc, argv);
 
   Tag::setMaxTag(comm.getMaxTag());
 
   debug::debugger.setParallelContext(comm.whoAmI(), comm.getNbProc());
   debug::setDebugLevel(dblError);
 
   static_argparser.setParallelContext(comm.whoAmI(), comm.getNbProc());
   static_argparser.setExternalExitFunction(debug::exit);
   static_argparser.addArgument("--aka_input_file", "Akantu's input file", 1,
                                cppargparse::_string, std::string());
   static_argparser.addArgument(
       "--aka_debug_level",
       std::string("Akantu's overall debug level") +
           std::string(" (0: error, 1: exceptions, 4: warnings, 5: info, ..., "
                       "100: dump") +
           std::string(" more info on levels can be foind in aka_error.hh)"),
       1, cppargparse::_integer, int(dblWarning));
 
   static_argparser.addArgument(
       "--aka_print_backtrace",
       "Should Akantu print a backtrace in case of error", 0,
       cppargparse::_boolean, false, true);
 
   static_argparser.parse(argc, argv, cppargparse::_remove_parsed);
 
   std::string infile = static_argparser["aka_input_file"];
   if (infile == "")
     infile = input_file;
   debug::debugger.printBacktrace(static_argparser["aka_print_backtrace"]);
 
   if ("" != infile) {
     readInputFile(infile);
   }
 
   long int seed;
   try {
     seed = static_parser.getParameter("seed", _ppsc_current_scope);
   } catch (debug::Exception &) {
     seed = time(nullptr);
   }
 
   seed *= (comm.whoAmI() + 1);
   RandomGenerator<UInt>::seed(seed);
 
   int dbl_level = static_argparser["aka_debug_level"];
   debug::setDebugLevel(DebugLevel(dbl_level));
 
   AKANTU_DEBUG_INFO("Random seed set to " << seed);
 
   std::atexit(finalize);
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void finalize() {
   AKANTU_DEBUG_IN();
 
   // if (StaticCommunicator::isInstantiated()) {
   //   StaticCommunicator & comm = StaticCommunicator::getStaticCommunicator();
   //   delete &comm;
   // }
 
   if (StaticMemory::isInstantiated()) {
     delete &(StaticMemory::getStaticMemory());
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void readInputFile(const std::string & input_file) {
   static_parser.parse(input_file);
 }
 
 /* -------------------------------------------------------------------------- */
 cppargparse::ArgumentParser & getStaticArgumentParser() {
   return static_argparser;
 }
 
 /* -------------------------------------------------------------------------- */
 Parser & getStaticParser() { return static_parser; }
 
 /* -------------------------------------------------------------------------- */
 const ParserSection & getUserParser() {
   return *(static_parser.getSubSections(ParserType::_user).first);
 }
 
 std::unique_ptr<Communicator> Communicator::static_communicator;
 
 } // akantu
diff --git a/src/common/aka_common.hh b/src/common/aka_common.hh
index 09bcf4b14..37aaded5b 100644
--- a/src/common/aka_common.hh
+++ b/src/common/aka_common.hh
@@ -1,519 +1,519 @@
 /**
  * @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: Thu Jan 21 2016
+ * @date last modification: Mon Feb 12 2018
  *
  * @brief  common type descriptions for akantu
  *
  * @section LICENSE
  *
- * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
- * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
- * Solides)
+ * 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
+ * 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
+ * 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/>.
  *
  * @section DESCRIPTION
  *
  * All common things to be included in the projects files
  *
  */
 
 /* -------------------------------------------------------------------------- */
 
 #ifndef __AKANTU_COMMON_HH__
 #define __AKANTU_COMMON_HH__
 
 #include "aka_compatibilty_with_cpp_standard.hh"
 
 /* -------------------------------------------------------------------------- */
 #define __BEGIN_AKANTU_DUMPER__ namespace dumper {
 #define __END_AKANTU_DUMPER__ }
 /* -------------------------------------------------------------------------- */
 #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 <string>
 #include <type_traits>
 #include <unordered_map>
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 /* Common types                                                               */
 /* -------------------------------------------------------------------------- */
 using ID = std::string;
 
 #ifdef AKANTU_NDEBUG
 static const Real REAL_INIT_VALUE = Real(0.);
 #else
 static const Real REAL_INIT_VALUE = std::numeric_limits<Real>::quiet_NaN();
 #endif
 
 /* -------------------------------------------------------------------------- */
 /* Memory types                                                               */
 /* -------------------------------------------------------------------------- */
 
 using MemoryID = UInt;
 
 // using Surface = std::string;
 // using SurfacePair= std::pair<Surface, Surface>;
 // using SurfacePairList = std::list<SurfacePair>;
 
 /* -------------------------------------------------------------------------- */
 extern const UInt _all_dimensions;
 
 #define AKANTU_PP_ENUM(s, data, i, elem)                                       \
   BOOST_PP_TUPLE_REM()                                                         \
   elem BOOST_PP_COMMA_IF(BOOST_PP_NOT_EQUAL(i, BOOST_PP_DEC(data)))
 } // namespace akantu
 
 #if (defined(__GNUC__) || defined(__GNUG__))
 #define AKA_GCC_VERSION                                                        \
   (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__)
 #if AKA_GCC_VERSION < 60000
 #define AKANTU_ENUM_HASH(type_name)                                            \
   namespace std {                                                              \
     template <> struct hash<::akantu::type_name> {                             \
       using argument_type = ::akantu::type_name;                               \
       size_t operator()(const argument_type & e) const noexcept {              \
         auto ue = underlying_type_t<argument_type>(e);                         \
         return uh(ue);                                                         \
       }                                                                        \
                                                                                \
     private:                                                                   \
       const hash<underlying_type_t<argument_type>> uh{};                       \
     };                                                                         \
   }
 #else
 #define AKANTU_ENUM_HASH(type_name)
 #endif // AKA_GCC_VERSION
 #endif // GNU
 
 #include "aka_element_classes_info.hh"
 
 namespace akantu {
 
 #define AKANTU_PP_CAT(s, data, elem) BOOST_PP_CAT(data, elem)
 
 #define AKANTU_PP_TYPE_TO_STR(s, data, elem)                                   \
   ({BOOST_PP_CAT(data::_, elem), BOOST_PP_STRINGIZE(elem)})
 
 #define AKANTU_PP_STR_TO_TYPE(s, data, elem)                                   \
   ({BOOST_PP_STRINGIZE(elem), BOOST_PP_CAT(data::_, elem)})
 
 #define AKANTU_ENUM_DECLARE(type_name, list)                                   \
   enum class type_name {                                                       \
     BOOST_PP_SEQ_ENUM(BOOST_PP_SEQ_TRANSFORM(AKANTU_PP_CAT, _, list))          \
   };
 
 #define AKANTU_ENUM_OUTPUT_STREAM(type_name, list)                             \
   }                                                                            \
   AKANTU_ENUM_HASH(type_name)                                                  \
   namespace aka {                                                              \
     inline std::string to_string(const ::akantu::type_name & type) {           \
       static std::unordered_map<::akantu::type_name, std::string> convert{     \
           BOOST_PP_SEQ_FOR_EACH_I(                                             \
               AKANTU_PP_ENUM, BOOST_PP_SEQ_SIZE(list),                         \
               BOOST_PP_SEQ_TRANSFORM(AKANTU_PP_TYPE_TO_STR,                    \
                                      ::akantu::type_name, list))};             \
       return convert.at(type);                                                 \
     }                                                                          \
   }                                                                            \
   namespace akantu {                                                           \
     inline std::ostream & operator<<(std::ostream & stream,                    \
                                      const type_name & type) {                 \
       stream << aka::to_string(type);                                          \
       return stream;                                                           \
     }
 
 #define AKANTU_ENUM_INPUT_STREAM(type_name, list)                              \
   inline std::istream & operator>>(std::istream & stream, type_name & type) {  \
     std::string str;                                                           \
     stream >> str;                                                             \
     static std::unordered_map<std::string, type_name> convert{                 \
         BOOST_PP_SEQ_FOR_EACH_I(                                               \
             AKANTU_PP_ENUM, BOOST_PP_SEQ_SIZE(list),                           \
             BOOST_PP_SEQ_TRANSFORM(AKANTU_PP_STR_TO_TYPE, type_name, list))};  \
     type = convert.at(str);                                                    \
     return stream;                                                             \
   }
 
 /* -------------------------------------------------------------------------- */
 /* Mesh/FEM/Model types                                                       */
 /* -------------------------------------------------------------------------- */
 
 /// small help to use names for directions
 enum SpacialDirection { _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
 };
 
 #ifndef SWIG
 // clang-format off
 #define AKANTU_MODEL_TYPES                                              \
   (model)                                                               \
   (solid_mechanics_model)                                               \
   (solid_mechanics_model_cohesive)                                      \
   (heat_transfer_model)                                                 \
   (structural_mechanics_model)						\
   (embedded_model)
 // clang-format on
 
 /// enum ModelType defines which type of physics is solved
 AKANTU_ENUM_DECLARE(ModelType, AKANTU_MODEL_TYPES)
 AKANTU_ENUM_OUTPUT_STREAM(ModelType, AKANTU_MODEL_TYPES)
 AKANTU_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
 };
 
 /// enum DOFSupportType defines which kind of dof that can exists
 enum DOFSupportType { _dst_nodal, _dst_generic };
 
 /// Type of non linear resolution available in akantu
 enum NonLinearSolverType {
   _nls_linear,                  ///< No non linear convergence loop
   _nls_newton_raphson,          ///< Regular Newton-Raphson
   _nls_newton_raphson_modified, ///< Newton-Raphson with initial tangent
   _nls_lumped,                  ///< Case of lumped mass or equivalent matrix
   _nls_auto ///< This will take a default value that make sense in case of
             ///  model::getNewSolver
 };
 
 /// Define the node/dof type
 enum NodeType : Int { _nt_pure_gost = -3, _nt_master = -2, _nt_normal = -1 };
 
 /// Type of time stepping solver
 enum TimeStepSolverType {
   _tsst_static,         ///< Static solution
   _tsst_dynamic,        ///< Dynamic solver
   _tsst_dynamic_lumped, ///< Dynamic solver with lumped mass
   _tsst_not_defined,    ///< For not defined cases
 };
 
 /// Type of integration scheme
 enum IntegrationSchemeType {
   _ist_pseudo_time,            ///< Pseudo Time
   _ist_forward_euler,          ///< GeneralizedTrapezoidal(0)
   _ist_trapezoidal_rule_1,     ///< GeneralizedTrapezoidal(1/2)
   _ist_backward_euler,         ///< GeneralizedTrapezoidal(1)
   _ist_central_difference,     ///< NewmarkBeta(0, 1/2)
   _ist_fox_goodwin,            ///< NewmarkBeta(1/6, 1/2)
   _ist_trapezoidal_rule_2,     ///< NewmarkBeta(1/2, 1/2)
   _ist_linear_acceleration,    ///< NewmarkBeta(1/3, 1/2)
   _ist_newmark_beta,           ///< generic NewmarkBeta with user defined
                                /// alpha and beta
   _ist_generalized_trapezoidal ///< generic GeneralizedTrapezoidal with user
                                ///  defined alpha
 };
 
 /// enum SolveConvergenceCriteria different convergence criteria
 enum SolveConvergenceCriteria {
   _scc_residual,         ///< Use residual to test the convergence
   _scc_solution,         ///< Use solution to test the convergence
   _scc_residual_mass_wgh ///< Use residual weighted by inv. nodal mass to testb
 };
 
 /// enum CohesiveMethod type of insertion of cohesive elements
 enum CohesiveMethod { _intrinsic, _extrinsic };
 
 /// @enum SparseMatrixType type of sparse matrix used
 enum MatrixType { _unsymmetric, _symmetric, _mt_not_defined };
 
 /* -------------------------------------------------------------------------- */
 /* Ghosts handling                                                            */
 /* -------------------------------------------------------------------------- */
 /// @enum CommunicatorType type of communication method to use
 enum CommunicatorType { _communicator_mpi, _communicator_dummy };
 
 /// @enum SynchronizationTag type of synchronizations
 enum SynchronizationTag {
   //--- Generic tags ---
   _gst_whatever,
   _gst_update,
   _gst_size,
 
   //--- SolidMechanicsModel tags ---
   _gst_smm_mass,      ///< synchronization of the SolidMechanicsModel.mass
   _gst_smm_for_gradu, ///< synchronization of the
                       /// SolidMechanicsModel.displacement
   _gst_smm_boundary,  ///< synchronization of the boundary, forces, velocities
                       /// and displacement
   _gst_smm_uv,  ///< synchronization of the nodal velocities and displacement
   _gst_smm_res, ///< synchronization of the nodal residual
   _gst_smm_init_mat, ///< synchronization of the data to initialize materials
   _gst_smm_stress,  ///< synchronization of the stresses to compute the internal
                     /// forces
   _gst_smmc_facets, ///< synchronization of facet data to setup facet synch
   _gst_smmc_facets_conn,   ///< synchronization of facet global connectivity
   _gst_smmc_facets_stress, ///< synchronization of facets' stress to setup facet
                            /// synch
   _gst_smmc_damage,        ///< synchronization of damage
 
   // --- GlobalIdsUpdater tags ---
   _gst_giu_global_conn, ///< synchronization of global connectivities
 
   // --- CohesiveElementInserter tags ---
   _gst_ce_groups, ///< synchronization of cohesive element insertion depending
                   /// on facet groups
 
   // --- GroupManager tags ---
   _gst_gm_clusters, ///< synchronization of clusters
 
   // --- HeatTransfer tags ---
   _gst_htm_capacity,             ///< synchronization of the nodal heat capacity
   _gst_htm_temperature,          ///< synchronization of the nodal temperature
   _gst_htm_gradient_temperature, ///< synchronization of the element gradient
                                  /// temperature
   // --- LevelSet tags ---
   _gst_htm_phi,          ///< synchronization of the nodal level set value phi
   _gst_htm_gradient_phi, ///< synchronization of the element gradient phi
 
   //--- Material non local ---
   _gst_mnl_for_average, ///< synchronization of data to average in non local
                         /// material
   _gst_mnl_weight,      ///< synchronization of data for the weight computations
 
   // --- NeighborhoodSynchronization tags ---
   _gst_nh_criterion,
 
   // --- General tags ---
   _gst_test,        ///< Test tag
   _gst_user_1,      ///< tag for user simulations
   _gst_user_2,      ///< tag for user simulations
   _gst_material_id, ///< synchronization of the material ids
   _gst_for_dump,    ///< everything that needs to be synch before dump
 
   // --- Contact & Friction ---
   _gst_cf_nodal, ///< synchronization of disp, velo, and current position
   _gst_cf_incr,  ///< synchronization of increment
 
   // --- Solver tags ---
   _gst_solver_solution ///< synchronization of the solution obained with the
                        /// PETSc solver
 };
 
 /// standard output stream operator for SynchronizationTag
 inline std::ostream & operator<<(std::ostream & stream,
                                  SynchronizationTag type);
 
 /// @enum GhostType type of ghost
 enum GhostType {
   _not_ghost = 0,
   _ghost = 1,
   _casper // not used but a real cute ghost
 };
 }
 
 #ifndef SWIG
 AKANTU_ENUM_HASH(GhostType)
 #endif
 
 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>;
 extern ghost_type_t ghost_types;
 
 /// 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
 
 /* -------------------------------------------------------------------------- */
 /* Type traits                                                                */
 /* -------------------------------------------------------------------------- */
 struct TensorTrait {};
 /* -------------------------------------------------------------------------- */
 template <typename T> using is_tensor = std::is_base_of<TensorTrait, T>;
 /* -------------------------------------------------------------------------- */
 template <typename T> using is_scalar = std::is_arithmetic<T>;
 /* -------------------------------------------------------------------------- */
 
 /* -------------------------------------------------------------------------- */
 #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_BY_SUPPORT_TYPE(name, variable, type, support, con)   \
   inline con Array<type> & get##name(                                          \
       const support & el_type, const GhostType & ghost_type = _not_ghost)      \
       con {                                                                    \
     return variable(el_type, ghost_type);                                      \
   }
 
 #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);
 /* -------------------------------------------------------------------------- */
 
 /*
  * For intel compiler annoying remark
  */
 // #if defined(__INTEL_COMPILER)
 // /// remark #981: operands are evaluated in unspecified order
 // #pragma warning(disable : 981)
 // /// remark #383: value copied to temporary, reference to temporary used
 // #pragma warning(disable : 383)
 // #endif // defined(__INTEL_COMPILER)
 
 /* -------------------------------------------------------------------------- */
 /* string manipulation                                                        */
 /* -------------------------------------------------------------------------- */
 inline std::string to_lower(const std::string & str);
 /* -------------------------------------------------------------------------- */
 inline std::string trim(const std::string & to_trim);
 /* -------------------------------------------------------------------------- */
 
 /* -------------------------------------------------------------------------- */
 /// give a string representation of the a human readable size in bit
 template <typename T> std::string printMemorySize(UInt size);
 /* -------------------------------------------------------------------------- */
 
 } // namespace akantu
 
 #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();
 
 } // namespace akantu
 
 #include "aka_common_inline_impl.cc"
 
 /* -------------------------------------------------------------------------- */
 
 #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_common_inline_impl.cc b/src/common/aka_common_inline_impl.cc
index a16615d07..9f2a34849 100644
--- a/src/common/aka_common_inline_impl.cc
+++ b/src/common/aka_common_inline_impl.cc
@@ -1,459 +1,458 @@
 /**
  * @file   aka_common_inline_impl.cc
  *
  * @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Fri Jun 18 2010
- * @date last modification: Thu Oct 15 2015
+ * @date last modification: Tue Feb 20 2018
  *
  * @brief  inline implementations of common akantu type descriptions
  *
  * @section LICENSE
  *
- * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
- * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
- * Solides)
+ * 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
+ * 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
+ * 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/>.
  *
  * @section DESCRIPTION
  *
  * All common things to be included in the projects files
  *
  */
 
 /* -------------------------------------------------------------------------- */
 #include "aka_common.hh"
 #include <algorithm>
 #include <cctype>
 #include <iomanip>
 #include <iostream>
 
 /* -------------------------------------------------------------------------- */
 #ifndef __AKANTU_AKA_COMMON_INLINE_IMPL_CC__
 #define __AKANTU_AKA_COMMON_INLINE_IMPL_CC__
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 /// standard output stream operator for GhostType
 inline std::ostream & operator<<(std::ostream & stream, GhostType type) {
   switch (type) {
   case _not_ghost:
     stream << "not_ghost";
     break;
   case _ghost:
     stream << "ghost";
     break;
   case _casper:
     stream << "Casper the friendly ghost";
     break;
   }
   return stream;
 }
 
 /* -------------------------------------------------------------------------- */
 /// standard output stream operator for TimeStepSolverType
 inline std::ostream & operator<<(std::ostream & stream,
                                  const TimeStepSolverType & type) {
   switch (type) {
   case _tsst_static:
     stream << "static";
     break;
   case _tsst_dynamic:
     stream << "dynamic";
     break;
   case _tsst_dynamic_lumped:
     stream << "dynamic_lumped";
     break;
   case _tsst_not_defined:
     stream << "not defined time step solver";
     break;
   }
   return stream;
 }
 
 /* -------------------------------------------------------------------------- */
 /// standard input stream operator for TimeStepSolverType
 inline std::istream & operator>>(std::istream & stream,
                                  TimeStepSolverType & type) {
   std::string str;
   stream >> str;
   if (str == "static")
     type = _tsst_static;
   else if (str == "dynamic")
     type = _tsst_dynamic;
   else if (str == "dynamic_lumped")
     type = _tsst_dynamic_lumped;
   else {
     AKANTU_ERROR("The type " << str
                              << " is not a recognized TimeStepSolverType");
 
     stream.setstate(std::ios::failbit);
   }
 
   return stream;
 }
 
 /* -------------------------------------------------------------------------- */
 /// standard output stream operator for NonLinearSolverType
 inline std::ostream & operator<<(std::ostream & stream,
                                  const NonLinearSolverType & type) {
   switch (type) {
   case _nls_linear:
     stream << "linear";
     break;
   case _nls_newton_raphson:
     stream << "newton_raphson";
     break;
   case _nls_newton_raphson_modified:
     stream << "newton_raphson_modified";
     break;
   case _nls_lumped:
     stream << "lumped";
     break;
   case _nls_auto:
     stream << "auto";
     break;
   }
   return stream;
 }
 
 /* -------------------------------------------------------------------------- */
 /// standard input stream operator for NonLinearSolverType
 inline std::istream & operator>>(std::istream & stream,
                                  NonLinearSolverType & type) {
   std::string str;
   stream >> str;
   if (str == "linear")
     type = _nls_linear;
   else if (str == "newton_raphson")
     type = _nls_newton_raphson;
   else if (str == "newton_raphson_modified")
     type = _nls_newton_raphson_modified;
   else if (str == "lumped")
     type = _nls_lumped;
   else if (str == "auto")
     type = _nls_auto;
   else
     type = _nls_auto;
 
   return stream;
 }
 
 /* -------------------------------------------------------------------------- */
 /// standard output stream operator for IntegrationSchemeType
 inline std::ostream & operator<<(std::ostream & stream,
                                  const IntegrationSchemeType & type) {
   switch (type) {
   case _ist_pseudo_time:
     stream << "pseudo_time";
     break;
   case _ist_forward_euler:
     stream << "forward_euler";
     break;
   case _ist_trapezoidal_rule_1:
     stream << "trapezoidal_rule_1";
     break;
   case _ist_backward_euler:
     stream << "backward_euler";
     break;
   case _ist_central_difference:
     stream << "central_difference";
     break;
   case _ist_fox_goodwin:
     stream << "fox_goodwin";
     break;
   case _ist_trapezoidal_rule_2:
     stream << "trapezoidal_rule_2";
     break;
   case _ist_linear_acceleration:
     stream << "linear_acceleration";
     break;
   case _ist_newmark_beta:
     stream << "newmark_beta";
     break;
   case _ist_generalized_trapezoidal:
     stream << "generalized_trapezoidal";
     break;
   }
   return stream;
 }
 
 /* -------------------------------------------------------------------------- */
 /// standard input stream operator for IntegrationSchemeType
 inline std::istream & operator>>(std::istream & stream,
                                  IntegrationSchemeType & type) {
   std::string str;
   stream >> str;
 
   if (str == "pseudo_time")
     type = _ist_pseudo_time;
   else if (str == "forward_euler")
     type = _ist_forward_euler;
   else if (str == "trapezoidal_rule_1")
     type = _ist_trapezoidal_rule_1;
   else if (str == "backward_euler")
     type = _ist_backward_euler;
   else if (str == "central_difference")
     type = _ist_central_difference;
   else if (str == "fox_goodwin")
     type = _ist_fox_goodwin;
   else if (str == "trapezoidal_rule_2")
     type = _ist_trapezoidal_rule_2;
   else if (str == "linear_acceleration")
     type = _ist_linear_acceleration;
   else if (str == "newmark_beta")
     type = _ist_newmark_beta;
   else if (str == "generalized_trapezoidal")
     type = _ist_generalized_trapezoidal;
   else {
     AKANTU_ERROR("The type " << str
                              << " is not a recognized IntegrationSchemeType");
     stream.setstate(std::ios::failbit);
   }
   return stream;
 }
 
 /* -------------------------------------------------------------------------- */
 /// standard output stream operator for SynchronizationTag
 inline std::ostream & operator<<(std::ostream & stream,
                                  SynchronizationTag type) {
   switch (type) {
   case _gst_whatever:
     stream << "_gst_whatever";
     break;
   case _gst_update:
     stream << "_gst_update";
     break;
   case _gst_size:
     stream << "_gst_size";
     break;
   case _gst_smm_mass:
     stream << "_gst_smm_mass";
     break;
   case _gst_smm_for_gradu:
     stream << "_gst_smm_for_gradu";
     break;
   case _gst_smm_boundary:
     stream << "_gst_smm_boundary";
     break;
   case _gst_smm_uv:
     stream << "_gst_smm_uv";
     break;
   case _gst_smm_res:
     stream << "_gst_smm_res";
     break;
   case _gst_smm_init_mat:
     stream << "_gst_smm_init_mat";
     break;
   case _gst_smm_stress:
     stream << "_gst_smm_stress";
     break;
   case _gst_smmc_facets:
     stream << "_gst_smmc_facets";
     break;
   case _gst_smmc_facets_conn:
     stream << "_gst_smmc_facets_conn";
     break;
   case _gst_smmc_facets_stress:
     stream << "_gst_smmc_facets_stress";
     break;
   case _gst_smmc_damage:
     stream << "_gst_smmc_damage";
     break;
   case _gst_giu_global_conn:
     stream << "_gst_giu_global_conn";
     break;
   case _gst_ce_groups:
     stream << "_gst_ce_groups";
     break;
   case _gst_gm_clusters:
     stream << "_gst_gm_clusters";
     break;
   case _gst_htm_capacity:
     stream << "_gst_htm_capacity";
     break;
   case _gst_htm_temperature:
     stream << "_gst_htm_temperature";
     break;
   case _gst_htm_gradient_temperature:
     stream << "_gst_htm_gradient_temperature";
     break;
   case _gst_htm_phi:
     stream << "_gst_htm_phi";
     break;
   case _gst_htm_gradient_phi:
     stream << "_gst_htm_gradient_phi";
     break;
   case _gst_mnl_for_average:
     stream << "_gst_mnl_for_average";
     break;
   case _gst_mnl_weight:
     stream << "_gst_mnl_weight";
     break;
   case _gst_nh_criterion:
     stream << "_gst_nh_criterion";
     break;
   case _gst_test:
     stream << "_gst_test";
     break;
   case _gst_user_1:
     stream << "_gst_user_1";
     break;
   case _gst_user_2:
     stream << "_gst_user_2";
     break;
   case _gst_material_id:
     stream << "_gst_material_id";
     break;
   case _gst_for_dump:
     stream << "_gst_for_dump";
     break;
   case _gst_cf_nodal:
     stream << "_gst_cf_nodal";
     break;
   case _gst_cf_incr:
     stream << "_gst_cf_incr";
     break;
   case _gst_solver_solution:
     stream << "_gst_solver_solution";
     break;
   }
   return stream;
 }
 
 /* -------------------------------------------------------------------------- */
 /// standard output stream operator for SolveConvergenceCriteria
 inline std::ostream & operator<<(std::ostream & stream,
                                  const SolveConvergenceCriteria & criteria) {
   switch (criteria) {
   case _scc_residual:
     stream << "_scc_residual";
     break;
   case _scc_solution:
     stream << "_scc_solution";
     break;
   case _scc_residual_mass_wgh:
     stream << "_scc_residual_mass_wgh";
     break;
   }
   return stream;
 }
 
 inline std::istream & operator>>(std::istream & stream,
                                  SolveConvergenceCriteria & criteria) {
   std::string str;
   stream >> str;
   if (str == "residual")
     criteria = _scc_residual;
   else if (str == "solution")
     criteria = _scc_solution;
   else if (str == "residual_mass_wgh")
     criteria = _scc_residual_mass_wgh;
   else {
     stream.setstate(std::ios::failbit);
   }
   return stream;
 }
 
 /* -------------------------------------------------------------------------- */
 inline std::string to_lower(const std::string & str) {
   std::string lstr = str;
   std::transform(lstr.begin(), lstr.end(), lstr.begin(), (int (*)(int))tolower);
   return lstr;
 }
 
 /* -------------------------------------------------------------------------- */
 inline std::string trim(const std::string & to_trim) {
   std::string trimed = to_trim;
   // left trim
   trimed.erase(trimed.begin(),
                std::find_if(trimed.begin(), trimed.end(),
                             std::not1(std::ptr_fun<int, int>(isspace))));
   // right trim
   trimed.erase(std::find_if(trimed.rbegin(), trimed.rend(),
                             std::not1(std::ptr_fun<int, int>(isspace)))
                    .base(),
                trimed.end());
   return trimed;
 }
 
 } // akantu
 
 #include <cmath>
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 template <typename T> std::string printMemorySize(UInt size) {
   Real real_size = size * sizeof(T);
 
   UInt mult = 0;
   if (real_size != 0)
     mult = (std::log(real_size) / std::log(2)) / 10;
 
   std::stringstream sstr;
 
   real_size /= Real(1 << (10 * mult));
   sstr << std::setprecision(2) << std::fixed << real_size;
 
   std::string size_prefix;
   switch (mult) {
   case 0:
     sstr << "";
     break;
   case 1:
     sstr << "Ki";
     break;
   case 2:
     sstr << "Mi";
     break;
   case 3:
     sstr << "Gi";
     break; // I started on this type of machines
            // (32bit computers) (Nicolas)
   case 4:
     sstr << "Ti";
     break;
   case 5:
     sstr << "Pi";
     break;
   case 6:
     sstr << "Ei";
     break; // theoritical limit of RAM of the current
            // computers in 2014 (64bit computers) (Nicolas)
   case 7:
     sstr << "Zi";
     break;
   case 8:
     sstr << "Yi";
     break;
   default:
     AKANTU_ERROR(
         "The programmer in 2014 didn't thought so far (even wikipedia does not "
         "go further)."
         << " You have at least 1024 times more than a yobibit of RAM!!!"
         << " Just add the prefix corresponding in this switch case.");
   }
 
   sstr << "Byte";
 
   return sstr.str();
 }
 
 } // akantu
 
 #endif /* __AKANTU_AKA_COMMON_INLINE_IMPL_CC__ */
diff --git a/src/common/aka_compatibilty_with_cpp_standard.hh b/src/common/aka_compatibilty_with_cpp_standard.hh
index ebc6b3795..35fefe790 100644
--- a/src/common/aka_compatibilty_with_cpp_standard.hh
+++ b/src/common/aka_compatibilty_with_cpp_standard.hh
@@ -1,147 +1,150 @@
 /**
  * @file   aka_compatibilty_with_cpp_standard.hh
  *
- * @author Nicolas Richart
+ * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
- * @date creation  Wed Oct 25 2017
+ * @date creation: Fri Jun 18 2010
+ * @date last modification: Wed Jan 10 2018
  *
- * @brief The content of this file is taken from the possible implementations on
+ * @brief  The content of this file is taken from the possible implementations
+ * on
  * http://en.cppreference.com
  *
  * @section LICENSE
  *
- * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * 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
+ * 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
+ * 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_static_if.hh"
 /* -------------------------------------------------------------------------- */
 #include <tuple>
 #include <type_traits>
 #include <utility>
 /* -------------------------------------------------------------------------- */
 
 #ifndef __AKANTU_AKA_COMPATIBILTY_WITH_CPP_STANDARD_HH__
 #define __AKANTU_AKA_COMPATIBILTY_WITH_CPP_STANDARD_HH__
 
 namespace aka {
 
 // Part taken from C++14
 #if __cplusplus < 201402L
 template <bool B, class T = void>
 using enable_if_t = typename enable_if<B, T>::type;
 #else
 template <bool B, class T = void> using enable_if_t = std::enable_if_t<B, T>;
 #endif
 
 // Part taken from C++17
 #if __cplusplus < 201703L
 // bool_constant
 template <bool B> using bool_constant = std::integral_constant<bool, B>;
 namespace {
   template <bool B> constexpr bool bool_constant_v = bool_constant<B>::value;
 }
 /* -------------------------------------------------------------------------- */
 
 // conjunction
 template <class...> struct conjunction : std::true_type {};
 template <class B1> struct conjunction<B1> : B1 {};
 template <class B1, class... Bn>
 struct conjunction<B1, Bn...>
     : std::conditional_t<bool(B1::value), conjunction<Bn...>, B1> {};
 
 /* -------------------------------------------------------------------------- */
 
 // negations
 template <class B> struct negation : bool_constant<!bool(B::value)> {};
 
 /* -------------------------------------------------------------------------- */
 
 namespace detail {
   template <class T> struct is_reference_wrapper : std::false_type {};
   template <class U>
   struct is_reference_wrapper<std::reference_wrapper<U>> : std::true_type {};
   // template <class T>
   // constexpr bool is_reference_wrapper_v = is_reference_wrapper<T>::value;
 
   // template <class T, class Type, class T1, class... Args>
   // decltype(auto) INVOKE(Type T::*f, T1 && t1, Args &&... args) {
   //   static_assert(std::is_member_function_pointer<decltype(f)>{} and
   //                     std::is_base_of<T, std::decay_t<T1>>{},
   //                 "Does not know what to do with this types");
   //   return (std::forward<T1>(t1).*f)(std::forward<Args>(args)...);
   // }
 
   template <class T, class Type, class T1, class... Args>
   decltype(auto) INVOKE(Type T::*f, T1 && t1, Args &&... args) {
     static_if(std::is_member_function_pointer<decltype(f)>{})
         .then_([&](auto && f) {
           static_if(std::is_base_of<T, std::decay_t<T1>>{})
               .then_([&](auto && f) {
                 return (std::forward<T1>(t1).*f)(std::forward<Args>(args)...);
               })
               .elseif(is_reference_wrapper<std::decay_t<T1>>{})([&](auto && f) {
                 return (t1.get().*f)(std::forward<Args>(args)...);
               })
               .else_([&](auto && f) {
                 return ((*std::forward<T1>(t1)).*
                         f)(std::forward<Args>(args)...);
               })(std::forward<decltype(f)>(f));
         })
         .else_([&](auto && f) {
           static_assert(std::is_member_object_pointer<decltype(f)>::value,
                         "f is not a member object");
           static_assert(sizeof...(args) == 0, "f takes arguments");
           static_if(std::is_base_of<T, std::decay_t<T1>>{})
               .then_([&](auto && f) { return std::forward<T1>(t1).*f; })
               .elseif(std::is_base_of<T, std::decay_t<T1>>{})(
                   [&](auto && f) { return t1.get().*f; })
               .else_([&](auto && f) { return (*std::forward<T1>(t1)).*f; })(
                   std::forward<decltype(f)>(f));
         })(std::forward<decltype(f)>(f));
   }
 
   template <class F, class... Args>
   decltype(auto) INVOKE(F && f, Args &&... args) {
     return std::forward<F>(f)(std::forward<Args>(args)...);
   }
 } // namespace detail
 
 template <class F, class... Args>
 decltype(auto) invoke(F && f, Args &&... args) {
   return detail::INVOKE(std::forward<F>(f), std::forward<Args>(args)...);
 }
 
 namespace detail {
   template <class F, class Tuple, std::size_t... Is>
   constexpr decltype(auto) apply_impl(F && f, Tuple && t,
                                       std::index_sequence<Is...>) {
     return invoke(std::forward<F>(f), std::get<Is>(std::forward<Tuple>(t))...);
   }
 } // namespace detail
 
 template <class F, class Tuple>
 constexpr decltype(auto) apply(F && f, Tuple && t) {
   return detail::apply_impl(
       std::forward<F>(f), std::forward<Tuple>(t),
       std::make_index_sequence<std::tuple_size<std::decay_t<Tuple>>::value>{});
 }
 
 #endif
 } // namespace aka
 
 #endif /* __AKANTU_AKA_COMPATIBILTY_WITH_CPP_STANDARD_HH__ */
diff --git a/src/common/aka_config.hh.in b/src/common/aka_config.hh.in
index ecbec6274..321a236e4 100644
--- a/src/common/aka_config.hh.in
+++ b/src/common/aka_config.hh.in
@@ -1,103 +1,94 @@
 /**
  * @file   aka_config.hh.in
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Sun Sep 26 2010
- * @date last modification: Thu Jan 21 2016
+ * @date last modification: Thu Jan 25 2018
  *
  * @brief  Compilation time configuration of Akantu
  *
  * @section LICENSE
  *
- * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
- * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
- * Solides)
+ * 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 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.
+ * 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/>.
+ * 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_AKA_CONFIG_HH__
 #define __AKANTU_AKA_CONFIG_HH__
 
 #define AKANTU_VERSION_MAJOR @AKANTU_MAJOR_VERSION@
 #define AKANTU_VERSION_MINOR @AKANTU_MINOR_VERSION@
 #define AKANTU_VERSION_PATCH @AKANTU_PATCH_VERSION@
 #define AKANTU_VERSION (AKANTU_VERSION_MAJOR * 10000 \
                         + AKANTU_VERSION_MINOR * 100 \
                         + AKANTU_VERSION_PATCH)
 
 @AKANTU_TYPES_EXTRA_INCLUDES@
 namespace akantu {
 using Real = @AKANTU_FLOAT_TYPE@;
 using Int = @AKANTU_SIGNED_INTEGER_TYPE@;
 using UInt = @AKANTU_UNSIGNED_INTEGER_TYPE@;
 } // akantu
 
 #define AKANTU_INTEGER_SIZE @AKANTU_INTEGER_SIZE@
 #define AKANTU_FLOAT_SIZE @AKANTU_FLOAT_SIZE@
 
 #cmakedefine AKANTU_HAS_STRDUP
 
 #cmakedefine AKANTU_USE_BLAS
 #cmakedefine AKANTU_USE_LAPACK
 
 #cmakedefine AKANTU_PARALLEL
 #cmakedefine AKANTU_USE_MPI
 
 #cmakedefine AKANTU_USE_SCOTCH
 #cmakedefine AKANTU_USE_PTSCOTCH
 #cmakedefine AKANTU_SCOTCH_NO_EXTERN
 
 #cmakedefine AKANTU_IMPLICIT
 #cmakedefine AKANTU_USE_MUMPS
 #cmakedefine AKANTU_USE_PETSC
 
 #cmakedefine AKANTU_USE_IOHELPER
 #cmakedefine AKANTU_USE_QVIEW
 #cmakedefine AKANTU_USE_BLACKDYNAMITE
 
 #cmakedefine AKANTU_USE_PYBIND11
 
 #cmakedefine AKANTU_USE_OBSOLETE_GETTIMEOFDAY
 
 #cmakedefine AKANTU_EXTRA_MATERIALS
 #cmakedefine AKANTU_STUDENTS_EXTRA_PACKAGE
 #cmakedefine AKANTU_DAMAGE_NON_LOCAL
 
 #cmakedefine AKANTU_SOLID_MECHANICS
 #cmakedefine AKANTU_STRUCTURAL_MECHANICS
 #cmakedefine AKANTU_HEAT_TRANSFER
 #cmakedefine AKANTU_PYTHON_INTERFACE
 
 #cmakedefine AKANTU_COHESIVE_ELEMENT
 #cmakedefine AKANTU_PARALLEL_COHESIVE_ELEMENT
 
 #cmakedefine AKANTU_IGFEM
 
 #cmakedefine AKANTU_USE_CGAL
 #cmakedefine AKANTU_EMBEDDED
 
 // Debug tools
 //#cmakedefine AKANTU_NDEBUG
 #cmakedefine AKANTU_DEBUG_TOOLS
 #cmakedefine READLINK_COMMAND @READLINK_COMMAND@
 #cmakedefine ADDR2LINE_COMMAND @ADDR2LINE_COMMAND@
 
 #define __aka_inline__ inline
 
 #endif /* __AKANTU_AKA_CONFIG_HH__ */
diff --git a/src/common/aka_csr.hh b/src/common/aka_csr.hh
index 632b20219..7227cceee 100644
--- a/src/common/aka_csr.hh
+++ b/src/common/aka_csr.hh
@@ -1,259 +1,258 @@
 /**
  * @file   aka_csr.hh
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Wed Apr 20 2011
- * @date last modification: Sun Oct 19 2014
+ * @date last modification: Sun Dec 03 2017
  *
  * @brief  A compresed sparse row structure based on akantu Arrays
  *
  * @section LICENSE
  *
- * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
- * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
- * Solides)
+ * 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
+ * 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
+ * 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_array.hh"
 #include "aka_common.hh"
 
 /* -------------------------------------------------------------------------- */
 
 #ifndef __AKANTU_AKA_CSR_HH__
 #define __AKANTU_AKA_CSR_HH__
 
 namespace akantu {
 
 /**
  * This class  can be  used to  store the structure  of a  sparse matrix  or for
  * vectors with variable number of component per element
  *
  * @param nb_rows number of rows of a matrix or size of a vector.
  */
 template <typename T> class CSR {
   /* ------------------------------------------------------------------------ */
   /* Constructors/Destructors                                                 */
   /* ------------------------------------------------------------------------ */
 public:
   explicit CSR(UInt nb_rows = 0)
       : nb_rows(nb_rows), rows_offsets(nb_rows + 1, 1, "rows_offsets"),
         rows(0, 1, "rows") {
     rows_offsets.clear();
   };
 
   virtual ~CSR() = default;
 
   /* ------------------------------------------------------------------------ */
   /* Methods                                                                  */
   /* ------------------------------------------------------------------------ */
 public:
   /// does nothing
   inline void beginInsertions(){};
 
   /// insert a new entry val in row row
   inline UInt insertInRow(UInt row, const T & val) {
     UInt pos = rows_offsets(row)++;
     rows(pos) = val;
     return pos;
   }
 
   /// access an element of the matrix
   inline const T & operator()(UInt row, UInt col) const {
     AKANTU_DEBUG_ASSERT(rows_offsets(row + 1) - rows_offsets(row) > col,
                         "This element is not present in this CSR");
     return rows(rows_offsets(row) + col);
   }
 
   /// access an element of the matrix
   inline T & operator()(UInt row, UInt col) {
     AKANTU_DEBUG_ASSERT(rows_offsets(row + 1) - rows_offsets(row) > col,
                         "This element is not present in this CSR");
     return rows(rows_offsets(row) + col);
   }
 
   inline void endInsertions() {
     for (UInt i = nb_rows; i > 0; --i)
       rows_offsets(i) = rows_offsets(i - 1);
     rows_offsets(0) = 0;
   }
 
   inline void countToCSR() {
     for (UInt i = 1; i < nb_rows; ++i)
       rows_offsets(i) += rows_offsets(i - 1);
     for (UInt i = nb_rows; i >= 1; --i)
       rows_offsets(i) = rows_offsets(i - 1);
     rows_offsets(0) = 0;
   }
 
   inline void clearRows() {
     rows_offsets.clear();
     rows.resize(0);
   };
 
   inline void resizeRows(UInt nb_rows) {
     this->nb_rows = nb_rows;
     rows_offsets.resize(nb_rows + 1);
     rows_offsets.clear();
   }
 
   inline void resizeCols() { rows.resize(rows_offsets(nb_rows)); }
 
   inline void copy(Array<UInt> & offsets, Array<T> & values) {
     offsets.copy(rows_offsets);
     values.copy(rows);
   }
 
   /* ------------------------------------------------------------------------ */
   /* Accessors                                                                */
   /* ------------------------------------------------------------------------ */
 public:
   /// returns the number of rows
   inline UInt getNbRows() const { return rows_offsets.size() - 1; };
 
   /// returns the number of non-empty columns in a given row
   inline UInt getNbCols(UInt row) const {
     return rows_offsets(row + 1) - rows_offsets(row);
   };
 
   /// returns the offset (start of columns) for a given row
   inline UInt & rowOffset(UInt row) { return rows_offsets(row); };
 
   /// iterator on a row
   template <class R>
   class iterator_internal
       : public std::iterator<std::bidirectional_iterator_tag, R> {
   public:
     using _parent = std::iterator<std::bidirectional_iterator_tag, R>;
     using pointer = typename _parent::pointer;
     using reference = typename _parent::reference;
 
     explicit iterator_internal(pointer x = nullptr) : pos(x){};
     iterator_internal(const iterator_internal & it) : pos(it.pos){};
 
     iterator_internal & operator++() {
       ++pos;
       return *this;
     };
     iterator_internal operator++(int) {
       iterator tmp(*this);
       operator++();
       return tmp;
     };
 
     iterator_internal & operator--() {
       --pos;
       return *this;
     };
     iterator_internal operator--(int) {
       iterator_internal tmp(*this);
       operator--();
       return tmp;
     };
 
     bool operator==(const iterator_internal & rhs) { return pos == rhs.pos; };
     bool operator!=(const iterator_internal & rhs) { return pos != rhs.pos; };
     reference operator*() { return *pos; };
     pointer operator->() const { return pos; };
 
   private:
     pointer pos;
   };
 
   using iterator = iterator_internal<T>;
   using const_iterator = iterator_internal<const T>;
 
   inline iterator begin(UInt row) {
     return iterator(rows.storage() + rows_offsets(row));
   };
   inline iterator end(UInt row) {
     return iterator(rows.storage() + rows_offsets(row + 1));
   };
 
   inline const_iterator begin(UInt row) const {
     return const_iterator(rows.storage() + rows_offsets(row));
   };
   inline const_iterator end(UInt row) const {
     return const_iterator(rows.storage() + rows_offsets(row + 1));
   };
 
   inline iterator rbegin(UInt row) {
     return iterator(rows.storage() + rows_offsets(row + 1) - 1);
   };
   inline iterator rend(UInt row) {
     return iterator(rows.storage() + rows_offsets(row) - 1);
   };
 
   inline const Array<UInt> & getRowsOffset() const { return rows_offsets; };
   inline const Array<T> & getRows() const { return rows; };
   inline Array<T> & getRows() { return rows; };
   /* ------------------------------------------------------------------------ */
   /* Class Members                                                            */
   /* ------------------------------------------------------------------------ */
 protected:
   UInt nb_rows;
 
   /// array of size nb_rows containing the offset where the values are stored in
   Array<UInt> rows_offsets;
 
   /// compressed row values, values of row[i] are stored between rows_offsets[i]
   /// and rows_offsets[i+1]
   Array<T> rows;
 };
 
 /* -------------------------------------------------------------------------- */
 /* Data CSR                                                                   */
 /* -------------------------------------------------------------------------- */
 
 /**
  * Inherits from  CSR<UInt> and  can contain information  such as  matrix values
  * where the mother class would be a CSR structure for row and cols
  *
  * @return nb_rows
  */
 template <class T> class DataCSR : public CSR<UInt> {
 public:
   DataCSR(UInt nb_rows = 0) : CSR<UInt>(nb_rows), data(0, 1){};
 
   inline void resizeCols() {
     CSR<UInt>::resizeCols();
     data.resize(rows_offsets(nb_rows));
   }
 
   inline const Array<T> & getData() const { return data; };
 
 private:
   Array<T> data;
 };
 
 /* -------------------------------------------------------------------------- */
 /* inline functions                                                           */
 /* -------------------------------------------------------------------------- */
 
 //#include "aka_csr_inline_impl.cc"
 
 /// standard output stream operator
 // inline std::ostream & operator <<(std::ostream & stream, const CSR & _this)
 // {
 //   _this.printself(stream);
 //   return stream;
 // }
 
 } // akantu
 
 #endif /* __AKANTU_AKA_CSR_HH__ */
diff --git a/src/common/aka_element_classes_info.hh.in b/src/common/aka_element_classes_info.hh.in
index 1fbdeadf1..a1b6651e1 100644
--- a/src/common/aka_element_classes_info.hh.in
+++ b/src/common/aka_element_classes_info.hh.in
@@ -1,217 +1,209 @@
 /**
  * @file   aka_element_classes_info.hh.in
  *
  * @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Sun Jul 19 2015
- * @date last modification: Fri Oct 16 2015
+ * @date last modification: Tue Feb 20 2018
  *
  * @brief  Declaration of the enums for the element classes
  *
  * @section LICENSE
  *
- * Copyright (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne) Laboratory
- * (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * Copyright (©) 2015-2018 EPFL (Ecole Polytechnique Fédérale de Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
- * Akantu is free  software: you can redistribute it and/or  modify it under the
- * terms  of the  GNU Lesser  General Public  License as  published by  the Free
- * Software Foundation, either version 3 of the License, or (at your option) any
- * later version.
+ * Akantu is 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.
+ * 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/>.
+ * 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 <boost/preprocessor.hpp>
 /* -------------------------------------------------------------------------- */
 
 #ifndef __AKANTU_AKA_ELEMENT_CLASSES_INFO_HH__
 #define __AKANTU_AKA_ELEMENT_CLASSES_INFO_HH__
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 /* Element Types                                                              */
 /* -------------------------------------------------------------------------- */
 
 /// @enum ElementType type of elements
 enum ElementType {
   _not_defined,
   @AKANTU_ELEMENT_TYPES_ENUM@
   _max_element_type
 };
 
 @AKANTU_ELEMENT_TYPES_BOOST_SEQ@
 
 @AKANTU_ALL_ELEMENT_BOOST_SEQ@
 
 /* -------------------------------------------------------------------------- */
 /* Element Kinds                                                              */
 /* -------------------------------------------------------------------------- */
 @AKANTU_ELEMENT_KINDS_BOOST_SEQ@
 
 @AKANTU_ELEMENT_KIND_BOOST_SEQ@
 
 #ifndef SWIG
 enum ElementKind {
   BOOST_PP_SEQ_ENUM(AKANTU_ELEMENT_KIND),
   _ek_not_defined
 };
 
 
 /* -------------------------------------------------------------------------- */
 struct ElementKind_def {
   using type = ElementKind;
   static const type _begin_ = BOOST_PP_SEQ_HEAD(AKANTU_ELEMENT_KIND);
   static const type _end_   = _ek_not_defined;
 };
 
 using element_kind_t = safe_enum<ElementKind_def> ;
 #else
 enum ElementKind;
 #endif
 
 /* -------------------------------------------------------------------------- */
 /// @enum GeometricalType type of element potentially contained in a Mesh
 enum GeometricalType {
   @AKANTU_GEOMETRICAL_TYPES_ENUM@
   _gt_not_defined
 };
 
 /* -------------------------------------------------------------------------- */
 /* Interpolation Types                                                        */
 /* -------------------------------------------------------------------------- */
 @AKANTU_INTERPOLATION_TYPES_BOOST_SEQ@
 
 #ifndef SWIG
 /// @enum InterpolationType type of elements
 enum InterpolationType {
   BOOST_PP_SEQ_ENUM(AKANTU_INTERPOLATION_TYPES),
   _itp_not_defined
 };
 #else
 enum InterpolationType;
 #endif
 
 /* -------------------------------------------------------------------------- */
 /* Some sub types less probable to change                                     */
 /* -------------------------------------------------------------------------- */
 /// @enum GeometricalShapeType types of shapes to define the contains
 /// function in the element classes
 enum GeometricalShapeType {
   @AKANTU_GEOMETRICAL_SHAPES_ENUM@
   _gst_not_defined
 };
 
 /* -------------------------------------------------------------------------- */
 /// @enum GaussIntegrationType classes of types using common
 /// description of the gauss point position and weights
 enum GaussIntegrationType {
   @AKANTU_GAUSS_INTEGRATION_TYPES_ENUM@
   _git_not_defined
 };
 
 /* -------------------------------------------------------------------------- */
 /// @enum InterpolationKind the family of interpolation types
 enum InterpolationKind {
   @AKANTU_INTERPOLATION_KIND_ENUM@
   _itk_not_defined
 };
 
 /* -------------------------------------------------------------------------- */
 // BOOST PART: TOUCH ONLY IF YOU KNOW WHAT YOU ARE DOING
 #define AKANTU_BOOST_CASE_MACRO(r, macro, _type)                               \
   case _type: {                                                                \
     macro(_type);                                                              \
     break;                                                                     \
   }
 
 #define AKANTU_BOOST_LIST_SWITCH(macro1, list1, var)                           \
   do {                                                                         \
     switch (var) {                                                             \
       BOOST_PP_SEQ_FOR_EACH(AKANTU_BOOST_CASE_MACRO, macro1, list1)            \
     default: {                                                                 \
       AKANTU_ERROR("Type (" << var << ") not handled by this function"); \
     }                                                                          \
     }                                                                          \
   } while (0)
 
 #define AKANTU_BOOST_LIST_SWITCH_NO_DEFAULT(macro1, list1, var)                \
   do {                                                                         \
     switch (var) {                                                             \
       BOOST_PP_SEQ_FOR_EACH(AKANTU_BOOST_CASE_MACRO, macro1, list1)            \
     case _not_defined:                                                         \
       break;                                                                   \
     case _max_element_type:                                                    \
       break;                                                                   \
     }                                                                          \
   } while (0)
 
 #define AKANTU_BOOST_ELEMENT_SWITCH(macro1, list1)                             \
   AKANTU_BOOST_LIST_SWITCH(macro1, list1, type)
 
 #define AKANTU_BOOST_ELEMENT_SWITCH_NO_DEFAULT(macro1, list1)                  \
   AKANTU_BOOST_LIST_SWITCH_NO_DEFAULT(macro1, list1, type)
 
 #define AKANTU_BOOST_ALL_ELEMENT_SWITCH(macro)                                 \
   AKANTU_BOOST_ELEMENT_SWITCH(macro, AKANTU_ALL_ELEMENT_TYPE)
 
 #define AKANTU_BOOST_ALL_ELEMENT_SWITCH_NO_DEFAULT(macro)                      \
   AKANTU_BOOST_ELEMENT_SWITCH_NO_DEFAULT(macro, AKANTU_ALL_ELEMENT_TYPE)
 
 #define AKANTU_BOOST_LIST_MACRO(r, macro, type) macro(type)
 
 #define AKANTU_BOOST_APPLY_ON_LIST(macro, list)                                \
   BOOST_PP_SEQ_FOR_EACH(AKANTU_BOOST_LIST_MACRO, macro, list)
 
 #define AKANTU_BOOST_ALL_ELEMENT_LIST(macro)                                   \
   AKANTU_BOOST_APPLY_ON_LIST(macro, AKANTU_ALL_ELEMENT_TYPE)
 
 #define AKANTU_GET_ELEMENT_LIST(kind) AKANTU##kind##_ELEMENT_TYPE
 
 #define AKANTU_BOOST_KIND_ELEMENT_SWITCH(macro, kind)                          \
   AKANTU_BOOST_ELEMENT_SWITCH(macro, AKANTU_GET_ELEMENT_LIST(kind))
 
 // BOOST_PP_SEQ_TO_LIST does not exists in Boost < 1.49
 #define AKANTU_GENERATE_KIND_LIST(seq)                                         \
   BOOST_PP_TUPLE_TO_LIST(BOOST_PP_SEQ_SIZE(seq), BOOST_PP_SEQ_TO_TUPLE(seq))
 
 #define AKANTU_ELEMENT_KIND_BOOST_LIST                                         \
   AKANTU_GENERATE_KIND_LIST(AKANTU_ELEMENT_KIND)
 
 #define AKANTU_BOOST_ALL_KIND_LIST(macro, list)                                \
   BOOST_PP_LIST_FOR_EACH(AKANTU_BOOST_LIST_MACRO, macro, list)
 
 #define AKANTU_BOOST_ALL_KIND(macro)                                           \
   AKANTU_BOOST_ALL_KIND_LIST(macro, AKANTU_ELEMENT_KIND_BOOST_LIST)
 
 #define AKANTU_BOOST_ALL_KIND_SWITCH(macro)                                    \
   AKANTU_BOOST_LIST_SWITCH(macro, AKANTU_ELEMENT_KIND, kind)
 
 @AKANTU_ELEMENT_KINDS_BOOST_MACROS@
 
 // /// define kept for compatibility reasons (they are most probably not needed
 // /// anymore) \todo check if they can be removed
 // #define AKANTU_REGULAR_ELEMENT_TYPE	AKANTU_ek_regular_ELEMENT_TYPE
 // #define AKANTU_COHESIVE_ELEMENT_TYPE	AKANTU_ek_cohesive_ELEMENT_TYPE
 // #define AKANTU_STRUCTURAL_ELEMENT_TYPE  AKANTU_ek_structural_ELEMENT_TYPE
 // #define AKANTU_IGFEM_ELEMENT_TYPE       AKANTU_ek_igfem_ELEMENT_TYPE
 
 /* -------------------------------------------------------------------------- */
 /* Lists of interests for FEEngineTemplate functions                          */
 /* -------------------------------------------------------------------------- */
 @AKANTU_FE_ENGINE_LISTS@
 
 } // akantu
 
 #endif /* __AKANTU_AKA_ELEMENT_CLASSES_INFO_HH__ */
 
 #include "aka_element_classes_info_inline_impl.cc"
diff --git a/src/common/aka_element_classes_info_inline_impl.cc b/src/common/aka_element_classes_info_inline_impl.cc
index 6bac2c4ee..871c7d2b6 100644
--- a/src/common/aka_element_classes_info_inline_impl.cc
+++ b/src/common/aka_element_classes_info_inline_impl.cc
@@ -1,113 +1,114 @@
 /**
  * @file   aka_element_classes_info_inline_impl.cc
  *
  * @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Thu Jun 18 2015
- * @date last modification: Sun Jul 19 2015
+ * @date last modification: Wed Jan 10 2018
  *
  * @brief  Implementation of the streaming fonction for the element classes
  * enums
  *
  * @section LICENSE
  *
- * Copyright (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne) Laboratory
- * (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * Copyright (©) 2015-2018 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
- * terms  of the  GNU Lesser  General Public  License as  published by  the Free
+ * 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
+ * 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 <unordered_map>
 /* -------------------------------------------------------------------------- */
 
 #ifndef __AKANTU_AKA_ELEMENT_CLASSES_INFO_INLINE_IMPL_CC__
 #define __AKANTU_AKA_ELEMENT_CLASSES_INFO_INLINE_IMPL_CC__
 
 AKANTU_ENUM_HASH(ElementType)
 
 #define AKANTU_PP_ELEMTYPE_TO_STR(s, data, elem)                               \
   ({akantu::elem, BOOST_PP_STRINGIZE(elem)})
 
 #define AKANTU_PP_STR_TO_ELEMTYPE(s, data, elem)                               \
   ({BOOST_PP_STRINGIZE(elem), akantu::elem})
 
 namespace aka {
 inline std::string to_string(const akantu::ElementType & type) {
   static std::unordered_map<akantu::ElementType, std::string> convert{
       BOOST_PP_SEQ_FOR_EACH_I(
           AKANTU_PP_ENUM, BOOST_PP_SEQ_SIZE(AKANTU_ALL_ELEMENT_TYPE),
           BOOST_PP_SEQ_TRANSFORM(AKANTU_PP_ELEMTYPE_TO_STR, _,
                                  AKANTU_ALL_ELEMENT_TYPE)),
       {akantu::_not_defined, "_not_defined"},
       {akantu::_max_element_type, "_max_element_type"}};
   return convert.at(type);
 }
 }
 
 namespace akantu {
 
 #define STRINGIFY(type) stream << BOOST_PP_STRINGIZE(type)
 
 /* -------------------------------------------------------------------------- */
 //! standard output stream operator for ElementType
 inline std::ostream & operator<<(std::ostream & stream,
                                  const ElementType & type) {
   stream << aka::to_string(type);
   return stream;
 }
 
 /* -------------------------------------------------------------------------- */
 
 //! standard input stream operator for ElementType
 inline std::istream & operator>>(std::istream & stream, ElementType & type) {
   std::string str;
   stream >> str;
   static std::unordered_map<std::string, ElementType> convert{
       BOOST_PP_SEQ_FOR_EACH_I(
           AKANTU_PP_ENUM, BOOST_PP_SEQ_SIZE(AKANTU_ALL_ELEMENT_TYPE),
           BOOST_PP_SEQ_TRANSFORM(AKANTU_PP_STR_TO_ELEMTYPE, _,
                                  AKANTU_ALL_ELEMENT_TYPE))};
   type = convert.at(str);
   return stream;
 }
 
 /* -------------------------------------------------------------------------- */
 //! standard output stream operator for ElementType
 inline std::ostream & operator<<(std::ostream & stream, ElementKind kind) {
   AKANTU_BOOST_ALL_KIND_SWITCH(STRINGIFY);
 
   return stream;
 }
 
 /* -------------------------------------------------------------------------- */
 /// standard output stream operator for InterpolationType
 inline std::ostream & operator<<(std::ostream & stream,
                                  InterpolationType type) {
   switch (type) {
     BOOST_PP_SEQ_FOR_EACH(AKANTU_BOOST_CASE_MACRO, STRINGIFY,
                           AKANTU_INTERPOLATION_TYPES)
   case _itp_not_defined:
     stream << "_itp_not_defined";
     break;
   }
   return stream;
 }
 
 #undef STRINGIFY
 
 } // akantu
 
 #endif /* __AKANTU_AKA_ELEMENT_CLASSES_INFO_INLINE_IMPL_CC__ */
diff --git a/src/common/aka_error.cc b/src/common/aka_error.cc
index bbe935cb2..1afca6656 100644
--- a/src/common/aka_error.cc
+++ b/src/common/aka_error.cc
@@ -1,360 +1,359 @@
 /**
  * @file   aka_error.cc
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Mon Sep 06 2010
- * @date last modification: Tue Jan 19 2016
+ * @date last modification: Sun Dec 03 2017
  *
  * @brief  handling of errors
  *
  * @section LICENSE
  *
- * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
- * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
- * Solides)
+ * 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
+ * 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
+ * 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_error.hh"
 #include "aka_common.hh"
 #include "aka_config.hh"
 /* -------------------------------------------------------------------------- */
 #include <csignal>
 #include <iostream>
 
 #if (defined(READLINK_COMMAND) || defined(ADDR2LINE_COMMAND)) &&               \
     (not defined(_WIN32))
 #include <execinfo.h>
 #include <sys/wait.h>
 #endif
 
 #include <cmath>
 #include <cstring>
 #include <cxxabi.h>
 #include <fstream>
 #include <iomanip>
 #include <map>
 #include <sys/types.h>
 #include <unistd.h>
 
 #if defined(AKANTU_CORE_CXX11)
 #include <chrono>
 #elif defined(AKANTU_USE_OBSOLETE_GETTIMEOFDAY)
 #include <sys/time.h>
 #else
 #include <time.h>
 #endif
 
 #ifdef AKANTU_USE_MPI
 #include <mpi.h>
 #endif
 
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 namespace debug {
 
   static void printBacktraceAndExit(int) { std::terminate(); }
 
   /* ------------------------------------------------------------------------ */
   void initSignalHandler() { std::signal(SIGSEGV, &printBacktraceAndExit); }
 
   /* ------------------------------------------------------------------------ */
   std::string demangle(const char * symbol) {
     int status;
     std::string result;
     char * demangled_name;
 
     if ((demangled_name = abi::__cxa_demangle(symbol, nullptr, nullptr,
                                               &status)) != nullptr) {
       result = demangled_name;
       free(demangled_name);
     } else {
       result = symbol;
     }
 
     return result;
   }
 
 /* ------------------------------------------------------------------------ */
 #if (defined(READLINK_COMMAND) || defined(ADDR2LINK_COMMAND)) &&               \
     (not defined(_WIN32))
   std::string exec(const std::string & cmd) {
     FILE * pipe = popen(cmd.c_str(), "r");
     if (!pipe)
       return "";
     char buffer[1024];
     std::string result = "";
     while (!feof(pipe)) {
       if (fgets(buffer, 128, pipe) != nullptr)
         result += buffer;
     }
 
     result = result.substr(0, result.size() - 1);
     pclose(pipe);
     return result;
   }
 #endif
 
   /* ------------------------------------------------------------------------ */
   void printBacktrace(__attribute__((unused)) int sig) {
     AKANTU_DEBUG_INFO("Caught  signal " << sig << "!");
 
 #if not defined(_WIN32)
 #if defined(READLINK_COMMAND) && defined(ADDR2LINE_COMMAND)
     std::string me = "";
     char buf[1024];
     /* The manpage says it won't null terminate.  Let's zero the buffer. */
     memset(buf, 0, sizeof(buf));
     /* Note we use sizeof(buf)-1 since we may need an extra char for NUL. */
     if (readlink("/proc/self/exe", buf, sizeof(buf) - 1))
       me = std::string(buf);
 
     std::ifstream inmaps;
     inmaps.open("/proc/self/maps");
     std::map<std::string, size_t> addr_map;
     std::string line;
     while (inmaps.good()) {
       std::getline(inmaps, line);
       std::stringstream sstr(line);
 
       size_t first = line.find('-');
       std::stringstream sstra(line.substr(0, first));
       size_t addr;
       sstra >> std::hex >> addr;
 
       std::string lib;
       sstr >> lib;
       sstr >> lib;
       sstr >> lib;
       sstr >> lib;
       sstr >> lib;
       sstr >> lib;
       if (lib != "" && addr_map.find(lib) == addr_map.end()) {
         addr_map[lib] = addr;
       }
     }
 
     if (me != "")
       addr_map[me] = 0;
 #endif
 
     /// \todo for windows this part could be coded using CaptureStackBackTrace
     /// and SymFromAddr
     const size_t max_depth = 100;
     size_t stack_depth;
     void * stack_addrs[max_depth];
     char ** stack_strings;
 
     size_t i;
     stack_depth = backtrace(stack_addrs, max_depth);
     stack_strings = backtrace_symbols(stack_addrs, stack_depth);
 
     std::cerr << "BACKTRACE :  " << stack_depth << " stack frames."
               << std::endl;
     auto w = size_t(std::floor(log(double(stack_depth)) / std::log(10.)) + 1);
 
     /// -1 to remove the call to the printBacktrace function
     for (i = 1; i < stack_depth; i++) {
       std::cerr << std::dec << "  [" << std::setw(w) << i << "] ";
       std::string bt_line(stack_strings[i]);
       size_t first, second;
 
       if ((first = bt_line.find('(')) != std::string::npos &&
           (second = bt_line.find('+')) != std::string::npos) {
         std::string location = bt_line.substr(0, first);
 #if defined(READLINK_COMMAND)
         std::string location_cmd =
             std::string(BOOST_PP_STRINGIZE(READLINK_COMMAND)) +
             std::string(" -f ") + location;
         location = exec(location_cmd);
 #endif
         std::string call =
             demangle(bt_line.substr(first + 1, second - first - 1).c_str());
         size_t f = bt_line.find('[');
         size_t s = bt_line.find(']');
         std::string address = bt_line.substr(f + 1, s - f - 1);
         std::stringstream sstra(address);
         size_t addr;
         sstra >> std::hex >> addr;
 
         std::cerr << location << " [" << call << "]";
 
 #if defined(READLINK_COMMAND) && defined(ADDR2LINE_COMMAND)
         auto it = addr_map.find(location);
         if (it != addr_map.end()) {
           std::stringstream syscom;
           syscom << BOOST_PP_STRINGIZE(ADDR2LINE_COMMAND) << " 0x" << std::hex
                  << (addr - it->second) << " -i -e " << location;
           std::string line = exec(syscom.str());
           std::cerr << " (" << line << ")" << std::endl;
         } else {
 #endif
           std::cerr << " (0x" << std::hex << addr << ")" << std::endl;
 #if defined(READLINK_COMMAND) && defined(ADDR2LINE_COMMAND)
         }
 #endif
       } else {
         std::cerr << bt_line << std::endl;
       }
     }
 
     free(stack_strings);
 
     std::cerr << "END BACKTRACE" << std::endl;
 #endif
   }
 
   /* ------------------------------------------------------------------------ */
   namespace {
     void terminate_handler() {
       auto eptr = std::current_exception();
       auto t = abi::__cxa_current_exception_type();
       auto name = t ? demangle(t->name()) : std::string("unknown");
       try {
         if (eptr)
           std::rethrow_exception(eptr);
         else
           std::cerr << "!! Execution terminated for unknown reasons !!"
                     << std::endl;
       } catch (std::exception & e) {
         std::cerr << "!! Uncaught exception of type " << name
                   << " !!\nwhat(): \"" << e.what() << "\"" << std::endl;
       } catch (...) {
         std::cerr << "!! Something strange of type \"" << name
                   << "\" was thrown.... !!" << std::endl;
       }
 
       if (debugger.printBacktrace())
         printBacktrace(15);
     }
   } // namespace
   /* ------------------------------------------------------------------------ */
   /* ------------------------------------------------------------------------ */
   Debugger::Debugger() {
     cout = &std::cerr;
     level = dblWarning;
     parallel_context = "";
     file_open = false;
     print_backtrace = false;
 
     initSignalHandler();
     std::set_terminate(terminate_handler);
   }
 
   /* ------------------------------------------------------------------------ */
   Debugger::~Debugger() {
     if (file_open) {
       dynamic_cast<std::ofstream *>(cout)->close();
       delete cout;
     }
   }
 
   /* ------------------------------------------------------------------------ */
   void Debugger::exit(int status) {
     if (status != 0)
       std::terminate();
 
     std::exit(0);
   }
 
   /*------------------------------------------------------------------------- */
   void Debugger::throwException(const std::string & info,
                                 const std::string & file, unsigned int line,
                                 __attribute__((unused)) bool silent,
                                 __attribute__((unused))
                                 const std::string & location) const
       noexcept(false) {
 
 #if !defined(AKANTU_NDEBUG)
     if (!silent) {
       printMessage("###", dblWarning, info + location);
     }
 #endif
 
     debug::Exception ex(info, file, line);
     throw ex;
   }
 
   /* ------------------------------------------------------------------------ */
   void Debugger::printMessage(const std::string & prefix,
                               const DebugLevel & level,
                               const std::string & info) const {
     if (this->level >= level) {
 #if defined(AKANTU_CORE_CXX11)
       double timestamp =
           std::chrono::duration_cast<std::chrono::duration<double, std::micro>>(
               std::chrono::system_clock::now().time_since_epoch())
               .count();
 #elif defined(AKANTU_USE_OBSOLETE_GETTIMEOFDAY)
       struct timeval time;
       gettimeofday(&time, NULL);
       double timestamp = time.tv_sec * 1e6 + time.tv_usec; /*in us*/
 #else
       struct timespec time;
       clock_gettime(CLOCK_REALTIME_COARSE, &time);
       double timestamp = time.tv_sec * 1e6 + time.tv_nsec * 1e-3; /*in us*/
 #endif
       *(cout) << parallel_context << "{" << (size_t)timestamp << "} " << prefix
               << " " << info << std::endl;
     }
   }
 
   /* ------------------------------------------------------------------------ */
   void Debugger::setDebugLevel(const DebugLevel & level) {
     this->level = level;
   }
 
   /* ------------------------------------------------------------------------ */
   const DebugLevel & Debugger::getDebugLevel() const { return this->level; }
 
   /* ------------------------------------------------------------------------ */
   void Debugger::setLogFile(const std::string & filename) {
     if (file_open) {
       dynamic_cast<std::ofstream *>(cout)->close();
       delete cout;
     }
 
     auto * fileout = new std::ofstream(filename.c_str());
     file_open = true;
     cout = fileout;
   }
 
   std::ostream & Debugger::getOutputStream() { return *cout; }
 
   /* ------------------------------------------------------------------------ */
   void Debugger::setParallelContext(int rank, int size) {
     std::stringstream sstr;
     UInt pad = std::ceil(std::log10(size));
     sstr << "<" << getpid() << ">[R" << std::setfill(' ') << std::right
          << std::setw(pad) << rank << "|S" << size << "] ";
     parallel_context = sstr.str();
   }
 
   void setDebugLevel(const DebugLevel & level) {
     debugger.setDebugLevel(level);
   }
 
   const DebugLevel & getDebugLevel() { return debugger.getDebugLevel(); }
 
   /* --------------------------------------------------------------------------
    */
   void exit(int status) { debugger.exit(status); }
 
 } // namespace debug
 } // namespace akantu
diff --git a/src/common/aka_error.hh b/src/common/aka_error.hh
index d06b8bb97..cf737bbc8 100644
--- a/src/common/aka_error.hh
+++ b/src/common/aka_error.hh
@@ -1,339 +1,339 @@
 /**
  * @file   aka_error.hh
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Mon Jun 14 2010
- * @date last modification: Mon Jul 13 2015
+ * @date last modification: Tue Feb 20 2018
  *
  * @brief  error management and internal exceptions
  *
  * @section LICENSE
  *
- * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
- * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
- * Solides)
+ * 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
+ * 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
+ * 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 <sstream>
 #include <typeinfo>
 #include <utility>
 /* -------------------------------------------------------------------------- */
 
 /* -------------------------------------------------------------------------- */
 #ifndef __AKANTU_ERROR_HH__
 #define __AKANTU_ERROR_HH__
 
 namespace akantu {
 /* -------------------------------------------------------------------------- */
 enum DebugLevel {
   dbl0 = 0,
   dblError = 0,
   dblAssert = 0,
   dbl1 = 1,
   dblException = 1,
   dblCritical = 1,
   dbl2 = 2,
   dblMajor = 2,
   dbl3 = 3,
   dblCall = 3,
   dblSecondary = 3,
   dblHead = 3,
   dbl4 = 4,
   dblWarning = 4,
   dbl5 = 5,
   dblInfo = 5,
   dbl6 = 6,
   dblIn = 6,
   dblOut = 6,
   dbl7 = 7,
   dbl8 = 8,
   dblTrace = 8,
   dbl9 = 9,
   dblAccessory = 9,
   dbl10 = 10,
   dblDebug = 42,
   dbl100 = 100,
   dblDump = 100,
   dblTest = 1337
 };
 
 /* -------------------------------------------------------------------------- */
 #define AKANTU_LOCATION                                                        \
   "(" << __func__ << "(): " << __FILE__ << ":" << __LINE__ << ")"
 
 /* -------------------------------------------------------------------------- */
 namespace debug {
   void setDebugLevel(const DebugLevel & level);
   const DebugLevel & getDebugLevel();
 
   void initSignalHandler();
   std::string demangle(const char * symbol);
 #ifndef SWIG
   std::string exec(const std::string & cmd);
 #endif
   void printBacktrace(int sig);
 
   void exit(int status) __attribute__((noreturn));
   /* ------------------------------------------------------------------------ */
   /// exception class that can be thrown by akantu
   class Exception : public std::exception {
     /* ---------------------------------------------------------------------- */
     /* Constructors/Destructors                                               */
     /* ---------------------------------------------------------------------- */
   protected:
     explicit Exception(std::string info = "")
         : _info(std::move(info)), _file("") {}
 
   public:
     //! full constructor
     Exception(std::string info, std::string file, unsigned int line)
         : _info(std::move(info)), _file(std::move(file)), _line(line) {}
 
     //! destructor
     ~Exception() noexcept override = default;
 
     /* ---------------------------------------------------------------------- */
     /*  Methods */
     /* ---------------------------------------------------------------------- */
   public:
     const char * what() const noexcept override { return _info.c_str(); }
 
     virtual const std::string info() const noexcept {
       std::stringstream stream;
       stream << debug::demangle(typeid(*this).name()) << " : " << _info << " ["
              << _file << ":" << _line << "]";
       return stream.str();
     }
 
   public:
     void setInfo(const std::string & info) { _info = info; }
     void setFile(const std::string & file) { _file = file; }
     void setLine(unsigned int line) { _line = line; }
     /* ---------------------------------------------------------------------- */
     /* Class Members                                                          */
     /* ---------------------------------------------------------------------- */
   protected:
     /// exception description and additionals
     std::string _info;
 
   private:
     /// file it is thrown from
     std::string _file;
 
     /// ligne it is thrown from
     unsigned int _line{0};
   };
 
   class CriticalError : public Exception {};
   class AssertException : public Exception {};
   class NotImplementedException : public Exception {};
 
   /// standard output stream operator
   inline std::ostream & operator<<(std::ostream & stream,
                                    const Exception & _this) {
     stream << _this.what();
     return stream;
   }
 
   /* --------------------------------------------------------------------------
    */
   class Debugger {
   public:
     Debugger();
     virtual ~Debugger();
     Debugger(const Debugger &) = default;
     Debugger & operator=(const Debugger &) = default;
 
     void exit(int status) __attribute__((noreturn));
 
     void throwException(const std::string & info, const std::string & file,
                         unsigned int line, bool, const std::string &) const
         noexcept(false) __attribute__((noreturn));
 
     /*----------------------------------------------------------------------- */
     template <class Except>
     void throwCustomException(const Except & ex, const std::string & info,
                               const std::string & file, unsigned int line) const
         noexcept(false) __attribute__((noreturn));
     /*----------------------------------------------------------------------- */
     template <class Except>
     void throwCustomException(const Except & ex, const std::string & file,
                               unsigned int line) const noexcept(false)
         __attribute__((noreturn));
 
     void printMessage(const std::string & prefix, const DebugLevel & level,
                       const std::string & info) const;
 
     void setOutStream(std::ostream & out) { cout = &out; }
     std::ostream & getOutStream() { return *cout; }
 
   public:
     void setParallelContext(int rank, int size);
 
     void setDebugLevel(const DebugLevel & level);
     const DebugLevel & getDebugLevel() const;
 
     void setLogFile(const std::string & filename);
     std::ostream & getOutputStream();
 
     inline bool testLevel(const DebugLevel & level) const {
       return (this->level >= (level));
     }
 
     void printBacktrace(bool on_off) { this->print_backtrace = on_off; }
     bool printBacktrace() { return this->print_backtrace; }
 
   private:
     std::string parallel_context;
     std::ostream * cout;
     bool file_open;
     DebugLevel level;
     bool print_backtrace;
   };
 
   extern Debugger debugger;
 } // namespace debug
 
 /* -------------------------------------------------------------------------- */
 #define AKANTU_STRINGSTREAM_IN(_str, _sstr)                                    \
   ;                                                                            \
   do {                                                                         \
     std::stringstream _dbg_s_info;                                             \
     _dbg_s_info << _sstr;                                                      \
     _str = _dbg_s_info.str();                                                  \
   } while (false)
 
 /* -------------------------------------------------------------------------- */
 #define AKANTU_EXCEPTION(info) AKANTU_EXCEPTION_(info, false)
 
 #define AKANTU_SILENT_EXCEPTION(info) AKANTU_EXCEPTION_(info, true)
 
 #define AKANTU_EXCEPTION_(info, silent)                                        \
   do {                                                                         \
     std::stringstream _dbg_str;                                                \
     _dbg_str << info;                                                          \
     std::stringstream _dbg_loc;                                                \
     _dbg_loc << AKANTU_LOCATION;                                               \
     ::akantu::debug::debugger.throwException(                                  \
         _dbg_str.str(), __FILE__, __LINE__, silent, _dbg_loc.str());           \
   } while (false)
 
 #define AKANTU_CUSTOM_EXCEPTION_INFO(ex, info)                                 \
   do {                                                                         \
     std::stringstream _dbg_str;                                                \
     _dbg_str << info;                                                          \
     ::akantu::debug::debugger.throwCustomException(ex, _dbg_str.str(),         \
                                                    __FILE__, __LINE__);        \
   } while (false)
 
 #define AKANTU_CUSTOM_EXCEPTION(ex)                                            \
   do {                                                                         \
     ::akantu::debug::debugger.throwCustomException(ex, __FILE__, __LINE__);    \
   } while (false)
 
 /* -------------------------------------------------------------------------- */
 #ifdef AKANTU_NDEBUG
 #define AKANTU_DEBUG_TEST(level) (false)
 #define AKANTU_DEBUG_LEVEL_IS_TEST()                                           \
   (::akantu::debug::debugger.testLevel(dblTest))
 #define AKANTU_DEBUG(level, info)
 #define AKANTU_DEBUG_(pref, level, info)
 #define AKANTU_DEBUG_IN()
 #define AKANTU_DEBUG_OUT()
 #define AKANTU_DEBUG_INFO(info)
 #define AKANTU_DEBUG_WARNING(info)
 #define AKANTU_DEBUG_TRACE(info)
 #define AKANTU_DEBUG_ASSERT(test, info)
 #define AKANTU_ERROR(info)                                                     \
   AKANTU_CUSTOM_EXCEPTION_INFO(::akantu::debug::CriticalError(), info)
 /* -------------------------------------------------------------------------- */
 #else
 #define AKANTU_DEBUG(level, info) AKANTU_DEBUG_("   ", level, info)
 
 #define AKANTU_DEBUG_(pref, level, info)                                       \
   do {                                                                         \
     std::string _dbg_str;                                                      \
     AKANTU_STRINGSTREAM_IN(_dbg_str, info << " " << AKANTU_LOCATION);          \
     ::akantu::debug::debugger.printMessage(pref, level, _dbg_str);             \
   } while (false)
 
 #define AKANTU_DEBUG_TEST(level) (::akantu::debug::debugger.testLevel(level))
 
 #define AKANTU_DEBUG_LEVEL_IS_TEST()                                           \
   (::akantu::debug::debugger.testLevel(dblTest))
 
 #define AKANTU_DEBUG_IN()                                                      \
   AKANTU_DEBUG_("==>", ::akantu::dblIn, __func__ << "()")
 
 #define AKANTU_DEBUG_OUT()                                                     \
   AKANTU_DEBUG_("<==", ::akantu::dblOut, __func__ << "()")
 
 #define AKANTU_DEBUG_INFO(info) AKANTU_DEBUG_("---", ::akantu::dblInfo, info)
 
 #define AKANTU_DEBUG_WARNING(info)                                             \
   AKANTU_DEBUG_("/!\\", ::akantu::dblWarning, info)
 
 #define AKANTU_DEBUG_TRACE(info) AKANTU_DEBUG_(">>>", ::akantu::dblTrace, info)
 
 #define AKANTU_DEBUG_ASSERT(test, info)                                        \
   do {                                                                         \
     if (not(test))                                                             \
       AKANTU_CUSTOM_EXCEPTION_INFO(::akantu::debug::AssertException(),         \
                                    "assert [" << #test << "] " << info);       \
   } while (false)
 
 #define AKANTU_ERROR(info)                                                     \
   do {                                                                         \
     AKANTU_DEBUG_("!!! ", ::akantu::dblError, info);                           \
     AKANTU_CUSTOM_EXCEPTION_INFO(::akantu::debug::CriticalError(), info);      \
   } while (false)
 #endif // AKANTU_NDEBUG
 
 #define AKANTU_TO_IMPLEMENT()                                                  \
   AKANTU_CUSTOM_EXCEPTION_INFO(::akantu::debug::NotImplementedException(),     \
                                __func__ << " : not implemented yet !")
 
 /* -------------------------------------------------------------------------- */
 
 namespace debug {
   /* ------------------------------------------------------------------------ */
   template <class Except>
   void Debugger::throwCustomException(const Except & ex,
                                       const std::string & info,
                                       const std::string & file,
                                       unsigned int line) const noexcept(false) {
     auto & nc_ex = const_cast<Except &>(ex);
     nc_ex.setInfo(info);
     nc_ex.setFile(file);
     nc_ex.setLine(line);
     throw ex;
   }
   /* ------------------------------------------------------------------------ */
   template <class Except>
   void Debugger::throwCustomException(const Except & ex,
                                       const std::string & file,
                                       unsigned int line) const noexcept(false) {
     auto & nc_ex = const_cast<Except &>(ex);
     nc_ex.setFile(file);
     nc_ex.setLine(line);
     throw ex;
   }
 } // namespace debug
 } // namespace akantu
 
 #endif /* __AKANTU_ERROR_HH__ */
diff --git a/src/common/aka_event_handler_manager.hh b/src/common/aka_event_handler_manager.hh
index 5fd229933..043493feb 100644
--- a/src/common/aka_event_handler_manager.hh
+++ b/src/common/aka_event_handler_manager.hh
@@ -1,126 +1,125 @@
 /**
  * @file   aka_event_handler_manager.hh
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Fri Jun 18 2010
- * @date last modification: Wed Dec 16 2015
+ * @date last modification: Sun Dec 03 2017
  *
  * @brief  Base of Event Handler classes
  *
  * @section LICENSE
  *
- * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
- * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
- * Solides)
+ * 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
+ * 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
+ * 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_AKA_EVENT_HANDLER_MANAGER_HH__
 #define __AKANTU_AKA_EVENT_HANDLER_MANAGER_HH__
 
 /* -------------------------------------------------------------------------- */
 #include "aka_common.hh"
 /* -------------------------------------------------------------------------- */
 #include <algorithm>
 #include <list>
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 
 template <class EventHandler> class EventHandlerManager {
 private:
   using priority_value = std::pair<EventHandlerPriority, EventHandler *>;
   using priority_list = std::list<priority_value>;
   struct KeyComp {
     bool operator()(const priority_value & a, const priority_value & b) const {
       return (a.first < b.first);
     }
     bool operator()(const priority_value & a, UInt b) const {
       return (a.first < b);
     }
   };
 
   /* ------------------------------------------------------------------------ */
   /* Constructors/Destructors                                                 */
   /* ------------------------------------------------------------------------ */
 public:
   virtual ~EventHandlerManager() { event_handlers.clear(); }
 
   /* ------------------------------------------------------------------------ */
   /* Methods                                                                  */
   /* ------------------------------------------------------------------------ */
 public:
   /// register a new EventHandler to the Manager. The register object
   /// will then be informed about the events the manager observes.
   void registerEventHandler(EventHandler & event_handler,
                             EventHandlerPriority priority = _ehp_highest) {
     auto it = this->searchEventHandler(event_handler);
 
     if (it != this->event_handlers.end()) {
       AKANTU_EXCEPTION("This event handler was already registered (priority: "
                        << priority << ")");
     }
 
     auto pos =
         std::lower_bound(this->event_handlers.begin(),
                          this->event_handlers.end(), priority, KeyComp());
 
     this->event_handlers.insert(pos, std::make_pair(priority, &event_handler));
   }
 
   /// unregister a EventHandler object. This object will not be
   /// notified anymore about the events this manager observes.
   void unregisterEventHandler(EventHandler & event_handler) {
     auto it = this->searchEventHandler(event_handler);
 
     if (it == this->event_handlers.end()) {
       AKANTU_EXCEPTION("This event handler is not registered");
     }
 
     this->event_handlers.erase(it);
   }
 
   /// Notify all the registered EventHandlers about the event that just occured.
   template <class Event> void sendEvent(const Event & event) {
     for (auto & pair : this->event_handlers)
       pair.second->sendEvent(event);
   }
 
 private:
   typename priority_list::iterator searchEventHandler(EventHandler & handler) {
     auto it = this->event_handlers.begin();
     auto end = this->event_handlers.end();
 
     for (; it != end && it->second != &handler; ++it)
       ;
 
     return it;
   }
 
   /* ------------------------------------------------------------------------ */
   /* Class Members                                                            */
   /* ------------------------------------------------------------------------ */
 private:
   /// list of the event handlers
   priority_list event_handlers;
 };
 
 } // namespace akantu
 
 #endif /* __AKANTU_AKA_EVENT_HANDLER_MANAGER_HH__ */
diff --git a/src/common/aka_extern.cc b/src/common/aka_extern.cc
index 78ae76cfa..f6fb3c004 100644
--- a/src/common/aka_extern.cc
+++ b/src/common/aka_extern.cc
@@ -1,109 +1,108 @@
 /**
  * @file   aka_extern.cc
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Mon Jun 14 2010
- * @date last modification: Thu Nov 19 2015
+ * @date last modification: Tue Feb 20 2018
  *
  * @brief  initialisation of all global variables
  * to insure the order of creation
  *
  * @section LICENSE
  *
- * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
- * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
- * Solides)
+ * 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
+ * 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
+ * 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_array.hh"
 #include "aka_common.hh"
 #include "aka_math.hh"
 #include "aka_named_argument.hh"
 #include "aka_random_generator.hh"
 #include "communication_tag.hh"
 #include "cppargparse.hh"
 #include "parser.hh"
 #include "solid_mechanics_model.hh"
 #if defined(AKANTU_COHESIVE_ELEMENT)
 #include "solid_mechanics_model_cohesive.hh"
 #endif
 /* -------------------------------------------------------------------------- */
 #include <iostream>
 #include <limits>
 /* -------------------------------------------------------------------------- */
 #if defined(AKANTU_DEBUG_TOOLS)
 #include "aka_debug_tools.hh"
 #endif
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 /* error.hpp variables                                                        */
 /* -------------------------------------------------------------------------- */
 namespace debug {
   /** \todo write function to get this
    *   values from the environment or a config file
    */
   /// standard output for debug messages
   std::ostream * _akantu_debug_cout = &std::cerr;
 
   /// standard output for normal messages
   std::ostream & _akantu_cout = std::cout;
 
   /// parallel context used in debug messages
   std::string _parallel_context = "";
 
   Debugger debugger;
 
 #if defined(AKANTU_DEBUG_TOOLS)
   DebugElementManager element_manager;
 #endif
 } // namespace debug
 
 /* -------------------------------------------------------------------------- */
 /// list of ghost iterable types
 ghost_type_t ghost_types(_casper);
 
 /* -------------------------------------------------------------------------- */
 /// Paser for commandline arguments
 ::cppargparse::ArgumentParser static_argparser;
 
 /// Parser containing the information parsed by the input file given to initFull
 Parser static_parser;
 
 bool Parser::permissive_parser = false;
 
 /* -------------------------------------------------------------------------- */
 Real Math::tolerance = 1e2 * std::numeric_limits<Real>::epsilon();
 
 /* -------------------------------------------------------------------------- */
 const UInt _all_dimensions = UInt(-1);
 
 /* -------------------------------------------------------------------------- */
 const Array<UInt> empty_filter(0, 1, "empty_filter");
 
 /* -------------------------------------------------------------------------- */
 template <> long int RandomGenerator<UInt>::_seed = 5489u;
 template <> std::default_random_engine RandomGenerator<UInt>::generator(5489u);
 /* -------------------------------------------------------------------------- */
 int Tag::max_tag = 0;
 
 /* -------------------------------------------------------------------------- */
 
 } // namespace akantu
diff --git a/src/common/aka_factory.hh b/src/common/aka_factory.hh
index 64bd867f6..a278ef69d 100644
--- a/src/common/aka_factory.hh
+++ b/src/common/aka_factory.hh
@@ -1,83 +1,85 @@
 /**
  * @file   aka_factory.hh
  *
- * @author Nicolas Richart
+ * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
- * @date creation  Thu Jul 06 2017
+ * @date creation: Sun Jul 09 2017
+ * @date last modification: Fri Dec 08 2017
  *
- * @brief This is a generic factory
+ * @brief  This is a generic factory
  *
  * @section LICENSE
  *
- * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * 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
+ * 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
+ * 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 <functional>
 #include <map>
 #include <memory>
 #include <string>
 /* -------------------------------------------------------------------------- */
 
 #ifndef __AKANTU_AKA_FACTORY_HH__
 #define __AKANTU_AKA_FACTORY_HH__
 
 namespace akantu {
 
 template <class Base, class T = ID, class... Args> class Factory {
   using allocator_t = std::function<std::unique_ptr<Base>(Args...)>;
 
 private:
   Factory() = default;
 
 public:
   Factory(const Factory &) = delete;
   Factory & operator=(const Factory &) = delete;
 
   static Factory & getInstance() {
     static Factory instance;
     return instance;
   }
   /* ------------------------------------------------------------------------ */
   bool registerAllocator(const T & id, const allocator_t & allocator) {
     if (allocators.find(id) != allocators.end())
       AKANTU_EXCEPTION("The id " << id << " is already registered in the "
                                  << debug::demangle(typeid(Base).name())
                                  << " factory");
     allocators[id] = allocator;
     return true;
   }
 
   template <typename... AArgs>
   std::unique_ptr<Base> allocate(const T & id, AArgs &&... args) const {
     if (allocators.find(id) == allocators.end())
       AKANTU_EXCEPTION("The id  " << id << " is not registered in the "
                                   << debug::demangle(typeid(Base).name())
                                   << " factory.");
     return std::forward<std::unique_ptr<Base>>(
         allocators.at(id)(std::forward<AArgs>(args)...));
   }
 
 private:
   std::map<T, allocator_t> allocators;
 };
 
 } // namespace akantu
 
 #endif /* __AKANTU_AKA_FACTORY_HH__ */
diff --git a/src/common/aka_fwd.hh b/src/common/aka_fwd.hh
index 9055e696b..0ec003f5a 100644
--- a/src/common/aka_fwd.hh
+++ b/src/common/aka_fwd.hh
@@ -1,72 +1,72 @@
 /**
  * @file   aka_fwd.hh
  *
  * @author Alejandro M. Aragón <alejandro.aragon@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Fri Apr 13 2012
- * @date last modification: Tue Aug 18 2015
+ * @date last modification: Wed Oct 25 2017
  *
  * @brief  File containing forward declarations in akantu.
  * This file helps if circular #include would be needed because two classes
  * refer both to each other. This file usually does not need any modification.
  *
  * @section LICENSE
  *
- * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
- * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
- * Solides)
+ * 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
+ * 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
+ * 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_FWD_HH__
 #define __AKANTU_FWD_HH__
 
 namespace cppargparse {
 class ArgumentParser;
 }
 
 namespace akantu {
 // forward declaration
 template <int dim, class model_type> struct ContactData;
 
 template <typename T> class Matrix;
 template <typename T> class Vector;
 template <typename T> class Tensor3;
 
 template <typename T, bool is_scal = is_scalar<T>::value> class Array;
 template <typename T, typename SupportType = ElementType>
 class ElementTypeMapArray;
 
 template <class T> class SpatialGrid;
 
 // Model element
 template <class ModelPolicy> class ModelElement;
 
 extern const Array<UInt> empty_filter;
 
 class Parser;
 class ParserSection;
 
 extern Parser static_parser;
 
 extern cppargparse::ArgumentParser static_argparser;
 
 class Mesh;
 class SparseMatrix;
 } // namespace akantu
 
 #endif /* __AKANTU_FWD_HH__ */
diff --git a/src/common/aka_grid_dynamic.hh b/src/common/aka_grid_dynamic.hh
index f43007915..d717b12c8 100644
--- a/src/common/aka_grid_dynamic.hh
+++ b/src/common/aka_grid_dynamic.hh
@@ -1,512 +1,512 @@
 /**
  * @file   aka_grid_dynamic.hh
  *
  * @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Thu Feb 21 2013
- * @date last modification: Sat Sep 26 2015
+ * @date last modification: Wed Nov 08 2017
  *
  * @brief  Grid that is auto balanced
  *
  * @section LICENSE
  *
- * Copyright  (©)  2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de Lausanne)
+ * 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
+ * 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
+ * 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_array.hh"
 #include "aka_common.hh"
 #include "aka_types.hh"
 
 #include <iostream>
 
 /* -------------------------------------------------------------------------- */
 #include <map>
 /* -------------------------------------------------------------------------- */
 
 #ifndef __AKANTU_AKA_GRID_DYNAMIC_HH__
 #define __AKANTU_AKA_GRID_DYNAMIC_HH__
 
 namespace akantu {
 
 class Mesh;
 
 template <typename T> class SpatialGrid {
 public:
   explicit SpatialGrid(UInt dimension)
       : dimension(dimension), spacing(dimension), center(dimension),
         lower(dimension), upper(dimension), empty_cell() {}
 
   SpatialGrid(UInt dimension, const Vector<Real> & spacing,
               const Vector<Real> & center)
       : dimension(dimension), spacing(spacing), center(center),
         lower(dimension), upper(dimension), empty_cell() {
     for (UInt i = 0; i < dimension; ++i) {
       lower(i) = std::numeric_limits<Real>::max();
       upper(i) = -std::numeric_limits<Real>::max();
     }
   }
 
   virtual ~SpatialGrid() = default;
 
   class neighbor_cells_iterator;
   class cells_iterator;
 
   class CellID {
   public:
     CellID() : ids() {}
     explicit CellID(UInt dimention) : ids(dimention) {}
     void setID(UInt dir, Int id) { ids(dir) = id; }
     Int getID(UInt dir) const { return ids(dir); }
 
     bool operator<(const CellID & id) const {
       return std::lexicographical_compare(
           ids.storage(), ids.storage() + ids.size(), id.ids.storage(),
           id.ids.storage() + id.ids.size());
     }
 
     bool operator==(const CellID & id) const {
       return std::equal(ids.storage(), ids.storage() + ids.size(),
                         id.ids.storage());
     }
 
     bool operator!=(const CellID & id) const { return !(operator==(id)); }
 
     class neighbor_cells_iterator
         : private std::iterator<std::forward_iterator_tag, UInt> {
     public:
       neighbor_cells_iterator(const CellID & cell_id, bool end)
           : cell_id(cell_id), position(cell_id.ids.size(), end ? 1 : -1) {
 
         this->updateIt();
         if (end)
           this->it++;
       }
 
       neighbor_cells_iterator & operator++() {
         UInt i = 0;
         for (; i < position.size() && position(i) == 1; ++i)
           ;
 
         if (i == position.size()) {
           ++it;
           return *this;
         }
 
         for (UInt j = 0; j < i; ++j)
           position(j) = -1;
         position(i)++;
         updateIt();
 
         return *this;
       }
 
       neighbor_cells_iterator operator++(int) {
         neighbor_cells_iterator tmp(*this);
         operator++();
         return tmp;
       };
 
       bool operator==(const neighbor_cells_iterator & rhs) const {
         return cell_id == rhs.cell_id && it == rhs.it;
       };
       bool operator!=(const neighbor_cells_iterator & rhs) const {
         return !operator==(rhs);
       };
 
       CellID operator*() const {
         CellID cur_cell_id(cell_id);
         cur_cell_id.ids += position;
         return cur_cell_id;
       };
 
     private:
       void updateIt() {
         it = 0;
         for (UInt i = 0; i < position.size(); ++i)
           it = it * 3 + (position(i) + 1);
       }
 
     private:
       /// central cell id
       const CellID & cell_id;
       // number representing the current neighbor in base 3;
       UInt it;
       // current cell shift
       Vector<Int> position;
     };
 
     class Neighbors {
     public:
       explicit Neighbors(const CellID & cell_id) : cell_id(cell_id) {}
       decltype(auto) begin() { return neighbor_cells_iterator(cell_id, false); }
       decltype(auto) end() { return neighbor_cells_iterator(cell_id, true); }
 
     private:
       const CellID & cell_id;
     };
 
     decltype(auto) neighbors() { return Neighbors(*this); }
 
   private:
     friend class cells_iterator;
     Vector<Int> ids;
   };
 
   /* ------------------------------------------------------------------------ */
   class Cell {
   public:
     using iterator = typename std::vector<T>::iterator;
     using const_iterator = typename std::vector<T>::const_iterator;
 
     Cell() : id(), data() {}
 
     explicit Cell(const CellID & cell_id) : id(cell_id), data() {}
 
     bool operator==(const Cell & cell) const { return id == cell.id; }
     bool operator!=(const Cell & cell) const { return id != cell.id; }
 
     Cell & add(const T & d) {
       data.push_back(d);
       return *this;
     }
 
     iterator begin() { return data.begin(); }
     const_iterator begin() const { return data.begin(); }
 
     iterator end() { return data.end(); }
     const_iterator end() const { return data.end(); }
 
   private:
     CellID id;
     std::vector<T> data;
   };
 
 private:
   using cells_container = std::map<CellID, Cell>;
 
 public:
   const Cell & getCell(const CellID & cell_id) const {
     auto it = cells.find(cell_id);
     if (it != cells.end())
       return it->second;
     return empty_cell;
   }
 
   decltype(auto) beginCell(const CellID & cell_id) {
     auto it = cells.find(cell_id);
     if (it != cells.end())
       return it->second.begin();
     return empty_cell.begin();
   }
 
   decltype(auto) endCell(const CellID & cell_id) {
     auto it = cells.find(cell_id);
     if (it != cells.end())
       return it->second.end();
     return empty_cell.end();
   }
 
   decltype(auto) beginCell(const CellID & cell_id) const {
     auto it = cells.find(cell_id);
     if (it != cells.end())
       return it->second.begin();
     return empty_cell.begin();
   }
 
   decltype(auto) endCell(const CellID & cell_id) const {
     auto it = cells.find(cell_id);
     if (it != cells.end())
       return it->second.end();
     return empty_cell.end();
   }
 
   /* ------------------------------------------------------------------------ */
   class cells_iterator
       : private std::iterator<std::forward_iterator_tag, CellID> {
   public:
     explicit cells_iterator(typename std::map<CellID, Cell>::const_iterator it)
         : it(it) {}
 
     cells_iterator & operator++() {
       this->it++;
       return *this;
     }
 
     cells_iterator operator++(int) {
       cells_iterator tmp(*this);
       operator++();
       return tmp;
     };
 
     bool operator==(const cells_iterator & rhs) const { return it == rhs.it; };
     bool operator!=(const cells_iterator & rhs) const {
       return !operator==(rhs);
     };
 
     CellID operator*() const {
       CellID cur_cell_id(this->it->first);
       return cur_cell_id;
     };
 
   private:
     /// map iterator
     typename std::map<CellID, Cell>::const_iterator it;
   };
 
 public:
   template <class vector_type>
   Cell & insert(const T & d, const vector_type & position) {
     auto && cell_id = getCellID(position);
     auto && it = cells.find(cell_id);
     if (it == cells.end()) {
       Cell cell(cell_id);
       auto & tmp = (cells[cell_id] = cell).add(d);
 
       for (UInt i = 0; i < dimension; ++i) {
         Real posl = center(i) + cell_id.getID(i) * spacing(i);
         Real posu = posl + spacing(i);
         if (posl < lower(i))
           lower(i) = posl;
         if (posu > upper(i))
           upper(i) = posu;
       }
       return tmp;
     } else {
       return it->second.add(d);
     }
   }
 
   /* ------------------------------------------------------------------------ */
   inline decltype(auto) begin() const {
     auto begin = this->cells.begin();
     return cells_iterator(begin);
   }
 
   inline decltype(auto) end() const {
     auto end = this->cells.end();
     return cells_iterator(end);
   }
 
   template <class vector_type>
   CellID getCellID(const vector_type & position) const {
     CellID cell_id(dimension);
     for (UInt i = 0; i < dimension; ++i) {
       cell_id.setID(i, getCellID(position(i), i));
     }
     return cell_id;
   }
 
   void printself(std::ostream & stream, int indent = 0) const {
     std::string space;
     for (Int i = 0; i < indent; i++, space += AKANTU_INDENT)
       ;
 
     std::streamsize prec = stream.precision();
     std::ios_base::fmtflags ff = stream.flags();
 
     stream.setf(std::ios_base::showbase);
     stream.precision(5);
 
     stream << space << "SpatialGrid<" << debug::demangle(typeid(T).name())
            << "> [" << std::endl;
     stream << space << " + dimension    : " << this->dimension << std::endl;
     stream << space << " + lower bounds : {";
     for (UInt i = 0; i < lower.size(); ++i) {
       if (i != 0)
         stream << ", ";
       stream << lower(i);
     };
     stream << "}" << std::endl;
     stream << space << " + upper bounds : {";
     for (UInt i = 0; i < upper.size(); ++i) {
       if (i != 0)
         stream << ", ";
       stream << upper(i);
     };
     stream << "}" << std::endl;
     stream << space << " + spacing : {";
     for (UInt i = 0; i < spacing.size(); ++i) {
       if (i != 0)
         stream << ", ";
       stream << spacing(i);
     };
     stream << "}" << std::endl;
     stream << space << " + center : {";
     for (UInt i = 0; i < center.size(); ++i) {
       if (i != 0)
         stream << ", ";
       stream << center(i);
     };
     stream << "}" << std::endl;
 
     stream << space << " + nb_cells     : " << this->cells.size() << "/";
     Vector<Real> dist(this->dimension);
     dist = upper;
     dist -= lower;
     for (UInt i = 0; i < this->dimension; ++i) {
       dist(i) /= spacing(i);
     }
     UInt nb_cells = std::ceil(dist(0));
     for (UInt i = 1; i < this->dimension; ++i) {
       nb_cells *= std::ceil(dist(i));
     }
     stream << nb_cells << std::endl;
     stream << space << "]" << std::endl;
 
     stream.precision(prec);
     stream.flags(ff);
   }
 
   void saveAsMesh(Mesh & mesh) const;
 
 private:
   /* --------------------------------------------------------------------------
    */
   inline UInt getCellID(Real position, UInt direction) const {
     AKANTU_DEBUG_ASSERT(direction < center.size(),
                         "The direction asked (" << direction
                                                 << ") is out of range "
                                                 << center.size());
     Real dist_center = position - center(direction);
     Int id = std::floor(dist_center / spacing(direction));
     // if(dist_center < 0) id--;
     return id;
   }
 
   friend class GridSynchronizer;
 
 public:
   AKANTU_GET_MACRO(LowerBounds, lower, const Vector<Real> &);
   AKANTU_GET_MACRO(UpperBounds, upper, const Vector<Real> &);
   AKANTU_GET_MACRO(Spacing, spacing, const Vector<Real> &);
 
 protected:
   UInt dimension;
 
   cells_container cells;
 
   Vector<Real> spacing;
   Vector<Real> center;
 
   Vector<Real> lower;
   Vector<Real> upper;
 
   Cell empty_cell;
 };
 
 /// standard output stream operator
 template <typename T>
 inline std::ostream & operator<<(std::ostream & stream,
                                  const SpatialGrid<T> & _this) {
   _this.printself(stream);
   return stream;
 }
 
 } // namespace akantu
 #include "mesh.hh"
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 template <typename T> void SpatialGrid<T>::saveAsMesh(Mesh & mesh) const {
   auto & nodes = const_cast<Array<Real> &>(mesh.getNodes());
 
   ElementType type;
   switch (dimension) {
   case 1:
     type = _segment_2;
     break;
   case 2:
     type = _quadrangle_4;
     break;
   case 3:
     type = _hexahedron_8;
     break;
   }
 
   mesh.addConnectivityType(type);
   auto & connectivity = const_cast<Array<UInt> &>(mesh.getConnectivity(type));
   auto & uint_data = mesh.getDataPointer<UInt>("tag_1", type);
 
   Vector<Real> pos(dimension);
 
   UInt global_id = 0;
   for (auto & cell_pair : cells) {
     UInt cur_node = nodes.size();
     UInt cur_elem = connectivity.size();
     const CellID & cell_id = cell_pair.first;
 
     for (UInt i = 0; i < dimension; ++i)
       pos(i) = center(i) + cell_id.getID(i) * spacing(i);
     nodes.push_back(pos);
     for (UInt i = 0; i < dimension; ++i)
       pos(i) += spacing(i);
     nodes.push_back(pos);
 
     connectivity.push_back(cur_node);
     switch (dimension) {
     case 1:
       connectivity(cur_elem, 1) = cur_node + 1;
       break;
     case 2:
       pos(0) -= spacing(0);
       nodes.push_back(pos);
       pos(0) += spacing(0);
       pos(1) -= spacing(1);
       nodes.push_back(pos);
       connectivity(cur_elem, 1) = cur_node + 3;
       connectivity(cur_elem, 2) = cur_node + 1;
       connectivity(cur_elem, 3) = cur_node + 2;
       break;
     case 3:
       pos(1) -= spacing(1);
       pos(2) -= spacing(2);
       nodes.push_back(pos);
       pos(1) += spacing(1);
       nodes.push_back(pos);
       pos(0) -= spacing(0);
       nodes.push_back(pos);
 
       pos(1) -= spacing(1);
       pos(2) += spacing(2);
       nodes.push_back(pos);
       pos(0) += spacing(0);
       nodes.push_back(pos);
       pos(0) -= spacing(0);
       pos(1) += spacing(1);
       nodes.push_back(pos);
 
       connectivity(cur_elem, 1) = cur_node + 2;
       connectivity(cur_elem, 2) = cur_node + 3;
       connectivity(cur_elem, 3) = cur_node + 4;
       connectivity(cur_elem, 4) = cur_node + 5;
       connectivity(cur_elem, 5) = cur_node + 6;
       connectivity(cur_elem, 6) = cur_node + 1;
       connectivity(cur_elem, 7) = cur_node + 7;
       break;
     }
     uint_data.push_back(global_id);
 
     ++global_id;
   }
 }
 
 } // namespace akantu
 
 #endif /* __AKANTU_AKA_GRID_DYNAMIC_HH__ */
diff --git a/src/common/aka_iterators.hh b/src/common/aka_iterators.hh
index 7eed4b058..b9a33e8b1 100644
--- a/src/common/aka_iterators.hh
+++ b/src/common/aka_iterators.hh
@@ -1,352 +1,354 @@
 /**
  * @file   aka_iterators.hh
  *
- * @author Nicolas Richart
+ * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
- * @date creation  Wed Jul 19 2017
+ * @date creation: Fri Aug 11 2017
+ * @date last modification: Mon Jan 29 2018
  *
- * @brief iterator interfaces
+ * @brief  iterator interfaces
  *
  * @section LICENSE
  *
- * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * 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
+ * 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
+ * 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 <tuple>
 #include <utility>
 /* -------------------------------------------------------------------------- */
 
 #ifndef __AKANTU_AKA_ITERATORS_HH__
 #define __AKANTU_AKA_ITERATORS_HH__
 
 namespace akantu {
 
 namespace tuple {
   /* ------------------------------------------------------------------------ */
   namespace details {
     template <size_t N> struct Foreach {
       template <class Tuple>
       static inline bool not_equal(Tuple && a, Tuple && b) {
         if (std::get<N - 1>(std::forward<Tuple>(a)) ==
             std::get<N - 1>(std::forward<Tuple>(b)))
           return false;
         return Foreach<N - 1>::not_equal(std::forward<Tuple>(a),
                                          std::forward<Tuple>(b));
       }
     };
 
     /* ---------------------------------------------------------------------- */
     template <> struct Foreach<0> {
       template <class Tuple>
       static inline bool not_equal(Tuple && a, Tuple && b) {
         return std::get<0>(std::forward<Tuple>(a)) !=
                std::get<0>(std::forward<Tuple>(b));
       }
     };
 
     template <typename... Ts>
     decltype(auto) make_tuple_no_decay(Ts &&... args) {
       return std::tuple<Ts...>(std::forward<Ts>(args)...);
     }
 
     template <class F, class Tuple, size_t... Is>
     void foreach_impl(F && func, Tuple && tuple,
                       std::index_sequence<Is...> &&) {
       (void)std::initializer_list<int>{
           (std::forward<F>(func)(std::get<Is>(std::forward<Tuple>(tuple))),
            0)...};
     }
 
     template <class F, class Tuple, size_t... Is>
     decltype(auto) transform_impl(F && func, Tuple && tuple,
                                   std::index_sequence<Is...> &&) {
       return make_tuple_no_decay(
           std::forward<F>(func)(std::get<Is>(std::forward<Tuple>(tuple)))...);
     }
   } // namespace details
 
   /* ------------------------------------------------------------------------ */
   template <class Tuple> bool are_not_equal(Tuple && a, Tuple && b) {
     return details::Foreach<std::tuple_size<std::decay_t<Tuple>>::value>::
         not_equal(std::forward<Tuple>(a), std::forward<Tuple>(b));
   }
 
   template <class F, class Tuple> void foreach (F && func, Tuple && tuple) {
     return details::foreach_impl(
         std::forward<F>(func), std::forward<Tuple>(tuple),
         std::make_index_sequence<
             std::tuple_size<std::decay_t<Tuple>>::value>{});
   }
 
   template <class F, class Tuple>
   decltype(auto) transform(F && func, Tuple && tuple) {
     return details::transform_impl(
         std::forward<F>(func), std::forward<Tuple>(tuple),
         std::make_index_sequence<
             std::tuple_size<std::decay_t<Tuple>>::value>{});
   }
 } // namespace tuple
 
 /* -------------------------------------------------------------------------- */
 namespace iterators {
   namespace {
     template <typename It, typename category>
     struct is_at_least_category
         : std::is_same<std::common_type_t<
                            typename std::iterator_traits<It>::iterator_category,
                            category>,
                        category> {};
   }
 
   template <class... Iterators> class ZipIterator {
   public:
     using value_type =
         std::tuple<typename std::iterator_traits<Iterators>::value_type...>;
     using difference_type = std::common_type_t<
         typename std::iterator_traits<Iterators>::difference_type...>;
     using pointer =
         std::tuple<typename std::iterator_traits<Iterators>::pointer...>;
     using reference =
         std::tuple<typename std::iterator_traits<Iterators>::reference...>;
     using iterator_category = std::input_iterator_tag;
     // std::common_type_t<typename
     // std::iterator_traits<Iterators>::iterator_category...>;
 
   private:
     using tuple_t = std::tuple<Iterators...>;
 
   public:
     explicit ZipIterator(tuple_t iterators) : iterators(std::move(iterators)) {}
 
     // input iterator ++it
     ZipIterator & operator++() {
       tuple::foreach ([](auto && it) { ++it; }, iterators);
       return *this;
     }
 
     // input iterator it++
     ZipIterator operator++(int) {
       auto cpy = *this;
       tuple::foreach ([](auto && it) { ++it; }, iterators);
       return cpy;
     }
 
     // input iterator it != other_it
     bool operator!=(const ZipIterator & other) const {
       return tuple::are_not_equal(iterators, other.iterators);
     }
 
     // input iterator dereference *it
     decltype(auto) operator*() {
       return tuple::transform([](auto && it) -> decltype(auto) { return *it; },
                               iterators);
     }
 
     bool operator==(const ZipIterator & other) const {
       return not tuple::are_not_equal(iterators, other.iterators);
     }
 
   private:
     tuple_t iterators;
   };
 } // namespace iterators
 
 /* -------------------------------------------------------------------------- */
 template <class... Iterators>
 decltype(auto) zip_iterator(std::tuple<Iterators...> && iterators_tuple) {
   auto zip = iterators::ZipIterator<Iterators...>(
       std::forward<decltype(iterators_tuple)>(iterators_tuple));
   return zip;
 }
 
 /* -------------------------------------------------------------------------- */
 namespace containers {
   template <class... Containers> class ZipContainer {
     using containers_t = std::tuple<Containers...>;
 
   public:
     explicit ZipContainer(Containers &&... containers)
         : containers(std::forward<Containers>(containers)...) {}
 
     decltype(auto) begin() const {
       return zip_iterator(
           tuple::transform([](auto && c) { return c.begin(); },
                            std::forward<containers_t>(containers)));
     }
 
     decltype(auto) end() const {
       return zip_iterator(
           tuple::transform([](auto && c) { return c.end(); },
                            std::forward<containers_t>(containers)));
     }
 
     decltype(auto) begin() {
       return zip_iterator(
           tuple::transform([](auto && c) { return c.begin(); },
                            std::forward<containers_t>(containers)));
     }
 
     decltype(auto) end() {
       return zip_iterator(
           tuple::transform([](auto && c) { return c.end(); },
                            std::forward<containers_t>(containers)));
     }
 
   private:
     containers_t containers;
   };
 
   template <class Iterator> class Range {
   public:
     explicit Range(Iterator && it1, Iterator && it2)
         : iterators(std::forward<Iterator>(it1), std::forward<Iterator>(it2)) {}
 
     decltype(auto) begin() const { return std::get<0>(iterators); }
     decltype(auto) begin() { return std::get<0>(iterators); }
 
     decltype(auto) end() const { return std::get<1>(iterators); }
     decltype(auto) end() { return std::get<1>(iterators); }
 
   private:
     std::tuple<Iterator, Iterator> iterators;
   };
 } // namespace containers
 
 /* -------------------------------------------------------------------------- */
 template <class... Containers> decltype(auto) zip(Containers &&... conts) {
   return containers::ZipContainer<Containers...>(
       std::forward<Containers>(conts)...);
 }
 
 template <class Iterator>
 decltype(auto) range(Iterator && it1, Iterator && it2) {
   return containers::Range<Iterator>(std::forward<Iterator>(it1),
                                      std::forward<Iterator>(it2));
 }
 /* -------------------------------------------------------------------------- */
 /* Arange                                                                     */
 /* -------------------------------------------------------------------------- */
 namespace iterators {
   template <class T> class ArangeIterator {
   public:
     using value_type = T;
     using pointer = T *;
     using reference = T &;
     using difference_type = size_t;
     using iterator_category = std::input_iterator_tag;
 
     constexpr ArangeIterator(T value, T step) : value(value), step(step) {}
     constexpr ArangeIterator(const ArangeIterator &) = default;
 
     constexpr ArangeIterator & operator++() {
       value += step;
       return *this;
     }
 
     constexpr T operator*() const { return value; }
 
     constexpr bool operator==(const ArangeIterator & other) const {
       return (value == other.value) and (step == other.step);
     }
 
     constexpr bool operator!=(const ArangeIterator & other) const {
       return not operator==(other);
     }
 
   private:
     T value{0};
     const T step{1};
   };
 } // namespace iterators
 
 namespace containers {
   template <class T> class ArangeContainer {
   public:
     using iterator = iterators::ArangeIterator<T>;
 
     constexpr ArangeContainer(T start, T stop, T step = 1)
         : start(start), stop((stop - start) % step == 0
                                  ? stop
                                  : start + (1 + (stop - start) / step) * step),
           step(step) {}
     explicit constexpr ArangeContainer(T stop) : ArangeContainer(0, stop, 1) {}
 
     constexpr T operator[](size_t i) {
       T val = start + i * step;
       assert(val < stop && "i is out of range");
       return val;
     }
 
     constexpr T size() { return (stop - start) / step; }
 
     constexpr iterator begin() { return iterator(start, step); }
     constexpr iterator end() { return iterator(stop, step); }
 
   private:
     const T start{0}, stop{0}, step{1};
   };
 } // namespace containers
 
 template <class T,
           typename = std::enable_if_t<std::is_integral<std::decay_t<T>>::value>>
 inline decltype(auto) arange(const T & stop) {
   return containers::ArangeContainer<T>(stop);
 }
 
 template <class T1, class T2,
           typename = std::enable_if_t<
               std::is_integral<std::common_type_t<T1, T2>>::value>>
 inline constexpr decltype(auto) arange(const T1 & start, const T2 & stop) {
   return containers::ArangeContainer<std::common_type_t<T1, T2>>(start, stop);
 }
 
 template <class T1, class T2, class T3,
           typename = std::enable_if_t<
               std::is_integral<std::common_type_t<T1, T2, T3>>::value>>
 inline constexpr decltype(auto) arange(const T1 & start, const T2 & stop,
                                        const T3 & step) {
   return containers::ArangeContainer<std::common_type_t<T1, T2, T3>>(
       start, stop, step);
 }
 
 /* -------------------------------------------------------------------------- */
 template <class Container>
 inline constexpr decltype(auto) enumerate(Container && container,
                                           size_t start_ = 0) {
   auto stop = std::forward<Container>(container).size();
   decltype(stop) start = start_;
   return zip(arange(start, stop), std::forward<Container>(container));
 }
 
 } // namespace akantu
 
 namespace std {
 template <typename... Its>
 struct iterator_traits<::akantu::iterators::ZipIterator<Its...>> {
   using iterator_category = forward_iterator_tag;
   using value_type =
       typename ::akantu::iterators::ZipIterator<Its...>::value_type;
   using difference_type =
       typename ::akantu::iterators::ZipIterator<Its...>::difference_type;
   using pointer = typename ::akantu::iterators::ZipIterator<Its...>::pointer;
   using reference =
       typename ::akantu::iterators::ZipIterator<Its...>::reference;
 };
 }
 
 #endif /* __AKANTU_AKA_ITERATORS_HH__ */
diff --git a/src/common/aka_math.cc b/src/common/aka_math.cc
index 09ad498d8..09bd4270d 100644
--- a/src/common/aka_math.cc
+++ b/src/common/aka_math.cc
@@ -1,251 +1,250 @@
 /**
  * @file   aka_math.cc
  *
  * @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
  * @author Marion Estelle Chambart <marion.chambart@epfl.ch>
  * @author David Simon Kammer <david.kammer@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: Fri May 15 2015
+ * @date last modification: Sun Aug 13 2017
  *
  * @brief  Implementation of the math toolbox
  *
  * @section LICENSE
  *
- * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
- * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
- * Solides)
+ * 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
+ * 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
+ * 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_math.hh"
 #include "aka_array.hh"
 
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 void Math::matrix_vector(UInt m, UInt n, const Array<Real> & A,
                          const Array<Real> & x, Array<Real> & y, Real alpha) {
   AKANTU_DEBUG_IN();
 
   AKANTU_DEBUG_ASSERT(A.size() == x.size(),
                       "The vector A(" << A.getID() << ") and the vector x("
                                       << x.getID()
                                       << ") must have the same size");
 
   AKANTU_DEBUG_ASSERT(A.getNbComponent() == m * n,
                       "The vector A(" << A.getID()
                                       << ") has the good number of component.");
 
   AKANTU_DEBUG_ASSERT(
       x.getNbComponent() == n,
       "The vector x(" << x.getID() << ") do not the good number of component.");
 
   AKANTU_DEBUG_ASSERT(
       y.getNbComponent() == n,
       "The vector y(" << y.getID() << ") do not the good number of component.");
 
   UInt nb_element = A.size();
   UInt offset_A = A.getNbComponent();
   UInt offset_x = x.getNbComponent();
 
   y.resize(nb_element);
 
   Real * A_val = A.storage();
   Real * x_val = x.storage();
   Real * y_val = y.storage();
 
   for (UInt el = 0; el < nb_element; ++el) {
     matrix_vector(m, n, A_val, x_val, y_val, alpha);
 
     A_val += offset_A;
     x_val += offset_x;
     y_val += offset_x;
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void Math::matrix_matrix(UInt m, UInt n, UInt k, const Array<Real> & A,
                          const Array<Real> & B, Array<Real> & C, Real alpha) {
   AKANTU_DEBUG_IN();
 
   AKANTU_DEBUG_ASSERT(A.size() == B.size(),
                       "The vector A(" << A.getID() << ") and the vector B("
                                       << B.getID()
                                       << ") must have the same size");
 
   AKANTU_DEBUG_ASSERT(A.getNbComponent() == m * k,
                       "The vector A(" << A.getID()
                                       << ") has the good number of component.");
 
   AKANTU_DEBUG_ASSERT(
       B.getNbComponent() == k * n,
       "The vector B(" << B.getID() << ") do not the good number of component.");
 
   AKANTU_DEBUG_ASSERT(
       C.getNbComponent() == m * n,
       "The vector C(" << C.getID() << ") do not the good number of component.");
 
   UInt nb_element = A.size();
   UInt offset_A = A.getNbComponent();
   UInt offset_B = B.getNbComponent();
   UInt offset_C = C.getNbComponent();
 
   C.resize(nb_element);
 
   Real * A_val = A.storage();
   Real * B_val = B.storage();
   Real * C_val = C.storage();
 
   for (UInt el = 0; el < nb_element; ++el) {
     matrix_matrix(m, n, k, A_val, B_val, C_val, alpha);
 
     A_val += offset_A;
     B_val += offset_B;
     C_val += offset_C;
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void Math::matrix_matrixt(UInt m, UInt n, UInt k, const Array<Real> & A,
                           const Array<Real> & B, Array<Real> & C, Real alpha) {
   AKANTU_DEBUG_IN();
 
   AKANTU_DEBUG_ASSERT(A.size() == B.size(),
                       "The vector A(" << A.getID() << ") and the vector B("
                                       << B.getID()
                                       << ") must have the same size");
 
   AKANTU_DEBUG_ASSERT(A.getNbComponent() == m * k,
                       "The vector A(" << A.getID()
                                       << ") has the good number of component.");
 
   AKANTU_DEBUG_ASSERT(
       B.getNbComponent() == k * n,
       "The vector B(" << B.getID() << ") do not the good number of component.");
 
   AKANTU_DEBUG_ASSERT(
       C.getNbComponent() == m * n,
       "The vector C(" << C.getID() << ") do not the good number of component.");
 
   UInt nb_element = A.size();
   UInt offset_A = A.getNbComponent();
   UInt offset_B = B.getNbComponent();
   UInt offset_C = C.getNbComponent();
 
   C.resize(nb_element);
 
   Real * A_val = A.storage();
   Real * B_val = B.storage();
   Real * C_val = C.storage();
 
   for (UInt el = 0; el < nb_element; ++el) {
     matrix_matrixt(m, n, k, A_val, B_val, C_val, alpha);
 
     A_val += offset_A;
     B_val += offset_B;
     C_val += offset_C;
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void Math::compute_tangents(const Array<Real> & normals,
                             Array<Real> & tangents) {
   AKANTU_DEBUG_IN();
 
   UInt spatial_dimension = normals.getNbComponent();
   UInt tangent_components = spatial_dimension * (spatial_dimension - 1);
 
   AKANTU_DEBUG_ASSERT(
       tangent_components == tangents.getNbComponent(),
       "Cannot compute the tangents, the storage array for tangents"
           << " does not have the good amount of components.");
 
   UInt nb_normals = normals.size();
   tangents.resize(nb_normals);
 
   Real * normal_it = normals.storage();
   Real * tangent_it = tangents.storage();
 
   /// compute first tangent
   for (UInt q = 0; q < nb_normals; ++q) {
     /// if normal is orthogonal to xy plane, arbitrarly define tangent
     if (Math::are_float_equal(Math::norm2(normal_it), 0))
       tangent_it[0] = 1;
     else
       Math::normal2(normal_it, tangent_it);
 
     normal_it += spatial_dimension;
     tangent_it += tangent_components;
   }
 
   /// compute second tangent (3D case)
   if (spatial_dimension == 3) {
     normal_it = normals.storage();
     tangent_it = tangents.storage();
 
     for (UInt q = 0; q < nb_normals; ++q) {
       Math::normal3(normal_it, tangent_it, tangent_it + spatial_dimension);
       normal_it += spatial_dimension;
       tangent_it += tangent_components;
     }
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 Real Math::reduce(Array<Real> & array) {
   UInt nb_values = array.size();
   if (nb_values == 0)
     return 0.;
 
   UInt nb_values_to_sum = nb_values >> 1;
 
   std::sort(array.begin(), array.end());
 
   // as long as the half is not empty
   while (nb_values_to_sum) {
     UInt remaining = (nb_values - 2 * nb_values_to_sum);
     if (remaining)
       array(nb_values - 2) += array(nb_values - 1);
 
     // sum to consecutive values and store the sum in the first half
     for (UInt i = 0; i < nb_values_to_sum; ++i) {
       array(i) = array(2 * i) + array(2 * i + 1);
     }
 
     nb_values = nb_values_to_sum;
     nb_values_to_sum >>= 1;
   }
 
   return array(0);
 }
 
 } // akantu
diff --git a/src/common/aka_math.hh b/src/common/aka_math.hh
index 3a38dfd1a..6973b22b1 100644
--- a/src/common/aka_math.hh
+++ b/src/common/aka_math.hh
@@ -1,292 +1,291 @@
 /**
  * @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: Fri May 15 2015
+ * @date last modification: Mon Sep 11 2017
  *
  * @brief  mathematical operations
  *
  * @section LICENSE
  *
- * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
- * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
- * Solides)
+ * 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
+ * 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
+ * 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_AKA_MATH_H__
 #define __AKANTU_AKA_MATH_H__
 
 /* -------------------------------------------------------------------------- */
 #include <utility>
 
 #include "aka_common.hh"
 /* -------------------------------------------------------------------------- */
 namespace akantu {
 /* -------------------------------------------------------------------------- */
 
 template <typename T, bool is_scal> class Array;
 
 class Math {
   /* ------------------------------------------------------------------------ */
   /* Methods                                                                  */
   /* ------------------------------------------------------------------------ */
 public:
   /* ------------------------------------------------------------------------ */
   /* Matrix algebra                                                           */
   /* ------------------------------------------------------------------------ */
   /// @f$ y = A*x @f$
   static void matrix_vector(UInt m, UInt n, const Array<Real, true> & A,
                             const Array<Real, true> & x, Array<Real, true> & y,
                             Real alpha = 1.);
 
   /// @f$ y = A*x @f$
   static inline void matrix_vector(UInt m, UInt n, Real * A, Real * x, Real * y,
                                    Real alpha = 1.);
 
   /// @f$ y = A^t*x @f$
   static inline void matrixt_vector(UInt m, UInt n, Real * A, Real * x,
                                     Real * y, Real alpha = 1.);
 
   /// @f$ C = A*B @f$
   static void matrix_matrix(UInt m, UInt n, UInt k, const Array<Real, true> & A,
                             const Array<Real, true> & B, Array<Real, true> & C,
                             Real alpha = 1.);
 
   /// @f$ C = A*B^t @f$
   static void matrix_matrixt(UInt m, UInt n, UInt k,
                              const Array<Real, true> & A,
                              const Array<Real, true> & B, Array<Real, true> & C,
                              Real alpha = 1.);
 
   /// @f$ C = A*B @f$
   static 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$
   static 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$
   static 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$
   static 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>
   static inline void matMul(UInt m, UInt n, UInt k, Real alpha, Real * A,
                             Real * B, Real beta, Real * C);
 
   template <bool tr_A>
   static inline void matVectMul(UInt m, UInt n, Real alpha, Real * A, Real * x,
                                 Real beta, Real * y);
 
   static inline void aXplusY(UInt n, Real alpha, Real * x, Real * y);
 
   static inline void matrix33_eigenvalues(Real * A, Real * Adiag);
 
   static inline void matrix22_eigenvalues(Real * A, Real * Adiag);
   template <UInt dim> static 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>
   static void matrixEig(UInt n, T * A, T * d, T * V = nullptr);
 
   /// determinent of a 2x2 matrix
   static inline Real det2(const Real * mat);
   /// determinent of a 3x3 matrix
   static inline Real det3(const Real * mat);
   /// determinent of a nxn matrix
   template <UInt n> static inline Real det(const Real * mat);
   /// determinent of a nxn matrix
   template <typename T> static inline T det(UInt n, const T * mat);
 
   /// inverse a nxn matrix
   template <UInt n> static inline void inv(const Real * mat, Real * inv);
   /// inverse a nxn matrix
   template <typename T> static inline void inv(UInt n, const T * mat, T * inv);
   /// inverse a 3x3 matrix
   static inline void inv3(const Real * mat, Real * inv);
   /// inverse a 2x2 matrix
   static inline void inv2(const Real * mat, Real * inv);
 
   /// solve A x = b using a LU factorization
   template <typename T>
   static inline void solve(UInt n, const T * A, T * x, const T * b);
 
   /// return the double dot product between 2 tensors in 2d
   static inline Real matrixDoubleDot22(Real * A, Real * B);
 
   /// return the double dot product between 2 tensors in 3d
   static inline Real matrixDoubleDot33(Real * A, Real * B);
 
   /// extension of the double dot product to two 2nd order tensor in dimension n
   static inline Real matrixDoubleDot(UInt n, Real * A, Real * B);
 
   /* ------------------------------------------------------------------------ */
   /* Array algebra                                                            */
   /* ------------------------------------------------------------------------ */
   /// vector cross product
   static inline void vectorProduct3(const Real * v1, const Real * v2,
                                     Real * res);
 
   /// normalize a vector
   static inline void normalize2(Real * v);
 
   /// normalize a vector
   static inline void normalize3(Real * v);
 
   /// return norm of a 2-vector
   static inline Real norm2(const Real * v);
 
   /// return norm of a 3-vector
   static inline Real norm3(const Real * v);
 
   /// return norm of a vector
   static inline Real norm(UInt n, const Real * v);
 
   /// return the dot product between 2 vectors in 2d
   static inline Real vectorDot2(const Real * v1, const Real * v2);
 
   /// return the dot product between 2 vectors in 3d
   static inline Real vectorDot3(const Real * v1, const Real * v2);
 
   /// return the dot product between 2 vectors
   static inline Real vectorDot(Real * v1, Real * v2, UInt n);
 
   /* ------------------------------------------------------------------------ */
   /* Geometry                                                                 */
   /* ------------------------------------------------------------------------ */
   /// compute normal a normal to a vector
   static inline void normal2(const Real * v1, Real * res);
 
   /// compute normal a normal to a vector
   static inline void normal3(const Real * v1, const Real * v2, Real * res);
 
   /// compute the tangents to an array of normal vectors
   static void compute_tangents(const Array<Real> & normals,
                                Array<Real> & tangents);
 
   /// distance in 2D between x and y
   static inline Real distance_2d(const Real * x, const Real * y);
 
   /// distance in 3D between x and y
   static inline Real distance_3d(const Real * x, const Real * y);
 
   /// radius of the in-circle of a triangle
   static inline Real triangle_inradius(const Real * coord1, const Real * coord2,
                                        const Real * coord3);
 
   /// radius of the in-circle of a tetrahedron
   static inline Real tetrahedron_inradius(const Real * coord1,
                                           const Real * coord2,
                                           const Real * coord3,
                                           const Real * coord4);
 
   /// volume of a tetrahedron
   static inline Real tetrahedron_volume(const Real * coord1,
                                         const Real * coord2,
                                         const Real * coord3,
                                         const Real * coord4);
 
   /// compute the barycenter of n points
   static inline void barycenter(const Real * coord, UInt nb_points,
                                 UInt spatial_dimension, Real * barycenter);
 
   /// vector between x and y
   static inline void vector_2d(const Real * x, const Real * y, Real * vec);
 
   /// vector pointing from x to y in 3 spatial dimension
   static inline void vector_3d(const Real * x, const Real * y, Real * vec);
 
   /// test if two scalar are equal within a given tolerance
   static inline bool are_float_equal(Real x, Real y);
 
   /// test if two vectors are equal within a given tolerance
   static 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
   static inline bool isnan(Real x);
 
   /// test if the line x and y intersects each other
   static 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]
   static inline bool is_in_range(Real a, Real x_min, Real x_max);
 
   static inline Real getTolerance() { return tolerance; };
   static inline void setTolerance(Real tol) { tolerance = tol; };
 
   template <UInt p, typename T> static inline T pow(T x);
 
   /// reduce all the values of an array, the summation is done in place and the
   /// array is modified
   static 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(std::string name) : name(std::move(name)) {}
     virtual ~NewtonRaphsonFunctor() = default;
     virtual Real f(Real x) const = 0;
     virtual Real f_prime(Real x) const = 0;
     std::string name;
   };
 
 private:
   /// tolerance for functions that need one
   static Real tolerance;
 };
 
 /* -------------------------------------------------------------------------- */
 /* inline functions                                                           */
 /* -------------------------------------------------------------------------- */
 
 #include "aka_math_tmpl.hh"
 
 } // akantu
 
 #endif /* __AKANTU_AKA_MATH_H__ */
diff --git a/src/common/aka_math_tmpl.hh b/src/common/aka_math_tmpl.hh
index 2e0bdb5a7..599e21b3b 100644
--- a/src/common/aka_math_tmpl.hh
+++ b/src/common/aka_math_tmpl.hh
@@ -1,784 +1,783 @@
 /**
  * @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: Wed Oct 21 2015
+ * @date last modification: Tue Feb 20 2018
  *
  * @brief  Implementation of the inline functions of the math toolkit
  *
  * @section LICENSE
  *
- * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
- * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
- * Solides)
+ * 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
+ * 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
+ * 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/>.
  *
  */
 
 } // akantu
 
 #include <cmath>
 #include <cstring>
 #include <typeinfo>
 
 #include "aka_blas_lapack.hh"
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 inline void Math::matrix_vector(UInt im, UInt in, Real * A, Real * x, 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
   memset(y, 0, im * sizeof(Real));
   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 Math::matrixt_vector(UInt im, UInt in, Real * A, Real * x, 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
   memset(y, 0, in * sizeof(Real));
   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 Math::matrix_matrix(UInt im, UInt in, UInt ik, Real * A, Real * B,
                                 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
   memset(C, 0, im * in * sizeof(Real));
   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 Math::matrixt_matrix(UInt im, UInt in, UInt ik, Real * A, Real * B,
                                  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
   memset(C, 0, im * in * sizeof(Real));
   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 Math::matrix_matrixt(UInt im, UInt in, UInt ik, Real * A, Real * B,
                                  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
   memset(C, 0, im * in * sizeof(Real));
   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 Math::matrixt_matrixt(UInt im, UInt in, UInt ik, Real * A, Real * B,
                                   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
   memset(C, 0, im * in * sizeof(Real));
   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 Math::aXplusY(UInt n, Real alpha, Real * x, 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 Math::vectorDot(Real * v1, Real * v2, 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 Math::matMul(UInt m, UInt n, UInt k, Real alpha, Real * A, Real * B,
                          __attribute__((unused)) 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 Math::matVectMul(UInt m, UInt n, Real alpha, Real * A, Real * x,
                              __attribute__((unused)) 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 Math::matrixEig(UInt n, T * A, 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, jobvl;
   if (V != nullptr)
     jobvr = 'V'; // compute left  eigenvectors
   else
     jobvr = 'N'; // compute left  eigenvectors
 
   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 Math::matrix22_eigenvalues(Real * A, Real * Adiag) {
   /// d = determinant of Matrix A
   Real d = det2(A);
   /// b = trace of Matrix A
   Real b = A[0] + A[3];
 
   Real c = sqrt(b * b - 4 * d);
   Adiag[0] = .5 * (b + c);
   Adiag[1] = .5 * (b - c);
 }
 
 /* -------------------------------------------------------------------------- */
 inline void Math::matrix33_eigenvalues(Real * A, Real * Adiag) {
   matrixEig(3, A, Adiag);
 }
 
 /* -------------------------------------------------------------------------- */
 template <UInt dim> inline void Math::eigenvalues(Real * A, 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 Math::det2(const Real * mat) {
   return mat[0] * mat[3] - mat[1] * mat[2];
 }
 
 /* -------------------------------------------------------------------------- */
 inline Real Math::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 Math::det(const Real * mat) {
   if (n == 1)
     return *mat;
   else if (n == 2)
     return det2(mat);
   else if (n == 3)
     return det3(mat);
   else
     return det(n, mat);
 }
 
 /* -------------------------------------------------------------------------- */
 template <typename T> inline T Math::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 Math::normal2(const Real * vec, Real * normal) {
   normal[0] = vec[1];
   normal[1] = -vec[0];
   Math::normalize2(normal);
 }
 
 /* -------------------------------------------------------------------------- */
 inline void Math::normal3(const Real * vec1, const Real * vec2, Real * normal) {
   Math::vectorProduct3(vec1, vec2, normal);
   Math::normalize3(normal);
 }
 
 /* -------------------------------------------------------------------------- */
 inline void Math::normalize2(Real * vec) {
   Real norm = Math::norm2(vec);
   vec[0] /= norm;
   vec[1] /= norm;
 }
 
 /* -------------------------------------------------------------------------- */
 inline void Math::normalize3(Real * vec) {
   Real norm = Math::norm3(vec);
   vec[0] /= norm;
   vec[1] /= norm;
   vec[2] /= norm;
 }
 
 /* -------------------------------------------------------------------------- */
 inline Real Math::norm2(const Real * vec) {
   return sqrt(vec[0] * vec[0] + vec[1] * vec[1]);
 }
 
 /* -------------------------------------------------------------------------- */
 inline Real Math::norm3(const Real * vec) {
   return sqrt(vec[0] * vec[0] + vec[1] * vec[1] + vec[2] * vec[2]);
 }
 
 /* -------------------------------------------------------------------------- */
 inline Real Math::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 Math::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 Math::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 Math::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 Math::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 Math::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 Math::matrixDoubleDot22(Real * A, Real * B) {
   Real d;
   d = A[0] * B[0] + A[1] * B[1] + A[2] * B[2] + A[3] * B[3];
   return d;
 }
 
 /* -------------------------------------------------------------------------- */
 inline Real Math::matrixDoubleDot33(Real * A, Real * B) {
   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 Math::matrixDoubleDot(UInt n, Real * A, Real * B) {
   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 Math::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 Math::vectorDot2(const Real * v1, const Real * v2) {
   return (v1[0] * v2[0] + v1[1] * v2[1]);
 }
 
 /* -------------------------------------------------------------------------- */
 inline Real Math::vectorDot3(const Real * v1, const Real * v2) {
   return (v1[0] * v2[0] + v1[1] * v2[1] + v1[2] * v2[2]);
 }
 
 /* -------------------------------------------------------------------------- */
 inline Real Math::distance_2d(const Real * x, const Real * y) {
   return sqrt((y[0] - x[0]) * (y[0] - x[0]) + (y[1] - x[1]) * (y[1] - x[1]));
 }
 
 /* -------------------------------------------------------------------------- */
 inline Real Math::triangle_inradius(const Real * coord1, const Real * coord2,
                                     const 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 = distance_2d(coord1, coord2);
   b = distance_2d(coord2, coord3);
   c = distance_2d(coord1, coord3);
 
   Real s;
   s = (a + b + c) * 0.5;
 
   return sqrt((s - a) * (s - b) * (s - c) / s);
 }
 
 /* -------------------------------------------------------------------------- */
 inline Real Math::distance_3d(const Real * x, const Real * y) {
   return 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 Math::tetrahedron_volume(const Real * coord1, const Real * coord2,
                                      const Real * coord3, const Real * coord4) {
   Real xx[9], vol;
 
   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];
   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 Math::tetrahedron_inradius(const Real * coord1, const Real * coord2,
                                        const Real * coord3,
                                        const Real * coord4) {
 
   Real l12, l13, l14, l23, l24, l34;
   l12 = distance_3d(coord1, coord2);
   l13 = distance_3d(coord1, coord3);
   l14 = distance_3d(coord1, coord4);
   l23 = distance_3d(coord2, coord3);
   l24 = distance_3d(coord2, coord4);
   l34 = distance_3d(coord3, coord4);
 
   Real s1, s2, s3, s4;
 
   s1 = (l12 + l23 + l13) * 0.5;
   s1 = sqrt(s1 * (s1 - l12) * (s1 - l23) * (s1 - l13));
 
   s2 = (l12 + l24 + l14) * 0.5;
   s2 = sqrt(s2 * (s2 - l12) * (s2 - l24) * (s2 - l14));
 
   s3 = (l23 + l34 + l24) * 0.5;
   s3 = sqrt(s3 * (s3 - l23) * (s3 - l34) * (s3 - l24));
 
   s4 = (l13 + l34 + l14) * 0.5;
   s4 = sqrt(s4 * (s4 - l13) * (s4 - l34) * (s4 - l14));
 
   Real volume = Math::tetrahedron_volume(coord1, coord2, coord3, coord4);
 
   return 3 * volume / (s1 + s2 + s3 + s4);
 }
 
 /* -------------------------------------------------------------------------- */
 inline void Math::barycenter(const Real * coord, UInt nb_points,
                              UInt spatial_dimension, Real * barycenter) {
   memset(barycenter, 0, spatial_dimension * sizeof(Real));
   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 Math::vector_2d(const Real * x, const Real * y, Real * res) {
   res[0] = y[0] - x[0];
   res[1] = y[1] - x[1];
 }
 
 /* -------------------------------------------------------------------------- */
 inline void Math::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 Math::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 Math::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 Math::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 Math::intersects(Real x_min, Real x_max, Real y_min, Real y_max) {
   return !((x_max <= y_min) || (x_min >= y_max));
 }
 
 /* -------------------------------------------------------------------------- */
 inline bool Math::is_in_range(Real a, Real x_min, Real x_max) {
   return ((a >= x_min) && (a <= x_max));
 }
 
 /* -------------------------------------------------------------------------- */
 template <UInt p, typename T> inline T Math::pow(T x) {
   return (pow<p - 1, T>(x) * x);
 }
 template <> inline UInt Math::pow<0, UInt>(__attribute__((unused)) UInt x) {
   return (1);
 }
 template <> inline Real Math::pow<0, Real>(__attribute__((unused)) Real x) {
   return (1.);
 }
 
 /* -------------------------------------------------------------------------- */
 
 template <class Functor>
 Real Math::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;
 }
diff --git a/src/common/aka_memory.cc b/src/common/aka_memory.cc
index 006134ced..ed6c70903 100644
--- a/src/common/aka_memory.cc
+++ b/src/common/aka_memory.cc
@@ -1,64 +1,63 @@
 /**
  * @file   aka_memory.cc
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Fri Jun 18 2010
- * @date last modification: Sun Oct 19 2014
+ * @date last modification: Wed Nov 08 2017
  *
  * @brief  static memory wrapper
  *
  * @section LICENSE
  *
- * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
- * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
- * Solides)
+ * 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
+ * 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
+ * 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 <utility>
 
 #include "aka_memory.hh"
 #include "aka_static_memory.hh"
 
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 Memory::Memory(ID id, MemoryID memory_id)
     : static_memory(StaticMemory::getStaticMemory()), id(std::move(id)),
       memory_id(memory_id) {}
 
 /* -------------------------------------------------------------------------- */
 Memory::~Memory() {
   if (StaticMemory::isInstantiated()) {
     std::list<ID>::iterator it;
     for (it = handeld_vectors_id.begin(); it != handeld_vectors_id.end();
          ++it) {
       AKANTU_DEBUG(dblAccessory, "Deleting the vector " << *it);
       static_memory.sfree(memory_id, *it);
     }
     static_memory.destroy();
   }
 
   handeld_vectors_id.clear();
 }
 
 /* -------------------------------------------------------------------------- */
 
 } // akantu
diff --git a/src/common/aka_memory.hh b/src/common/aka_memory.hh
index a5db23abb..d2e030a1e 100644
--- a/src/common/aka_memory.hh
+++ b/src/common/aka_memory.hh
@@ -1,115 +1,114 @@
 /**
  * @file   aka_memory.hh
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Fri Jun 18 2010
- * @date last modification: Sun Oct 19 2014
+ * @date last modification: Wed Nov 08 2017
  *
  * @brief  wrapper for the static_memory, all object which wants
  * to access the static_memory as to inherit from the class memory
  *
  * @section LICENSE
  *
- * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
- * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
- * Solides)
+ * 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
+ * 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
+ * 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_MEMORY_HH__
 #define __AKANTU_MEMORY_HH__
 
 /* -------------------------------------------------------------------------- */
 #include "aka_array.hh"
 #include "aka_common.hh"
 #include "aka_static_memory.hh"
 
 /* -------------------------------------------------------------------------- */
 #include <list>
 
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 
 class Memory {
   /* ------------------------------------------------------------------------ */
   /* Constructors/Destructors                                                 */
   /* ------------------------------------------------------------------------ */
 protected:
   Memory(ID id, MemoryID memory_id = 0);
 
   virtual ~Memory();
 
   /* ------------------------------------------------------------------------ */
   /* Methods                                                                  */
   /* ------------------------------------------------------------------------ */
 protected:
   /// malloc
   template <class T>
   inline Array<T> & alloc(const ID & name, UInt size, UInt nb_component);
 
   /// malloc
   template <class T>
   inline Array<T> & alloc(const ID & name, UInt size, UInt nb_component,
                           const T & init_value);
 
   /* ------------------------------------------------------------------------ */
   /// free an array
   inline void dealloc(const ID & name);
 
   /* ------------------------------------------------------------------------ */
   /* Accessors                                                                */
   /* ------------------------------------------------------------------------ */
 protected:
   template <typename T> inline Array<T> & getArray(const ID & name);
 
   template <typename T> inline const Array<T> & getArray(const ID & name) const;
 
 public:
   AKANTU_GET_MACRO(MemoryID, memory_id, const MemoryID &);
 
   AKANTU_GET_MACRO(ID, id, const ID &);
 
   /* ------------------------------------------------------------------------ */
   /* Class Members                                                            */
   /* ------------------------------------------------------------------------ */
 private:
   /// the static memory instance
   StaticMemory & static_memory;
 
   /// list of allocated vectors id
   std::list<ID> handeld_vectors_id;
 
 protected:
   ID id;
 
   /// the id registred in the static memory
   MemoryID memory_id;
 };
 
 /* -------------------------------------------------------------------------- */
 /* Inline functions                                                           */
 /* -------------------------------------------------------------------------- */
 
 #if defined(AKANTU_INCLUDE_INLINE_IMPL)
 #include "aka_memory_inline_impl.cc"
 #endif
 
 } // akantu
 
 #endif /* __AKANTU_MEMORY_HH__ */
diff --git a/src/common/aka_memory_inline_impl.cc b/src/common/aka_memory_inline_impl.cc
index eec8da71a..70cb0e538 100644
--- a/src/common/aka_memory_inline_impl.cc
+++ b/src/common/aka_memory_inline_impl.cc
@@ -1,66 +1,65 @@
 /**
  * @file   aka_memory_inline_impl.cc
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Thu Jul 15 2010
- * @date last modification: Sun Oct 19 2014
+ * @date last modification: Wed Nov 08 2017
  *
  * @brief  Implementation of the inline functions of the class Memory
  *
  * @section LICENSE
  *
- * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
- * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
- * Solides)
+ * 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
+ * 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
+ * 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/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 template <class T>
 inline Array<T> & Memory::alloc(const ID & name, UInt size, UInt nb_component) {
   handeld_vectors_id.push_back(name);
   return static_memory.smalloc<T>(memory_id, name, size, nb_component);
 }
 
 /* -------------------------------------------------------------------------- */
 template <class T>
 inline Array<T> & Memory::alloc(const ID & name, UInt size, UInt nb_component,
                                 const T & init_value) {
   handeld_vectors_id.push_back(name);
   return static_memory.smalloc<T>(memory_id, name, size, nb_component,
                                   init_value);
 }
 
 /* -------------------------------------------------------------------------- */
 inline void Memory::dealloc(const ID & name) {
   AKANTU_DEBUG(dblAccessory, "Deleting the vector " << name);
   static_memory.sfree(memory_id, name);
   handeld_vectors_id.remove(name);
 }
 
 /* -------------------------------------------------------------------------- */
 template <class T> inline Array<T> & Memory::getArray(const ID & name) {
   return static_cast<Array<T> &>(
       const_cast<ArrayBase &>(static_memory.getArray(memory_id, name)));
 }
 
 /* -------------------------------------------------------------------------- */
 template <class T>
 inline const Array<T> & Memory::getArray(const ID & name) const {
   return static_cast<Array<T> &>(
       const_cast<ArrayBase &>(static_memory.getArray(memory_id, name)));
 }
diff --git a/src/common/aka_named_argument.hh b/src/common/aka_named_argument.hh
index 2f8f8f3d7..53a366d15 100644
--- a/src/common/aka_named_argument.hh
+++ b/src/common/aka_named_argument.hh
@@ -1,164 +1,194 @@
+/**
+ * @file   aka_named_argument.hh
+ *
+ * @author Nicolas Richart <nicolas.richart@epfl.ch>
+ *
+ * @date creation: Fri Jun 16 2017
+ * @date last modification: Wed Dec 06 2017
+ *
+ * @brief  tool to use named arguments in functions
+ *
+ * @section LICENSE
+ *
+ * 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/>.
+ *
+ */
+
 /**
  * @file   aka_named_argument.hh
  *
  * @author Marco Arena
  *
  * @date creation  Fri Jun 16 2017
  *
  * @brief A Documented file.
  *
  * @section LICENSE
  *
  * Public Domain ? https://gist.github.com/ilpropheta/7576dce4c3249df89f85
  *
  */
 /* -------------------------------------------------------------------------- */
 #include "aka_compatibilty_with_cpp_standard.hh"
 /* -------------------------------------------------------------------------- */
 #include <tuple>
 #include <type_traits>
 /* -------------------------------------------------------------------------- */
 
 #ifndef __AKANTU_AKA_NAMED_ARGUMENT_HH__
 #define __AKANTU_AKA_NAMED_ARGUMENT_HH__
 
 namespace akantu {
 
 namespace named_argument {
   struct param_t_trait {};
 
   /* -- Pack utils (proxy version) ------------------------------------------ */
   /// Proxy containing [tag, value]
   template <typename tag, typename type> struct param_t : param_t_trait {
     using _tag = tag;
     using _type = type;
 
     template <typename T>
     explicit param_t(T && value) : _value(std::forward<T>(value)) {}
 
     type _value;
   };
 
   /*
    * Tagged proxy that allows syntax _name = value
    * operator=(T&&) returns a param_t instance
    **/
   template <typename tag> struct param_proxy {
     using _tag = tag;
 
     template <typename T> decltype(auto) operator=(T && value) {
       return param_t<tag, decltype(value)>{std::forward<T>(value)};
     }
   };
 
   /*  Same as type_at but it's supposed to be used by passing
       a pack of param_t (_tag is looked for instead of a
       plain type). This and type_at should be refactored.
   */
   template <typename T, typename head, typename... tail> struct type_at_p {
     enum {
       _tmp = (std::is_same<T, typename std::decay_t<head>::_tag>::value)
                  ? 0
                  : type_at_p<T, tail...>::_pos
     };
     enum { _pos = _tmp == -1 ? -1 : 1 + _tmp };
   };
 
   template <typename T, typename head> struct type_at_p<T, head> {
     enum {
       _pos =
           (std::is_same<T, typename std::decay<head>::type::_tag>::value ? 1
                                                                          : -1)
     };
   };
 
   template <typename... Ts> struct type_at {
     enum { _pos = -1 };
   };
 
   template <typename T, typename head, typename... tail>
   struct type_at<T, head, tail...> {
     enum { _tmp = type_at_p<T, head, tail...>::_pos };
     enum { _pos = _tmp == 1 ? 0 : (_tmp == -1 ? -1 : _tmp - 1) };
   };
 
   /*  Same as get_at but it's supposed to be used by passing
       a pack of param_t (_type is retrieved instead)
       This and get_at should be refactored.
   */
   template <int pos, int curr> struct get_at {
     static_assert(pos >= 0, "Required parameter");
 
     template <typename head, typename... tail>
     static decltype(auto) get(head &&, tail &&... t) {
       return get_at<pos, curr + 1>::get(std::forward<tail>(t)...);
     }
   };
 
   template <int pos> struct get_at<pos, pos> {
     static_assert(pos >= 0, "Required parameter");
 
     template <typename head, typename... tail>
     static decltype(auto) get(head && h, tail &&...) {
       return std::forward<decltype(h._value)>(h._value);
     }
   };
 
   // Optional version
   template <int pos, int curr> struct get_optional {
     template <typename T, typename... pack>
     static decltype(auto) get(T &&, pack &&... _pack) {
       return get_at<pos, curr>::get(std::forward<pack>(_pack)...);
     }
   };
 
   template <int curr> struct get_optional<-1, curr> {
     template <typename T, typename... pack>
     static decltype(auto) get(T && _default, pack &&...) {
       return std::forward<T>(_default);
     }
   };
 
 } // namespace named_argument
 
 // CONVENIENCE MACROS FOR CLASS DESIGNERS ==========
 #define TAG_OF_ARGUMENT(_name) p_##_name
 #define TAG_OF_ARGUMENT_WNS(_name) TAG_OF_ARGUMENT(_name)
 
 #define REQUIRED_NAMED_ARG(_name)                                              \
   named_argument::get_at<                                                      \
       named_argument::type_at<TAG_OF_ARGUMENT_WNS(_name), pack...>::_pos,      \
       0>::get(std::forward<pack>(_pack)...)
 
 #define REQUIRED_NAMED_ARG(_name)                                              \
   named_argument::get_at<                                                      \
       named_argument::type_at<TAG_OF_ARGUMENT_WNS(_name), pack...>::_pos,      \
       0>::get(std::forward<pack>(_pack)...)
 #define OPTIONAL_NAMED_ARG(_name, _defaultVal)                                 \
   named_argument::get_optional<                                                \
       named_argument::type_at<TAG_OF_ARGUMENT_WNS(_name), pack...>::_pos,      \
       0>::get(_defaultVal, std::forward<pack>(_pack)...)
 
 #define DECLARE_NAMED_ARGUMENT(name)                                           \
   struct TAG_OF_ARGUMENT(name) {};                                             \
   named_argument::param_proxy<TAG_OF_ARGUMENT_WNS(name)> _##name               \
       __attribute__((unused))
 
 namespace {
   struct use_named_args_t {};
   use_named_args_t use_named_args __attribute__((unused));
 } // namespace
 
 template <typename T> struct is_named_argument : public std::false_type {};
 
 template <typename... type>
 struct is_named_argument<named_argument::param_t<type...>>
     : public std::true_type {};
 
 template <typename... pack>
 using are_named_argument =
     aka::conjunction<is_named_argument<std::decay_t<pack>>...>;
 
 } // namespace akantu
 
 #endif /* __AKANTU_AKA_NAMED_ARGUMENT_HH__ */
diff --git a/src/common/aka_random_generator.hh b/src/common/aka_random_generator.hh
index 7cda1a505..5bbb5a501 100644
--- a/src/common/aka_random_generator.hh
+++ b/src/common/aka_random_generator.hh
@@ -1,268 +1,268 @@
 /**
  * @file   aka_random_generator.hh
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Thu Feb 21 2013
- * @date last modification: Wed Nov 11 2015
+ * @date last modification: Wed Nov 08 2017
  *
  * @brief  generic random generator
  *
  * @section LICENSE
  *
- * Copyright  (©)  2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de Lausanne)
+ * 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
+ * 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
+ * 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_array.hh"
 /* -------------------------------------------------------------------------- */
 #include <random>
 /* -------------------------------------------------------------------------- */
 
 #ifndef __AKANTU_AKA_RANDOM_GENERATOR_HH__
 #define __AKANTU_AKA_RANDOM_GENERATOR_HH__
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 /* List of available distributions                                            */
 /* -------------------------------------------------------------------------- */
 // clang-format off
 #define AKANTU_RANDOM_DISTRIBUTION_TYPES                \
   ((uniform      , std::uniform_real_distribution ))    \
   ((exponential  , std::exponential_distribution  ))    \
   ((gamma        , std::gamma_distribution        ))    \
   ((weibull      , std::weibull_distribution      ))    \
   ((extreme_value, std::extreme_value_distribution))    \
   ((normal       , std::normal_distribution       ))    \
   ((lognormal    , std::lognormal_distribution    ))    \
   ((chi_squared  , std::chi_squared_distribution  ))    \
   ((cauchy       , std::cauchy_distribution       ))    \
   ((fisher_f     , std::fisher_f_distribution     ))    \
   ((student_t    , std::student_t_distribution    ))
 // clang-format on
 
 #define AKANTU_RANDOM_DISTRIBUTION_TYPES_PREFIX(elem) BOOST_PP_CAT(_rdt_, elem)
 #define AKANTU_RANDOM_DISTRIBUTION_PREFIX(s, data, elem)                       \
   AKANTU_RANDOM_DISTRIBUTION_TYPES_PREFIX(BOOST_PP_TUPLE_ELEM(2, 0, elem))
 
 enum RandomDistributionType {
   BOOST_PP_SEQ_ENUM(BOOST_PP_SEQ_TRANSFORM(AKANTU_RANDOM_DISTRIBUTION_PREFIX, _,
                                            AKANTU_RANDOM_DISTRIBUTION_TYPES)),
   _rdt_not_defined
 };
 
 /* -------------------------------------------------------------------------- */
 /* Generator                                                                  */
 /* -------------------------------------------------------------------------- */
 template <typename T> class RandomGenerator {
   /* ------------------------------------------------------------------------ */
 public:
   inline T operator()() { return generator(); }
 
   /// function to print the contain of the class
   virtual void printself(std::ostream & stream, int) const {
     stream << "RandGenerator [seed=" << _seed << "]";
   }
 
   /* ------------------------------------------------------------------------ */
 public:
   static void seed(long int s) {
     _seed = s;
     generator.seed(_seed);
   }
   static long int seed() { return _seed; }
 
   static constexpr T min() { return generator.min(); }
   static constexpr T max() { return generator.max(); }
 
   /* ------------------------------------------------------------------------ */
 private:
   static long int _seed;
   static std::default_random_engine generator;
 };
 
 /* -------------------------------------------------------------------------- */
 /* -------------------------------------------------------------------------- */
 /* -------------------------------------------------------------------------- */
 #undef AKANTU_RANDOM_DISTRIBUTION_PREFIX
 
 #define AKANTU_RANDOM_DISTRIBUTION_TYPE_PRINT_CASE(r, data, elem)              \
   case AKANTU_RANDOM_DISTRIBUTION_TYPES_PREFIX(                                \
       BOOST_PP_TUPLE_ELEM(2, 0, elem)): {                                      \
     stream << BOOST_PP_STRINGIZE(AKANTU_RANDOM_DISTRIBUTION_TYPES_PREFIX(      \
         BOOST_PP_TUPLE_ELEM(2, 0, elem)));                                     \
     break;                                                                     \
   }
 
 inline std::ostream & operator<<(std::ostream & stream,
                                  RandomDistributionType type) {
   switch (type) {
     BOOST_PP_SEQ_FOR_EACH(AKANTU_RANDOM_DISTRIBUTION_TYPE_PRINT_CASE, _,
                           AKANTU_RANDOM_DISTRIBUTION_TYPES)
   default:
     stream << UInt(type) << " not a RandomDistributionType";
     break;
   }
   return stream;
 }
 #undef AKANTU_RANDOM_DISTRIBUTION_TYPE_PRINT_CASE
 
 /* -------------------------------------------------------------------------- */
 /* Some Helper                                                                */
 /* -------------------------------------------------------------------------- */
 template <typename T, class Distribution> class RandomDistributionTypeHelper {
   enum { value = _rdt_not_defined };
 };
 
 /* -------------------------------------------------------------------------- */
 #define AKANTU_RANDOM_DISTRIBUTION_TYPE_GET_TYPE(r, data, elem)                \
   template <typename T>                                                        \
       struct RandomDistributionTypeHelper<                                     \
           T, BOOST_PP_TUPLE_ELEM(2, 1, elem) < T>> {                           \
     enum {                                                                     \
       value = AKANTU_RANDOM_DISTRIBUTION_TYPES_PREFIX(                         \
           BOOST_PP_TUPLE_ELEM(2, 0, elem))                                     \
     };                                                                         \
                                                                                \
     static void printself(std::ostream & stream) {                             \
       stream << BOOST_PP_STRINGIZE(BOOST_PP_TUPLE_ELEM(2, 0, elem));           \
     }                                                                          \
   };
 
 BOOST_PP_SEQ_FOR_EACH(AKANTU_RANDOM_DISTRIBUTION_TYPE_GET_TYPE, _,
                       AKANTU_RANDOM_DISTRIBUTION_TYPES)
 
 #undef AKANTU_RANDOM_DISTRIBUTION_TYPE_GET_TYPE
 
 /* -------------------------------------------------------------------------- */
 template <class T> class RandomDistribution {
 public:
   virtual ~RandomDistribution() = default;
   virtual T operator()(RandomGenerator<UInt> & gen) = 0;
   virtual std::unique_ptr<RandomDistribution<T>> make_unique() const = 0;
   virtual void printself(std::ostream & stream, int = 0) const = 0;
 };
 
 template <class T, class Distribution>
 class RandomDistributionProxy : public RandomDistribution<T> {
 public:
   explicit RandomDistributionProxy(Distribution dist)
       : distribution(std::move(dist)) {}
 
   T operator()(RandomGenerator<UInt> & gen) override {
     return distribution(gen);
   }
 
   std::unique_ptr<RandomDistribution<T>> make_unique() const override {
     return std::make_unique<RandomDistributionProxy<T, Distribution>>(
         distribution);
   }
 
   void printself(std::ostream & stream, int = 0) const override {
     RandomDistributionTypeHelper<T, Distribution>::printself(stream);
     stream << " [ " << distribution << " ]";
   }
 
 private:
   Distribution distribution;
 };
 
 /* -------------------------------------------------------------------------- */
 /* RandomParameter                                                            */
 /* -------------------------------------------------------------------------- */
 template <typename T> class RandomParameter {
 public:
   template <class Distribution>
   explicit RandomParameter(T base_value, Distribution dist)
       : base_value(base_value),
         type(RandomDistributionType(
             RandomDistributionTypeHelper<T, Distribution>::value)),
         distribution_proxy(
             std::make_unique<RandomDistributionProxy<T, Distribution>>(
                 std::move(dist))) {}
 
   explicit RandomParameter(T base_value)
       : base_value(base_value),
         type(RandomDistributionType(
             RandomDistributionTypeHelper<
                 T, std::uniform_real_distribution<T>>::value)),
         distribution_proxy(
             std::make_unique<
                 RandomDistributionProxy<T, std::uniform_real_distribution<T>>>(
                 std::uniform_real_distribution<T>(0., 0.))) {}
 
   RandomParameter(const RandomParameter & other)
       : base_value(other.base_value), type(other.type),
         distribution_proxy(other.distribution_proxy->make_unique()) {}
 
   RandomParameter & operator=(const RandomParameter & other) {
     distribution_proxy = other.distribution_proxy->make_unique();
     base_value = other.base_value;
     type = other.type;
     return *this;
   }
 
   virtual ~RandomParameter() = default;
 
   inline void setBaseValue(const T & value) { this->base_value = value; }
   inline T getBaseValue() const { return this->base_value; }
 
   template <template <typename> class Generator, class iterator>
   void setValues(iterator it, iterator end) {
     RandomGenerator<UInt> gen;
     for (; it != end; ++it)
       *it = this->base_value + (*distribution_proxy)(gen);
   }
 
   virtual void printself(std::ostream & stream,
                          __attribute__((unused)) int indent = 0) const {
     stream << base_value;
     stream << " + " << *distribution_proxy;
   }
 
 private:
   /// Value with no random variations
   T base_value;
 
   /// Random distribution type
   RandomDistributionType type;
 
   /// Proxy to store a std random distribution
   std::unique_ptr<RandomDistribution<T>> distribution_proxy;
 };
 
 /* -------------------------------------------------------------------------- */
 template <typename T>
 inline std::ostream & operator<<(std::ostream & stream,
                                  RandomDistribution<T> & _this) {
   _this.printself(stream);
   return stream;
 }
 
 /* -------------------------------------------------------------------------- */
 template <typename T>
 inline std::ostream & operator<<(std::ostream & stream,
                                  RandomParameter<T> & _this) {
   _this.printself(stream);
   return stream;
 }
 
 } // akantu
 
 #endif /* __AKANTU_AKA_RANDOM_GENERATOR_HH__ */
diff --git a/src/common/aka_safe_enum.hh b/src/common/aka_safe_enum.hh
index b27885dd1..2fd2a57bb 100644
--- a/src/common/aka_safe_enum.hh
+++ b/src/common/aka_safe_enum.hh
@@ -1,86 +1,86 @@
 /**
  * @file   aka_safe_enum.hh
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Thu Feb 21 2013
- * @date last modification: Sun Oct 19 2014
+ * @date last modification: Tue Nov 07 2017
  *
  * @brief  Safe enums type (see More C++ Idioms/Type Safe Enum on Wikibooks
  * http://en.wikibooks.org/wiki/More_C%2B%2B_Idioms/Type_Safe_Enum)
  *
  * @section LICENSE
  *
- * Copyright  (©)  2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de Lausanne)
+ * 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
+ * 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
+ * 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_AKA_SAFE_ENUM_HH__
 #define __AKANTU_AKA_SAFE_ENUM_HH__
 
 namespace akantu {
 
 /// Safe enumerated type
 template <typename def, typename inner = typename def::type>
 class safe_enum : public def {
   using type = typename def::type;
 
 public:
   explicit safe_enum(type v = def::_end_) : val(v) {}
   safe_enum(safe_enum && other) = default;
   safe_enum & operator=(safe_enum && other) = default;
 
   inner underlying() const { return val; }
 
   bool operator==(const safe_enum & s) const { return this->val == s.val; }
   bool operator!=(const safe_enum & s) const { return this->val != s.val; }
   bool operator<(const safe_enum & s) const { return this->val < s.val; }
   bool operator<=(const safe_enum & s) const { return this->val <= s.val; }
   bool operator>(const safe_enum & s) const { return this->val > s.val; }
   bool operator>=(const safe_enum & s) const { return this->val >= s.val; }
 
   operator inner() { return val; };
 
 public:
   // Works only if enumerations are contiguous.
   class iterator {
   public:
     explicit iterator(type v) : it(v) {}
     iterator & operator++() {
       ++it;
       return *this;
     }
     safe_enum operator*() { return safe_enum(static_cast<type>(it)); }
     bool operator!=(iterator const & it) { return it.it != this->it; }
 
   private:
     int it;
   };
 
   static iterator begin() { return iterator(def::_begin_); }
 
   static iterator end() { return iterator(def::_end_); }
 
 protected:
   inner val;
 };
 
 } // akantu
 
 #endif /* __AKANTU_AKA_SAFE_ENUM_HH__ */
diff --git a/src/common/aka_static_if.hh b/src/common/aka_static_if.hh
index 29a9bae34..cc77f848d 100644
--- a/src/common/aka_static_if.hh
+++ b/src/common/aka_static_if.hh
@@ -1,94 +1,29 @@
-// Copyright (c) 2016 Vittorio Romeo
-// License: AFL 3.0 | https://opensource.org/licenses/AFL-3.0
-// http://vittorioromeo.info | vittorio.romeo@outlook.com
-
-#ifndef __AKANTU_AKA_STATIC_IF_HH__
-#define __AKANTU_AKA_STATIC_IF_HH__
-
-#include <utility>
-
-#define FWD(...) ::std::forward<decltype(__VA_ARGS__)>(__VA_ARGS__)
-
-namespace akantu {
-
-template <typename TPredicate> auto static_if(TPredicate) noexcept;
-
-namespace impl {
-  template <bool TPredicateResult> struct static_if_impl;
-
-  template <typename TFunctionToCall> struct static_if_result;
-
-  template <typename TF> auto make_static_if_result(TF && f) noexcept;
-
-  template <> struct static_if_impl<true> {
-    template <typename TF> auto & else_(TF &&) noexcept {
-      // Ignore `else_`, as the predicate is true.
-      return *this;
-    }
-
-    template <typename TPredicate> auto & else_if(TPredicate) noexcept {
-      // Ignore `else_if`, as the predicate is true.
-      return *this;
-    }
-
-    template <typename TF> auto then(TF && f) noexcept {
-      // We found a matching branch, just make a result and
-      // ignore everything else.
-      return make_static_if_result(FWD(f));
-    }
-  };
-
-  template <> struct static_if_impl<false> {
-    template <typename TF> auto & then(TF &&) noexcept {
-      // Ignore `then`, as the predicate is false.
-      return *this;
-    }
-
-    template <typename TF> auto else_(TF && f) noexcept {
-      // (Assuming that `else_` is after all `else_if` calls.)
-
-      // We found a matching branch, just make a result and
-      // ignore everything else.
-
-      return make_static_if_result(FWD(f));
-    }
-
-    template <typename TPredicate> auto else_if(TPredicate) noexcept {
-      return static_if(TPredicate{});
-    }
-
-    template <typename... Ts> auto operator()(Ts &&...) noexcept {
-      // If there are no `else` branches, we must ignore calls
-      // to a failed `static_if` matching.
-    }
-  };
-
-  template <typename TFunctionToCall>
-  struct static_if_result : TFunctionToCall {
-    // Perfect-forward the function in the result instance.
-    template <typename TFFwd>
-    explicit static_if_result(TFFwd && f) noexcept : TFunctionToCall(FWD(f)) {}
-
-    // Ignore everything, we found a result.
-    template <typename TF> auto & then(TF &&) noexcept { return *this; }
-
-    template <typename TPredicate> auto & else_if(TPredicate) noexcept {
-      return *this;
-    }
-
-    template <typename TF> auto & else_(TF &&) noexcept { return *this; }
-  };
-
-  template <typename TF> auto make_static_if_result(TF && f) noexcept {
-    return static_if_result<TF>{FWD(f)};
-  }
-} // namespace impl
-
-template <typename TPredicate> auto static_if(TPredicate) noexcept {
-  return impl::static_if_impl<TPredicate{}>{};
-}
-
-#undef FWD
-} // namespace akantu
-
-#endif /* __AKANTU_AKA_STATIC_IF_HH__ */
+/**
+ * @file   aka_static_if.hh
+ *
+ * @author Nicolas Richart <nicolas.richart@epfl.ch>
+ *
+ * @date creation: Sun Aug 13 2017
+ * @date last modification: Wed Oct 25 2017
+ *
+ * @brief  if constexpr equivalent in c++14
+ *
+ * @section LICENSE
+ *
+ * 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/>.
+ *
+ */
diff --git a/src/common/aka_static_memory.cc b/src/common/aka_static_memory.cc
index a3a18b7aa..b1e9d8efa 100644
--- a/src/common/aka_static_memory.cc
+++ b/src/common/aka_static_memory.cc
@@ -1,161 +1,160 @@
 /**
  * @file   aka_static_memory.cc
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Fri Jun 18 2010
- * @date last modification: Wed Jan 06 2016
+ * @date last modification: Wed Nov 08 2017
  *
  * @brief  Memory management
  *
  * @section LICENSE
  *
- * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
- * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
- * Solides)
+ * 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
+ * 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
+ * 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 <sstream>
 #include <stdexcept>
 
 /* -------------------------------------------------------------------------- */
 #include "aka_static_memory.hh"
 
 /* -------------------------------------------------------------------------- */
 namespace akantu {
 
 bool StaticMemory::is_instantiated = false;
 StaticMemory * StaticMemory::single_static_memory = nullptr;
 UInt StaticMemory::nb_reference = 0;
 
 /* -------------------------------------------------------------------------- */
 StaticMemory & StaticMemory::getStaticMemory() {
   if (!single_static_memory) {
     single_static_memory = new StaticMemory();
     is_instantiated = true;
   }
 
   nb_reference++;
 
   return *single_static_memory;
 }
 
 /* -------------------------------------------------------------------------- */
 void StaticMemory::destroy() {
   nb_reference--;
   if (nb_reference == 0) {
     delete single_static_memory;
   }
 }
 
 /* -------------------------------------------------------------------------- */
 StaticMemory::~StaticMemory() {
   AKANTU_DEBUG_IN();
 
   MemoryMap::iterator memory_it;
   for (memory_it = memories.begin(); memory_it != memories.end(); ++memory_it) {
     ArrayMap::iterator vector_it;
     for (vector_it = (memory_it->second).begin();
          vector_it != (memory_it->second).end(); ++vector_it) {
       delete vector_it->second;
     }
     (memory_it->second).clear();
   }
   memories.clear();
   is_instantiated = false;
   StaticMemory::single_static_memory = nullptr;
   AKANTU_DEBUG_OUT();
 }
 /* -------------------------------------------------------------------------- */
 void StaticMemory::sfree(const MemoryID & memory_id, const ID & name) {
   AKANTU_DEBUG_IN();
 
   try {
     auto & vectors = const_cast<ArrayMap &>(getMemory(memory_id));
     ArrayMap::iterator vector_it;
     vector_it = vectors.find(name);
     if (vector_it != vectors.end()) {
       AKANTU_DEBUG_INFO("Array " << name
                                  << " removed from the static memory number "
                                  << memory_id);
       delete vector_it->second;
       vectors.erase(vector_it);
       AKANTU_DEBUG_OUT();
       return;
     }
   } catch (debug::Exception e) {
     AKANTU_EXCEPTION("The memory "
                      << memory_id << " does not exist (perhaps already freed) ["
                      << e.what() << "]");
     AKANTU_DEBUG_OUT();
     return;
   }
 
   AKANTU_DEBUG_INFO("The vector " << name
                                   << " does not exist (perhaps already freed)");
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void StaticMemory::printself(std::ostream & stream, int indent) const {
   std::string space = "";
   for (Int i = 0; i < indent; i++, space += AKANTU_INDENT)
     ;
 
   std::streamsize prec = stream.precision();
   stream.precision(2);
 
   stream << space << "StaticMemory [" << std::endl;
   UInt nb_memories = memories.size();
   stream << space << " + nb memories : " << nb_memories << std::endl;
 
   Real tot_size = 0;
   MemoryMap::const_iterator memory_it;
   for (memory_it = memories.begin(); memory_it != memories.end(); ++memory_it) {
     Real mem_size = 0;
 
     stream << space << AKANTU_INDENT << "Memory [" << std::endl;
     UInt mem_id = memory_it->first;
     stream << space << AKANTU_INDENT << " + memory id   : " << mem_id
            << std::endl;
     UInt nb_vectors = (memory_it->second).size();
     stream << space << AKANTU_INDENT << " + nb vectors  : " << nb_vectors
            << std::endl;
     stream.precision(prec);
     ArrayMap::const_iterator vector_it;
     for (vector_it = (memory_it->second).begin();
          vector_it != (memory_it->second).end(); ++vector_it) {
       (vector_it->second)->printself(stream, indent + 2);
       mem_size += (vector_it->second)->getMemorySize();
     }
     stream << space << AKANTU_INDENT
            << " + total size  : " << printMemorySize<char>(mem_size)
            << std::endl;
     stream << space << AKANTU_INDENT << "]" << std::endl;
     tot_size += mem_size;
   }
   stream << space << " + total size  : " << printMemorySize<char>(tot_size)
          << std::endl;
   stream << space << "]" << std::endl;
 
   stream.precision(prec);
 }
 
 /* -------------------------------------------------------------------------- */
 
 } // akantu
diff --git a/src/common/aka_static_memory.hh b/src/common/aka_static_memory.hh
index 3fddb5de0..e80897c65 100644
--- a/src/common/aka_static_memory.hh
+++ b/src/common/aka_static_memory.hh
@@ -1,157 +1,156 @@
 /**
  * @file   aka_static_memory.hh
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Fri Jun 18 2010
- * @date last modification: Sun Oct 19 2014
+ * @date last modification: Sun Dec 03 2017
  *
  * @brief  Memory management
  *
  * @section LICENSE
  *
- * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
- * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
- * Solides)
+ * 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
+ * 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
+ * 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/>.
  *
  * @section DESCRIPTION
  *
  * The class handling the memory, allocation/reallocation/desallocation
  * The objects can register their array and ask for allocation or realocation
  *
  */
 
 /* -------------------------------------------------------------------------- */
 
 #ifndef __AKANTU_STATIC_MEMORY_HH__
 #define __AKANTU_STATIC_MEMORY_HH__
 
 /* -------------------------------------------------------------------------- */
 #include "aka_array.hh"
 #include "aka_common.hh"
 
 /* -------------------------------------------------------------------------- */
 #include <map>
 
 /* -------------------------------------------------------------------------- */
 namespace akantu {
 
 using ArrayMap = std::map<ID, ArrayBase *>;
 using MemoryMap = std::map<MemoryID, ArrayMap>;
 
 /**
  * @class StaticMemory
  * @brief Class for memory management common to all objects (this class as to
  * be accessed by an interface class memory)
  */
 class StaticMemory {
 
   /* ------------------------------------------------------------------------ */
   /* Constructors/Destructors                                                 */
   /* ------------------------------------------------------------------------ */
 private:
   /// Default constructor
   StaticMemory() = default;
 
 public:
   virtual ~StaticMemory();
 
   /* ------------------------------------------------------------------------ */
   /* Accessors                                                                */
   /* ------------------------------------------------------------------------ */
 public:
   /// Get the global instance of the StaticMemory
   static StaticMemory & getStaticMemory();
 
   static bool isInstantiated() { return is_instantiated; };
 
   /// remove a reference on the static memory
   void destroy();
 
   /// access to an Array
   inline const ArrayBase & getArray(const MemoryID & memory_id,
                                     const ID & name) const;
 
   /// get all vectors of a memory
   inline const ArrayMap & getMemory(const MemoryID & memory_id) const;
 
   /* ------------------------------------------------------------------------ */
   /* Class Methods                                                            */
   /* ------------------------------------------------------------------------ */
 public:
   /**
    * Allocation of an array of type
    *
    * @param memory_id the id of the memory accessing to the static memory
    * @param name name of the array (for example connectivity)
    * @param size number of size (for example number of nodes)
    * @param nb_component number of component (for example spatial dimension)
    * @param type the type code of the array to be allocated
    *
    * @return pointer to an array of size nb_tupes * nb_component * sizeof(T)
    */
   template <typename T>
   Array<T> & smalloc(const MemoryID & memory_id, const ID & name, UInt size,
                      UInt nb_component);
 
   template <typename T>
   Array<T> & smalloc(const MemoryID & memory_id, const ID & name, UInt size,
                      UInt nb_component, const T & init_value);
   /**
    * free the memory associated to the array name
    *
    * @param memory_id the id of the memory accessing to the static memory
    * @param name the name of an existing array
    */
   void sfree(const MemoryID & memory_id, const ID & name);
 
   /// function to print the containt of the class
   virtual void printself(std::ostream & stream, int indent = 0) const;
 
   /* ------------------------------------------------------------------------ */
   /* Class Members                                                            */
   /* ------------------------------------------------------------------------ */
 private:
   /// is the static memory instantiated
   static bool is_instantiated;
 
   /// unique instance of the StaticMemory
   static StaticMemory * single_static_memory;
 
   /// map of all allocated arrays, indexed by their names
   MemoryMap memories;
 
   /// number of references on the static memory
   static UInt nb_reference;
 };
 
 #include "aka_static_memory_inline_impl.cc"
 #include "aka_static_memory_tmpl.hh"
 
 /* -------------------------------------------------------------------------- */
 /* inline functions                                                           */
 /* -------------------------------------------------------------------------- */
 
 /// standard output stream operator
 inline std::ostream & operator<<(std::ostream & stream,
                                  const StaticMemory & _this) {
   _this.printself(stream);
   return stream;
 }
 
 } // namespace akantu
 
 #endif /* __AKANTU_STATIC_MEMORY_HH__ */
diff --git a/src/common/aka_static_memory_inline_impl.cc b/src/common/aka_static_memory_inline_impl.cc
index cc245ebaf..a0cc61fab 100644
--- a/src/common/aka_static_memory_inline_impl.cc
+++ b/src/common/aka_static_memory_inline_impl.cc
@@ -1,65 +1,64 @@
 /**
  * @file   aka_static_memory_inline_impl.cc
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Thu Jul 15 2010
- * @date last modification: Fri May 22 2015
+ * @date last modification: Wed Feb 03 2016
  *
  * @brief  Implementation of inline functions of the class StaticMemory
  *
  * @section LICENSE
  *
- * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
- * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
- * Solides)
+ * 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
+ * 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
+ * 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/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 inline const ArrayMap &
 StaticMemory::getMemory(const MemoryID & memory_id) const {
   AKANTU_DEBUG_IN();
   MemoryMap::const_iterator memory_it;
   memory_it = memories.find(memory_id);
 
   if (memory_it == memories.end()) {
     AKANTU_SILENT_EXCEPTION("StaticMemory as no memory with ID " << memory_id);
   }
 
   AKANTU_DEBUG_OUT();
   return memory_it->second;
 }
 
 /* -------------------------------------------------------------------------- */
 inline const ArrayBase & StaticMemory::getArray(const MemoryID & memory_id,
                                                 const ID & name) const {
   AKANTU_DEBUG_IN();
 
   const ArrayMap & vectors = getMemory(memory_id);
 
   ArrayMap::const_iterator vectors_it;
   vectors_it = vectors.find(name);
   if (vectors_it == vectors.end()) {
     AKANTU_SILENT_EXCEPTION("StaticMemory as no array named "
                             << name << " for the Memory " << memory_id);
   }
 
   AKANTU_DEBUG_OUT();
   return *(vectors_it->second);
 }
 
 /* -------------------------------------------------------------------------- */
diff --git a/src/common/aka_static_memory_tmpl.hh b/src/common/aka_static_memory_tmpl.hh
index 484f7f125..b938bed9d 100644
--- a/src/common/aka_static_memory_tmpl.hh
+++ b/src/common/aka_static_memory_tmpl.hh
@@ -1,87 +1,86 @@
 /**
  * @file   aka_static_memory_tmpl.hh
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Thu Jul 15 2010
- * @date last modification: Sun Oct 19 2014
+ * @date last modification: Tue Feb 20 2018
  *
  * @brief  template part of the StaticMemory
  *
  * @section LICENSE
  *
- * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
- * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
- * Solides)
+ * 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
+ * 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
+ * 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/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 template <typename T>
 Array<T> & StaticMemory::smalloc(const MemoryID & memory_id, const ID & name,
                                  UInt size, UInt nb_component) {
   AKANTU_DEBUG_IN();
 
   MemoryMap::iterator memory_it;
   memory_it = memories.find(memory_id);
 
   if (memory_it == memories.end()) {
     memories[memory_id] = ArrayMap();
     memory_it = memories.find(memory_id);
   }
 
   if ((memory_it->second).find(name) != (memory_it->second).end()) {
     AKANTU_ERROR("The vector \"" << name
                                  << "\" is already registred in the memory "
                                  << memory_id);
   }
 
   auto * tmp_vect = new Array<T>(size, nb_component, name);
   (memory_it->second)[name] = tmp_vect;
 
   AKANTU_DEBUG_OUT();
   return *tmp_vect;
 }
 
 /* -------------------------------------------------------------------------- */
 template <typename T>
 Array<T> & StaticMemory::smalloc(const MemoryID & memory_id, const ID & name,
                                  UInt size, UInt nb_component,
                                  const T & init_value) {
   AKANTU_DEBUG_IN();
 
   MemoryMap::iterator memory_it;
   memory_it = memories.find(memory_id);
 
   if (memory_it == memories.end()) {
     memories[memory_id] = ArrayMap();
     memory_it = memories.find(memory_id);
   }
 
   if ((memory_it->second).find(name) != (memory_it->second).end()) {
     AKANTU_ERROR("The vector \"" << name
                                  << "\" is already registred in the memory "
                                  << memory_id);
   }
 
   auto * tmp_vect = new Array<T>(size, nb_component, init_value, name);
   (memory_it->second)[name] = tmp_vect;
 
   AKANTU_DEBUG_OUT();
   return *tmp_vect;
 }
 
 /* -------------------------------------------------------------------------- */
diff --git a/src/common/aka_typelist.hh b/src/common/aka_typelist.hh
index 1eb75cdfe..aa295594d 100644
--- a/src/common/aka_typelist.hh
+++ b/src/common/aka_typelist.hh
@@ -1,155 +1,155 @@
 /**
  * @file   aka_typelist.hh
  *
  * @author Alejandro M. Aragón <alejandro.aragon@epfl.ch>
  *
  * @date creation: Fri Jan 04 2013
- * @date last modification: Sun Oct 19 2014
+ * @date last modification: Mon Jun 19 2017
  *
  * @brief  Objects that support the visitor design pattern
  *
  * @section LICENSE
  *
- * Copyright  (©)  2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de Lausanne)
+ * 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
+ * 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
+ * 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_TYPELIST_HH__
 #define __AKANTU_TYPELIST_HH__
 
 #include "aka_common.hh"
 
 namespace akantu {
 
 struct Empty_type {};
 class Null_type {};
 
 template <class T, class U> struct Typelist {
   typedef T Head;
   typedef U Tail;
 };
 
 template <typename T1 = Null_type, typename T2 = Null_type,
           typename T3 = Null_type, typename T4 = Null_type,
           typename T5 = Null_type, typename T6 = Null_type,
           typename T7 = Null_type, typename T8 = Null_type,
           typename T9 = Null_type, typename T10 = Null_type,
           typename T11 = Null_type, typename T12 = Null_type,
           typename T13 = Null_type, typename T14 = Null_type,
           typename T15 = Null_type, typename T16 = Null_type,
           typename T17 = Null_type, typename T18 = Null_type,
           typename T19 = Null_type, typename T20 = Null_type>
 struct MakeTypelist {
 private:
   typedef typename MakeTypelist<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,
                                 T13, T14, T15, T16, T17, T18, T19, T20>::Result
       TailResult;
 
 public:
   typedef Typelist<T1, TailResult> Result;
 };
 
 template <> struct MakeTypelist<> { typedef Null_type Result; };
 
 ////////////////////////////////////////////////////////////////////////////////
 // class template Length
 // Computes the length of a typelist
 // Invocation (TList is a typelist):
 // Length<TList>::value
 // returns a compile-time constant containing the length of TList, not counting
 //     the end terminator (which by convention is Null_type)
 ////////////////////////////////////////////////////////////////////////////////
 
 template <class TList> struct Length;
 template <> struct Length<Null_type> {
   enum { value = 0 };
 };
 
 template <class T, class U> struct Length<Typelist<T, U>> {
   enum { value = 1 + Length<U>::value };
 };
 
 ////////////////////////////////////////////////////////////////////////////////
 // class template TypeAt
 // Finds the type at a given index in a typelist
 // Invocation (TList is a typelist and index is a compile-time integral
 //     constant):
 // TypeAt<TList, index>::Result
 // returns the type in position 'index' in TList
 // If you pass an out-of-bounds index, the result is a compile-time error
 ////////////////////////////////////////////////////////////////////////////////
 
 template <class TList, unsigned int index> struct TypeAt;
 
 template <class Head, class Tail> struct TypeAt<Typelist<Head, Tail>, 0> {
   typedef Head Result;
 };
 
 template <class Head, class Tail, unsigned int i>
 struct TypeAt<Typelist<Head, Tail>, i> {
   typedef typename TypeAt<Tail, i - 1>::Result Result;
 };
 
 ////////////////////////////////////////////////////////////////////////////////
 // class template Erase
 // Erases the first occurence, if any, of a type in a typelist
 // Invocation (TList is a typelist and T is a type):
 // Erase<TList, T>::Result
 // returns a typelist that is TList without the first occurence of T
 ////////////////////////////////////////////////////////////////////////////////
 
 template <class TList, class T> struct Erase;
 
 template <class T> // Specialization 1
 struct Erase<Null_type, T> {
   typedef Null_type Result;
 };
 
 template <class T, class Tail> // Specialization 2
 struct Erase<Typelist<T, Tail>, T> {
   typedef Tail Result;
 };
 
 template <class Head, class Tail, class T> // Specialization 3
 struct Erase<Typelist<Head, Tail>, T> {
   typedef Typelist<Head, typename Erase<Tail, T>::Result> Result;
 };
 
 template <class TList, class T> struct IndexOf;
 
 template <class T> struct IndexOf<Null_type, T> {
   enum { value = -1 };
 };
 
 template <class T, class Tail> struct IndexOf<Typelist<T, Tail>, T> {
   enum { value = 0 };
 };
 
 template <class Head, class Tail, class T>
 struct IndexOf<Typelist<Head, Tail>, T> {
 private:
   enum { temp = IndexOf<Tail, T>::value };
 
 public:
   enum { value = (temp == -1 ? -1 : 1 + temp) };
 };
 
 } // akantu
 
 #endif /* __AKANTU_TYPELIST_HH__ */
diff --git a/src/common/aka_types.hh b/src/common/aka_types.hh
index 09c422ee7..33e1d3aaf 100644
--- a/src/common/aka_types.hh
+++ b/src/common/aka_types.hh
@@ -1,1302 +1,1301 @@
 /**
  * @file   aka_types.hh
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Thu Feb 17 2011
- * @date last modification: Fri Jan 22 2016
+ * @date last modification: Tue Feb 20 2018
  *
  * @brief  description of the "simple" types
  *
  * @section LICENSE
  *
- * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
- * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
- * Solides)
+ * 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
+ * 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
+ * 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_error.hh"
 #include "aka_fwd.hh"
 #include "aka_math.hh"
 /* -------------------------------------------------------------------------- */
 #include <initializer_list>
 #include <iomanip>
 #include <type_traits>
 /* -------------------------------------------------------------------------- */
 
 #ifndef __AKANTU_AKA_TYPES_HH__
 #define __AKANTU_AKA_TYPES_HH__
 
 namespace akantu {
 
 enum NormType { L_1 = 1, L_2 = 2, L_inf = UInt(-1) };
 
 /**
  * DimHelper is a class to generalize the setup of a dim array from 3
  * values. This gives a common interface in the TensorStorage class
  * independently of its derived inheritance (Vector, Matrix, Tensor3)
  * @tparam dim
  */
 template <UInt dim> struct DimHelper {
   static inline void setDims(UInt m, UInt n, UInt p, UInt dims[dim]);
 };
 
 /* -------------------------------------------------------------------------- */
 template <> struct DimHelper<1> {
   static inline void setDims(UInt m, __attribute__((unused)) UInt n,
                              __attribute__((unused)) UInt p, UInt dims[1]) {
     dims[0] = m;
   }
 };
 
 /* -------------------------------------------------------------------------- */
 template <> struct DimHelper<2> {
   static inline void setDims(UInt m, UInt n, __attribute__((unused)) UInt p,
                              UInt dims[2]) {
     dims[0] = m;
     dims[1] = n;
   }
 };
 
 /* -------------------------------------------------------------------------- */
 template <> struct DimHelper<3> {
   static inline void setDims(UInt m, UInt n, UInt p, UInt dims[3]) {
     dims[0] = m;
     dims[1] = n;
     dims[2] = p;
   }
 };
 
 /* -------------------------------------------------------------------------- */
 template <typename T, UInt ndim, class RetType> class TensorStorage;
 
 /* -------------------------------------------------------------------------- */
 /* Proxy classes                                                              */
 /* -------------------------------------------------------------------------- */
 namespace tensors {
   template <class A, class B> struct is_copyable {
     enum : bool { value = false };
   };
 
   template <class A> struct is_copyable<A, A> {
     enum : bool { value = true };
   };
 
   template <class A> struct is_copyable<A, typename A::RetType> {
     enum : bool { value = true };
   };
 
   template <class A> struct is_copyable<A, typename A::RetType::proxy> {
     enum : bool { value = true };
   };
 
 } // namespace tensors
 
 /**
  * @class TensorProxy aka_types.hh
  * @desc The TensorProxy class is a proxy class to the TensorStorage it handles
  * the
  * wrapped case. That is to say if an accessor should give access to a Tensor
  * wrapped on some data, like the Array<T>::iterator they can return a
  * TensorProxy that will be automatically transformed as a TensorStorage wrapped
  * on the same data
  * @tparam T stored type
  * @tparam ndim order of the tensor
  * @tparam RetType real derived type
  */
 template <typename T, UInt ndim, class _RetType> class TensorProxy {
 protected:
   using RetTypeProxy = typename _RetType::proxy;
 
   constexpr TensorProxy(T * data, UInt m, UInt n, UInt p) {
     DimHelper<ndim>::setDims(m, n, p, this->n);
     this->values = data;
   }
 
 #ifndef SWIG
   template <class Other,
             typename = std::enable_if_t<
                 tensors::is_copyable<TensorProxy, Other>::value>>
   explicit TensorProxy(const Other & other) {
     this->values = other.storage();
     for (UInt i = 0; i < ndim; ++i)
       this->n[i] = other.size(i);
   }
 #endif
 public:
   using RetType = _RetType;
 
   UInt size(UInt i) const {
     AKANTU_DEBUG_ASSERT(i < ndim,
                         "This tensor has only " << ndim << " dimensions, not "
                                                 << (i + 1));
     return n[i];
   }
 
   inline UInt size() const {
     UInt _size = 1;
     for (UInt d = 0; d < ndim; ++d)
       _size *= this->n[d];
     return _size;
   }
 
   T * storage() const { return values; }
 
 #ifndef SWIG
   template <class Other,
             typename = std::enable_if_t<
                 tensors::is_copyable<TensorProxy, Other>::value>>
   inline TensorProxy & operator=(const Other & other) {
     AKANTU_DEBUG_ASSERT(
         other.size() == this->size(),
         "You are trying to copy two tensors with different sizes");
     memcpy(this->values, other.storage(), this->size() * sizeof(T));
     return *this;
   }
 #endif
   // template <class Other, typename = std::enable_if_t<
   //                          tensors::is_copyable<TensorProxy, Other>::value>>
   // inline TensorProxy & operator=(const Other && other) {
   //   AKANTU_DEBUG_ASSERT(
   //       other.size() == this->size(),
   //       "You are trying to copy two tensors with different sizes");
   //   memcpy(this->values, other.storage(), this->size() * sizeof(T));
   //   return *this;
   // }
 
   template <typename O> inline RetTypeProxy & operator*=(const O & o) {
     RetType(*this) *= o;
     return static_cast<RetTypeProxy &>(*this);
   }
 
   template <typename O> inline RetTypeProxy & operator/=(const O & o) {
     RetType(*this) /= o;
     return static_cast<RetTypeProxy &>(*this);
   }
 
 protected:
   T * values;
   UInt n[ndim];
 };
 
 /* -------------------------------------------------------------------------- */
 template <typename T> class VectorProxy : public TensorProxy<T, 1, Vector<T>> {
   using parent = TensorProxy<T, 1, Vector<T>>;
   using type = Vector<T>;
 
 public:
   constexpr VectorProxy(T * data, UInt n) : parent(data, n, 0, 0) {}
   template <class Other> explicit VectorProxy(Other & src) : parent(src) {}
 
   /* ---------------------------------------------------------------------- */
   template <class Other>
   inline VectorProxy<T> & operator=(const Other & other) {
     parent::operator=(other);
     return *this;
   }
 
   // inline VectorProxy<T> & operator=(const VectorProxy && other) {
   //   parent::operator=(other);
   //   return *this;
   // }
 
   /* ------------------------------------------------------------------------ */
   T & operator()(UInt index) { return this->values[index]; };
   const T & operator()(UInt index) const { return this->values[index]; };
 };
 
 template <typename T> class MatrixProxy : public TensorProxy<T, 2, Matrix<T>> {
   using parent = TensorProxy<T, 2, Matrix<T>>;
   using type = Matrix<T>;
 
 public:
   MatrixProxy(T * data, UInt m, UInt n) : parent(data, m, n, 0) {}
   template <class Other> explicit MatrixProxy(Other & src) : parent(src) {}
 
   /* ---------------------------------------------------------------------- */
   template <class Other>
   inline MatrixProxy<T> & operator=(const Other & other) {
     parent::operator=(other);
     return *this;
   }
 };
 
 template <typename T>
 class Tensor3Proxy : public TensorProxy<T, 3, Tensor3<T>> {
   using parent = TensorProxy<T, 3, Tensor3<T>>;
   using type = Tensor3<T>;
 
 public:
   Tensor3Proxy(const T * data, UInt m, UInt n, UInt k)
       : parent(data, m, n, k) {}
   Tensor3Proxy(const Tensor3Proxy & src) : parent(src) {}
   Tensor3Proxy(const Tensor3<T> & src) : parent(src) {}
 
   /* ---------------------------------------------------------------------- */
   template <class Other>
   inline Tensor3Proxy<T> & operator=(const Other & other) {
     parent::operator=(other);
     return *this;
   }
 };
 
 /* -------------------------------------------------------------------------- */
 /* Tensor base class                                                          */
 /* -------------------------------------------------------------------------- */
 template <typename T, UInt ndim, class RetType>
 class TensorStorage : public TensorTrait {
 public:
   using value_type = T;
 
   friend class Array<T>;
 
 protected:
   template <class TensorType> void copySize(const TensorType & src) {
     for (UInt d = 0; d < ndim; ++d)
       this->n[d] = src.size(d);
     this->_size = src.size();
   }
 
   TensorStorage() : values(nullptr) {
     for (UInt d = 0; d < ndim; ++d)
       this->n[d] = 0;
     _size = 0;
   }
 
   TensorStorage(const TensorProxy<T, ndim, RetType> & proxy) {
     this->copySize(proxy);
     this->values = proxy.storage();
     this->wrapped = true;
   }
 
 public:
   TensorStorage(const TensorStorage & src) = delete;
 
   TensorStorage(const TensorStorage & src, bool deep_copy) : values(nullptr) {
     if (deep_copy)
       this->deepCopy(src);
     else
       this->shallowCopy(src);
   }
 
 protected:
   TensorStorage(UInt m, UInt n, UInt p, const T & def) {
     static_assert(std::is_trivially_constructible<T>{},
                   "Cannot create a tensor on non trivial types");
     DimHelper<ndim>::setDims(m, n, p, this->n);
 
     this->computeSize();
     this->values = new T[this->_size];
     this->set(def);
     this->wrapped = false;
   }
 
   TensorStorage(T * data, UInt m, UInt n, UInt p) {
     DimHelper<ndim>::setDims(m, n, p, this->n);
 
     this->computeSize();
     this->values = data;
     this->wrapped = true;
   }
 
 public:
   /* ------------------------------------------------------------------------ */
   template <class TensorType> inline void shallowCopy(const TensorType & src) {
     this->copySize(src);
     if (!this->wrapped)
       delete[] this->values;
     this->values = src.storage();
     this->wrapped = true;
   }
 
   /* ------------------------------------------------------------------------ */
   template <class TensorType> inline void deepCopy(const TensorType & src) {
     this->copySize(src);
 
     if (!this->wrapped)
       delete[] this->values;
 
     static_assert(std::is_trivially_constructible<T>{},
                   "Cannot create a tensor on non trivial types");
     this->values = new T[this->_size];
 
     static_assert(std::is_trivially_copyable<T>{},
                   "Cannot copy a tensor on non trivial types");
     memcpy((void *)this->values, (void *)src.storage(),
            this->_size * sizeof(T));
 
     this->wrapped = false;
   }
 
   virtual ~TensorStorage() {
     if (!this->wrapped)
       delete[] this->values;
   }
 
   /* ------------------------------------------------------------------------ */
   inline TensorStorage & operator=(const TensorStorage & src) {
     return this->operator=(dynamic_cast<RetType &>(src));
   }
 
   /* ------------------------------------------------------------------------ */
   inline TensorStorage & operator=(const RetType & src) {
     if (this != &src) {
       if (this->wrapped) {
         static_assert(std::is_trivially_copyable<T>{},
                       "Cannot copy a tensor on non trivial types");
         // this test is not sufficient for Tensor of order higher than 1
         AKANTU_DEBUG_ASSERT(this->_size == src.size(),
                             "Tensors of different size");
         memcpy((void *)this->values, (void *)src.storage(),
                this->_size * sizeof(T));
       } else {
         deepCopy(src);
       }
     }
     return *this;
   }
 
   /* ------------------------------------------------------------------------ */
   template <class R>
   inline RetType & operator+=(const TensorStorage<T, ndim, R> & other) {
     T * a = this->storage();
     T * b = other.storage();
     AKANTU_DEBUG_ASSERT(
         _size == other.size(),
         "The two tensors do not have the same size, they cannot be subtracted");
     for (UInt i = 0; i < _size; ++i)
       *(a++) += *(b++);
     return *(static_cast<RetType *>(this));
   }
 
   /* ------------------------------------------------------------------------ */
   template <class R>
   inline RetType & operator-=(const TensorStorage<T, ndim, R> & other) {
     T * a = this->storage();
     T * b = other.storage();
     AKANTU_DEBUG_ASSERT(
         _size == other.size(),
         "The two tensors do not have the same size, they cannot be subtracted");
     for (UInt i = 0; i < _size; ++i)
       *(a++) -= *(b++);
     return *(static_cast<RetType *>(this));
   }
 
   /* ------------------------------------------------------------------------ */
   inline RetType & operator+=(const T & x) {
     T * a = this->values;
     for (UInt i = 0; i < _size; ++i)
       *(a++) += x;
     return *(static_cast<RetType *>(this));
   }
 
   /* ------------------------------------------------------------------------ */
   inline RetType & operator-=(const T & x) {
     T * a = this->values;
     for (UInt i = 0; i < _size; ++i)
       *(a++) -= x;
     return *(static_cast<RetType *>(this));
   }
 
   /* ------------------------------------------------------------------------ */
   inline RetType & operator*=(const T & x) {
     T * a = this->storage();
     for (UInt i = 0; i < _size; ++i)
       *(a++) *= x;
     return *(static_cast<RetType *>(this));
   }
 
   /* ---------------------------------------------------------------------- */
   inline RetType & operator/=(const T & x) {
     T * a = this->values;
     for (UInt i = 0; i < _size; ++i)
       *(a++) /= x;
     return *(static_cast<RetType *>(this));
   }
 
   /// Y = \alpha X + Y
   inline RetType & aXplusY(const TensorStorage & other, const T & alpha = 1.) {
     AKANTU_DEBUG_ASSERT(
         _size == other.size(),
         "The two tensors do not have the same size, they cannot be subtracted");
 
     Math::aXplusY(this->_size, alpha, other.storage(), this->storage());
     return *(static_cast<RetType *>(this));
   }
 
   /* ------------------------------------------------------------------------ */
   T * storage() const { return values; }
   UInt size() const { return _size; }
   UInt size(UInt i) const {
     AKANTU_DEBUG_ASSERT(i < ndim,
                         "This tensor has only " << ndim << " dimensions, not "
                                                 << (i + 1));
     return n[i];
   };
   /* ------------------------------------------------------------------------ */
   inline void clear() { memset(values, 0, _size * sizeof(T)); };
   inline void set(const T & t) { std::fill_n(values, _size, t); };
 
   template <class TensorType> inline void copy(const TensorType & other) {
     AKANTU_DEBUG_ASSERT(
         _size == other.size(),
         "The two tensors do not have the same size, they cannot be copied");
     memcpy(values, other.storage(), _size * sizeof(T));
   }
 
   bool isWrapped() const { return this->wrapped; }
 
 protected:
   inline void computeSize() {
     _size = 1;
     for (UInt d = 0; d < ndim; ++d)
       _size *= this->n[d];
   }
 
 protected:
   template <typename R, NormType norm_type> struct NormHelper {
     template <class Ten> static R norm(const Ten & ten) {
       R _norm = 0.;
       R * it = ten.storage();
       R * end = ten.storage() + ten.size();
       for (; it < end; ++it)
         _norm += std::pow(std::abs(*it), norm_type);
       return std::pow(_norm, 1. / norm_type);
     }
   };
 
   template <typename R> struct NormHelper<R, L_1> {
     template <class Ten> static R norm(const Ten & ten) {
       R _norm = 0.;
       R * it = ten.storage();
       R * end = ten.storage() + ten.size();
       for (; it < end; ++it)
         _norm += std::abs(*it);
       return _norm;
     }
   };
 
   template <typename R> struct NormHelper<R, L_2> {
     template <class Ten> static R norm(const Ten & ten) {
       R _norm = 0.;
       R * it = ten.storage();
       R * end = ten.storage() + ten.size();
       for (; it < end; ++it)
         _norm += *it * *it;
       return sqrt(_norm);
     }
   };
 
   template <typename R> struct NormHelper<R, L_inf> {
     template <class Ten> static R norm(const Ten & ten) {
       R _norm = 0.;
       R * it = ten.storage();
       R * end = ten.storage() + ten.size();
       for (; it < end; ++it)
         _norm = std::max(std::abs(*it), _norm);
       return _norm;
     }
   };
 
 public:
   /*----------------------------------------------------------------------- */
   /// "Entrywise" norm norm<L_p> @f[ \|\boldsymbol{T}\|_p = \left(
   /// \sum_i^{n[0]}\sum_j^{n[1]}\sum_k^{n[2]} |T_{ijk}|^p \right)^{\frac{1}{p}}
   /// @f]
   template <NormType norm_type> inline T norm() const {
     return NormHelper<T, norm_type>::norm(*this);
   }
 
 protected:
   UInt n[ndim];
   UInt _size;
   T * values;
   bool wrapped{false};
 };
 
 /* -------------------------------------------------------------------------- */
 /* Vector                                                                     */
 /* -------------------------------------------------------------------------- */
 template <typename T> class Vector : public TensorStorage<T, 1, Vector<T>> {
   using parent = TensorStorage<T, 1, Vector<T>>;
 
 public:
   using value_type = typename parent::value_type;
   using proxy = VectorProxy<T>;
 
 public:
   Vector() : parent() {}
   explicit Vector(UInt n, const T & def = T()) : parent(n, 0, 0, def) {}
   Vector(T * data, UInt n) : parent(data, n, 0, 0) {}
   Vector(const Vector & src, bool deep_copy = true) : parent(src, deep_copy) {}
   Vector(const TensorProxy<T, 1, Vector> & src) : parent(src) {}
 
   Vector(std::initializer_list<T> list) : parent(list.size(), 0, 0, T()) {
     UInt i = 0;
     for (auto val : list) {
       operator()(i++) = val;
     }
   }
 
 public:
   ~Vector() override = default;
 
   /* ------------------------------------------------------------------------ */
   inline Vector & operator=(const Vector & src) {
     parent::operator=(src);
     return *this;
   }
 
   /* ------------------------------------------------------------------------ */
   inline T & operator()(UInt i) {
     AKANTU_DEBUG_ASSERT((i < this->n[0]),
                         "Access out of the vector! "
                             << "Index (" << i
                             << ") is out of the vector of size (" << this->n[0]
                             << ")");
     return *(this->values + i);
   }
 
   inline const T & operator()(UInt i) const {
     AKANTU_DEBUG_ASSERT((i < this->n[0]),
                         "Access out of the vector! "
                             << "Index (" << i
                             << ") is out of the vector of size (" << this->n[0]
                             << ")");
     return *(this->values + i);
   }
 
   inline T & operator[](UInt i) { return this->operator()(i); }
   inline const T & operator[](UInt i) const { return this->operator()(i); }
 
   /* ------------------------------------------------------------------------ */
   inline Vector<T> & operator*=(Real x) { return parent::operator*=(x); }
   inline Vector<T> & operator/=(Real x) { return parent::operator/=(x); }
   /* ------------------------------------------------------------------------ */
   inline Vector<T> & operator*=(const Vector<T> & vect) {
     T * a = this->storage();
     T * b = vect.storage();
     for (UInt i = 0; i < this->_size; ++i)
       *(a++) *= *(b++);
     return *this;
   }
 
   /* ------------------------------------------------------------------------ */
   inline Real dot(const Vector<T> & vect) const {
     return Math::vectorDot(this->values, vect.storage(), this->_size);
   }
 
   /* ------------------------------------------------------------------------ */
   inline Real mean() const {
     Real mean = 0;
     T * a = this->storage();
     for (UInt i = 0; i < this->_size; ++i)
       mean += *(a++);
     return mean / this->_size;
   }
 
   /* ------------------------------------------------------------------------ */
   inline Vector & crossProduct(const Vector<T> & v1, const Vector<T> & v2) {
     AKANTU_DEBUG_ASSERT(this->size() == 3,
                         "crossProduct is only defined in 3D (n=" << this->size()
                                                                  << ")");
     AKANTU_DEBUG_ASSERT(
         this->size() == v1.size() && this->size() == v2.size(),
         "crossProduct is not a valid operation non matching size vectors");
     Math::vectorProduct3(v1.storage(), v2.storage(), this->values);
     return *this;
   }
 
   inline Vector crossProduct(const Vector<T> & v) {
     Vector<T> tmp(this->size());
     tmp.crossProduct(*this, v);
     return tmp;
   }
 
   /* ------------------------------------------------------------------------ */
   inline void solve(const Matrix<T> & A, const Vector<T> & b) {
     AKANTU_DEBUG_ASSERT(
         this->size() == A.rows() && this->_size == A.cols(),
         "The size of the solution vector mismatches the size of the matrix");
     AKANTU_DEBUG_ASSERT(
         this->_size == b._size,
         "The rhs vector has a mismatch in size with the matrix");
     Math::solve(this->_size, A.storage(), this->values, b.storage());
   }
 
   /* ------------------------------------------------------------------------ */
   template <bool tr_A>
   inline void mul(const Matrix<T> & A, const Vector<T> & x, Real alpha = 1.0);
   /* ------------------------------------------------------------------------ */
   inline Real norm() const { return parent::template norm<L_2>(); }
 
   template <NormType nt> inline Real norm() const {
     return parent::template norm<nt>();
   }
 
   /* ------------------------------------------------------------------------ */
   inline Vector<Real> & normalize() {
     Real n = norm();
     operator/=(n);
     return *this;
   }
 
   /* ------------------------------------------------------------------------ */
   /// norm of (*this - x)
   inline Real distance(const Vector<T> & y) const {
     Real * vx = this->values;
     Real * vy = y.storage();
     Real sum_2 = 0;
     for (UInt i = 0; i < this->_size; ++i, ++vx, ++vy)
       sum_2 += (*vx - *vy) * (*vx - *vy);
     return sqrt(sum_2);
   }
 
   /* ------------------------------------------------------------------------ */
   inline bool equal(const Vector<T> & v,
                     Real tolerance = Math::getTolerance()) const {
     T * a = this->storage();
     T * b = v.storage();
     UInt i = 0;
     while (i < this->_size && (std::abs(*(a++) - *(b++)) < tolerance))
       ++i;
     return i == this->_size;
   }
 
   /* ------------------------------------------------------------------------ */
   inline short compare(const Vector<T> & v,
                        Real tolerance = Math::getTolerance()) const {
     T * a = this->storage();
     T * b = v.storage();
     for (UInt i(0); i < this->_size; ++i, ++a, ++b) {
       if (std::abs(*a - *b) > tolerance)
         return (((*a - *b) > tolerance) ? 1 : -1);
     }
     return 0;
   }
 
   /* ------------------------------------------------------------------------ */
   inline bool operator==(const Vector<T> & v) const { return equal(v); }
   inline bool operator!=(const Vector<T> & v) const { return !operator==(v); }
   inline bool operator<(const Vector<T> & v) const { return compare(v) == -1; }
   inline bool operator>(const Vector<T> & v) const { return compare(v) == 1; }
 
   /* ------------------------------------------------------------------------ */
   /// function to print the containt of the class
   virtual void printself(std::ostream & stream, int indent = 0) const {
     std::string space;
     for (Int i = 0; i < indent; i++, space += AKANTU_INDENT)
       ;
 
     stream << "[";
     for (UInt i = 0; i < this->_size; ++i) {
       if (i != 0)
         stream << ", ";
       stream << this->values[i];
     }
     stream << "]";
   }
 
   //  friend class ::akantu::Array<T>;
 };
 
 using RVector = Vector<Real>;
 
 /* ------------------------------------------------------------------------ */
 template <>
 inline bool Vector<UInt>::equal(const Vector<UInt> & v,
                                 __attribute__((unused)) Real tolerance) const {
   UInt * a = this->storage();
   UInt * b = v.storage();
   UInt i = 0;
   while (i < this->_size && (*(a++) == *(b++)))
     ++i;
   return i == this->_size;
 }
 
 /* ------------------------------------------------------------------------ */
 /* Matrix                                                                   */
 /* ------------------------------------------------------------------------ */
 template <typename T> class Matrix : public TensorStorage<T, 2, Matrix<T>> {
   using parent = TensorStorage<T, 2, Matrix<T>>;
 
 public:
   using value_type = typename parent::value_type;
   using proxy = MatrixProxy<T>;
 
 public:
   Matrix() : parent() {}
   Matrix(UInt m, UInt n, const T & def = T()) : parent(m, n, 0, def) {}
   Matrix(T * data, UInt m, UInt n) : parent(data, m, n, 0) {}
   Matrix(const Matrix & src, bool deep_copy = true) : parent(src, deep_copy) {}
   Matrix(const MatrixProxy<T> & src) : parent(src) {}
   Matrix(std::initializer_list<std::initializer_list<T>> list) {
     static_assert(std::is_trivially_copyable<T>{},
                   "Cannot create a tensor on non trivial types");
     std::size_t n = 0;
     std::size_t m = list.size();
     for (auto row : list) {
       n = std::max(n, row.size());
     }
 
     DimHelper<2>::setDims(m, n, 0, this->n);
     this->computeSize();
     this->values = new T[this->_size];
     this->set(0);
 
     UInt i = 0, j = 0;
     for (auto & row : list) {
       for (auto & val : row) {
         at(i, j++) = val;
       }
       ++i;
       j = 0;
     }
   }
 
   ~Matrix() override = default;
   /* ------------------------------------------------------------------------ */
   inline Matrix & operator=(const Matrix & src) {
     parent::operator=(src);
     return *this;
   }
 
 public:
   /* ---------------------------------------------------------------------- */
   UInt rows() const { return this->n[0]; }
   UInt cols() const { return this->n[1]; }
 
   /* ---------------------------------------------------------------------- */
   inline T & at(UInt i, UInt j) {
     AKANTU_DEBUG_ASSERT(((i < this->n[0]) && (j < this->n[1])),
                         "Access out of the matrix! "
                             << "Index (" << i << ", " << j
                             << ") is out of the matrix of size (" << this->n[0]
                             << ", " << this->n[1] << ")");
     return *(this->values + i + j * this->n[0]);
   }
 
   inline const T & at(UInt i, UInt j) const {
     AKANTU_DEBUG_ASSERT(((i < this->n[0]) && (j < this->n[1])),
                         "Access out of the matrix! "
                             << "Index (" << i << ", " << j
                             << ") is out of the matrix of size (" << this->n[0]
                             << ", " << this->n[1] << ")");
     return *(this->values + i + j * this->n[0]);
   }
 
   /* ------------------------------------------------------------------------ */
   inline T & operator()(UInt i, UInt j) { return this->at(i, j); }
   inline const T & operator()(UInt i, UInt j) const { return this->at(i, j); }
 
   /// give a line vector wrapped on the column i
   inline VectorProxy<T> operator()(UInt j) {
     AKANTU_DEBUG_ASSERT(j < this->n[1],
                         "Access out of the matrix! "
                             << "You are trying to access the column vector "
                             << j << " in a matrix of size (" << this->n[0]
                             << ", " << this->n[1] << ")");
     return VectorProxy<T>(this->values + j * this->n[0], this->n[0]);
   }
 
   inline const VectorProxy<T> operator()(UInt j) const {
     AKANTU_DEBUG_ASSERT(j < this->n[1],
                         "Access out of the matrix! "
                             << "You are trying to access the column vector "
                             << j << " in a matrix of size (" << this->n[0]
                             << ", " << this->n[1] << ")");
     return VectorProxy<T>(this->values + j * this->n[0], this->n[0]);
   }
 
   inline void block(const Matrix & block, UInt pos_i, UInt pos_j) {
     AKANTU_DEBUG_ASSERT(pos_i + block.rows() <= rows(),
                         "The block size or position are not correct");
     AKANTU_DEBUG_ASSERT(pos_i + block.cols() <= cols(),
                         "The block size or position are not correct");
     for (UInt i = 0; i < block.rows(); ++i)
       for (UInt j = 0; j < block.cols(); ++j)
         this->at(i + pos_i, j + pos_j) = block(i, j);
   }
 
   inline Matrix block(UInt pos_i, UInt pos_j, UInt block_rows,
                       UInt block_cols) const {
     AKANTU_DEBUG_ASSERT(pos_i + block_rows <= rows(),
                         "The block size or position are not correct");
     AKANTU_DEBUG_ASSERT(pos_i + block_cols <= cols(),
                         "The block size or position are not correct");
     Matrix block(block_rows, block_cols);
     for (UInt i = 0; i < block_rows; ++i)
       for (UInt j = 0; j < block_cols; ++j)
         block(i, j) = this->at(i + pos_i, j + pos_j);
     return block;
   }
 
   inline T & operator[](UInt idx) { return *(this->values + idx); };
   inline const T & operator[](UInt idx) const { return *(this->values + idx); };
 
   /* ---------------------------------------------------------------------- */
   inline Matrix operator*(const Matrix & B) {
     Matrix C(this->rows(), B.cols());
     C.mul<false, false>(*this, B);
     return C;
   }
 
   /* ----------------------------------------------------------------------- */
   inline Matrix & operator*=(const T & x) { return parent::operator*=(x); }
 
   inline Matrix & operator*=(const Matrix & B) {
     Matrix C(*this);
     this->mul<false, false>(C, B);
     return *this;
   }
 
   /* ---------------------------------------------------------------------- */
   template <bool tr_A, bool tr_B>
   inline void mul(const Matrix & A, const Matrix & B, T alpha = 1.0) {
     UInt k = A.cols();
     if (tr_A)
       k = A.rows();
 
 #ifndef AKANTU_NDEBUG
     if (tr_B) {
       AKANTU_DEBUG_ASSERT(k == B.cols(),
                           "matrices to multiply have no fit dimensions");
       AKANTU_DEBUG_ASSERT(this->cols() == B.rows(),
                           "matrices to multiply have no fit dimensions");
     } else {
       AKANTU_DEBUG_ASSERT(k == B.rows(),
                           "matrices to multiply have no fit dimensions");
       AKANTU_DEBUG_ASSERT(this->cols() == B.cols(),
                           "matrices to multiply have no fit dimensions");
     }
     if (tr_A) {
       AKANTU_DEBUG_ASSERT(this->rows() == A.cols(),
                           "matrices to multiply have no fit dimensions");
     } else {
       AKANTU_DEBUG_ASSERT(this->rows() == A.rows(),
                           "matrices to multiply have no fit dimensions");
     }
 #endif // AKANTU_NDEBUG
 
     Math::matMul<tr_A, tr_B>(this->rows(), this->cols(), k, alpha, A.storage(),
                              B.storage(), 0., this->storage());
   }
 
   /* ---------------------------------------------------------------------- */
   inline void outerProduct(const Vector<T> & A, const Vector<T> & B) {
     AKANTU_DEBUG_ASSERT(
         A.size() == this->rows() && B.size() == this->cols(),
         "A and B are not compatible with the size of the matrix");
     for (UInt i = 0; i < this->rows(); ++i) {
       for (UInt j = 0; j < this->cols(); ++j) {
         this->values[i + j * this->rows()] += A[i] * B[j];
       }
     }
   }
 
 private:
   class EigenSorter {
   public:
     EigenSorter(const Vector<T> & eigs) : eigs(eigs) {}
 
     bool operator()(const UInt & a, const UInt & b) const {
       return (eigs(a) > eigs(b));
     }
 
   private:
     const Vector<T> & eigs;
   };
 
 public:
   /* ---------------------------------------------------------------------- */
   inline void eig(Vector<T> & eigenvalues, Matrix<T> & eigenvectors) const {
     AKANTU_DEBUG_ASSERT(this->cols() == this->rows(),
                         "eig is not a valid operation on a rectangular matrix");
     AKANTU_DEBUG_ASSERT(eigenvalues.size() == this->cols(),
                         "eigenvalues should be of size " << this->cols()
                                                          << ".");
 #ifndef AKANTU_NDEBUG
     if (eigenvectors.storage() != nullptr)
       AKANTU_DEBUG_ASSERT((eigenvectors.rows() == eigenvectors.cols()) &&
                               (eigenvectors.rows() == this->cols()),
                           "Eigenvectors needs to be a square matrix of size "
                               << this->cols() << " x " << this->cols() << ".");
 #endif
 
     Matrix<T> tmp = *this;
     Vector<T> tmp_eigs(eigenvalues.size());
     Matrix<T> tmp_eig_vects(eigenvectors.rows(), eigenvectors.cols());
 
     if (tmp_eig_vects.rows() == 0 || tmp_eig_vects.cols() == 0)
       Math::matrixEig(tmp.cols(), tmp.storage(), tmp_eigs.storage());
     else
       Math::matrixEig(tmp.cols(), tmp.storage(), tmp_eigs.storage(),
                       tmp_eig_vects.storage());
 
     Vector<UInt> perm(eigenvalues.size());
     for (UInt i = 0; i < perm.size(); ++i)
       perm(i) = i;
 
     std::sort(perm.storage(), perm.storage() + perm.size(),
               EigenSorter(tmp_eigs));
 
     for (UInt i = 0; i < perm.size(); ++i)
       eigenvalues(i) = tmp_eigs(perm(i));
 
     if (tmp_eig_vects.rows() != 0 && tmp_eig_vects.cols() != 0)
       for (UInt i = 0; i < perm.size(); ++i) {
         for (UInt j = 0; j < eigenvectors.rows(); ++j) {
           eigenvectors(j, i) = tmp_eig_vects(j, perm(i));
         }
       }
   }
 
   /* ---------------------------------------------------------------------- */
   inline void eig(Vector<T> & eigenvalues) const {
     Matrix<T> empty;
     eig(eigenvalues, empty);
   }
 
   /* ---------------------------------------------------------------------- */
   inline void eye(T alpha = 1.) {
     AKANTU_DEBUG_ASSERT(this->cols() == this->rows(),
                         "eye is not a valid operation on a rectangular matrix");
     this->clear();
     for (UInt i = 0; i < this->cols(); ++i) {
       this->values[i + i * this->rows()] = alpha;
     }
   }
 
   /* ---------------------------------------------------------------------- */
   static inline Matrix<T> eye(UInt m, T alpha = 1.) {
     Matrix<T> tmp(m, m);
     tmp.eye(alpha);
     return tmp;
   }
 
   /* ---------------------------------------------------------------------- */
   inline T trace() const {
     AKANTU_DEBUG_ASSERT(
         this->cols() == this->rows(),
         "trace is not a valid operation on a rectangular matrix");
     T trace = 0.;
     for (UInt i = 0; i < this->rows(); ++i) {
       trace += this->values[i + i * this->rows()];
     }
     return trace;
   }
 
   /* ---------------------------------------------------------------------- */
   inline Matrix transpose() const {
     Matrix tmp(this->cols(), this->rows());
     for (UInt i = 0; i < this->rows(); ++i) {
       for (UInt j = 0; j < this->cols(); ++j) {
         tmp(j, i) = operator()(i, j);
       }
     }
     return tmp;
   }
 
   /* ---------------------------------------------------------------------- */
   inline void inverse(const Matrix & A) {
     AKANTU_DEBUG_ASSERT(A.cols() == A.rows(),
                         "inv is not a valid operation on a rectangular matrix");
     AKANTU_DEBUG_ASSERT(this->cols() == A.cols(),
                         "the matrix should have the same size as its inverse");
 
     if (this->cols() == 1)
       *this->values = 1. / *A.storage();
     else if (this->cols() == 2)
       Math::inv2(A.storage(), this->values);
     else if (this->cols() == 3)
       Math::inv3(A.storage(), this->values);
     else
       Math::inv(this->cols(), A.storage(), this->values);
   }
 
   inline Matrix inverse() {
     Matrix inv(this->rows(), this->cols());
     inv.inverse(*this);
     return inv;
   }
 
   /* --------------------------------------------------------------------- */
   inline T det() const {
     AKANTU_DEBUG_ASSERT(this->cols() == this->rows(),
                         "inv is not a valid operation on a rectangular matrix");
     if (this->cols() == 1)
       return *(this->values);
     else if (this->cols() == 2)
       return Math::det2(this->values);
     else if (this->cols() == 3)
       return Math::det3(this->values);
     else
       return Math::det(this->cols(), this->values);
   }
 
   /* --------------------------------------------------------------------- */
   inline T doubleDot(const Matrix<T> & other) const {
     AKANTU_DEBUG_ASSERT(
         this->cols() == this->rows(),
         "doubleDot is not a valid operation on a rectangular matrix");
     if (this->cols() == 1)
       return *(this->values) * *(other.storage());
     else if (this->cols() == 2)
       return Math::matrixDoubleDot22(this->values, other.storage());
     else if (this->cols() == 3)
       return Math::matrixDoubleDot33(this->values, other.storage());
     else
       AKANTU_ERROR("doubleDot is not defined for other spatial dimensions"
                    << " than 1, 2 or 3.");
     return T();
   }
 
   /* ---------------------------------------------------------------------- */
   /// function to print the containt of the class
   virtual void printself(std::ostream & stream, int indent = 0) const {
     std::string space;
     for (Int i = 0; i < indent; i++, space += AKANTU_INDENT)
       ;
 
     stream << "[";
     for (UInt i = 0; i < this->n[0]; ++i) {
       if (i != 0)
         stream << ", ";
       stream << "[";
       for (UInt j = 0; j < this->n[1]; ++j) {
         if (j != 0)
           stream << ", ";
         stream << operator()(i, j);
       }
       stream << "]";
     }
     stream << "]";
   };
 };
 
 /* ------------------------------------------------------------------------ */
 template <typename T>
 template <bool tr_A>
 inline void Vector<T>::mul(const Matrix<T> & A, const Vector<T> & x,
                            Real alpha) {
 #ifndef AKANTU_NDEBUG
   UInt n = x.size();
   if (tr_A) {
     AKANTU_DEBUG_ASSERT(n == A.rows(),
                         "matrix and vector to multiply have no fit dimensions");
     AKANTU_DEBUG_ASSERT(this->size() == A.cols(),
                         "matrix and vector to multiply have no fit dimensions");
   } else {
     AKANTU_DEBUG_ASSERT(n == A.cols(),
                         "matrix and vector to multiply have no fit dimensions");
     AKANTU_DEBUG_ASSERT(this->size() == A.rows(),
                         "matrix and vector to multiply have no fit dimensions");
   }
 #endif
   Math::matVectMul<tr_A>(A.rows(), A.cols(), alpha, A.storage(), x.storage(),
                          0., this->storage());
 }
 
 /* -------------------------------------------------------------------------- */
 template <typename T>
 inline std::ostream & operator<<(std::ostream & stream,
                                  const Matrix<T> & _this) {
   _this.printself(stream);
   return stream;
 }
 
 /* -------------------------------------------------------------------------- */
 template <typename T>
 inline std::ostream & operator<<(std::ostream & stream,
                                  const Vector<T> & _this) {
   _this.printself(stream);
   return stream;
 }
 
 /* ------------------------------------------------------------------------ */
 /* Tensor3                                                                  */
 /* ------------------------------------------------------------------------ */
 template <typename T> class Tensor3 : public TensorStorage<T, 3, Tensor3<T>> {
   using parent = TensorStorage<T, 3, Tensor3<T>>;
 
 public:
   using value_type = typename parent::value_type;
   using proxy = Tensor3Proxy<T>;
 
 public:
   Tensor3() : parent(){};
 
   Tensor3(UInt m, UInt n, UInt p, const T & def = T()) : parent(m, n, p, def) {}
 
   Tensor3(T * data, UInt m, UInt n, UInt p) : parent(data, m, n, p) {}
 
   Tensor3(const Tensor3 & src, bool deep_copy = true)
       : parent(src, deep_copy) {}
 
   Tensor3(const proxy & src) : parent(src) {}
 
 public:
   /* ------------------------------------------------------------------------ */
   inline Tensor3 & operator=(const Tensor3 & src) {
     parent::operator=(src);
     return *this;
   }
 
   /* ---------------------------------------------------------------------- */
   inline T & operator()(UInt i, UInt j, UInt k) {
     AKANTU_DEBUG_ASSERT(
         (i < this->n[0]) && (j < this->n[1]) && (k < this->n[2]),
         "Access out of the tensor3! "
             << "You are trying to access the element "
             << "(" << i << ", " << j << ", " << k << ") in a tensor of size ("
             << this->n[0] << ", " << this->n[1] << ", " << this->n[2] << ")");
     return *(this->values + (k * this->n[0] + i) * this->n[1] + j);
   }
 
   inline const T & operator()(UInt i, UInt j, UInt k) const {
     AKANTU_DEBUG_ASSERT(
         (i < this->n[0]) && (j < this->n[1]) && (k < this->n[2]),
         "Access out of the tensor3! "
             << "You are trying to access the element "
             << "(" << i << ", " << j << ", " << k << ") in a tensor of size ("
             << this->n[0] << ", " << this->n[1] << ", " << this->n[2] << ")");
     return *(this->values + (k * this->n[0] + i) * this->n[1] + j);
   }
 
   inline MatrixProxy<T> operator()(UInt k) {
     AKANTU_DEBUG_ASSERT((k < this->n[2]),
                         "Access out of the tensor3! "
                             << "You are trying to access the slice " << k
                             << " in a tensor3 of size (" << this->n[0] << ", "
                             << this->n[1] << ", " << this->n[2] << ")");
     return MatrixProxy<T>(this->values + k * this->n[0] * this->n[1],
                           this->n[0], this->n[1]);
   }
 
   inline const MatrixProxy<T> operator()(UInt k) const {
     AKANTU_DEBUG_ASSERT((k < this->n[2]),
                         "Access out of the tensor3! "
                             << "You are trying to access the slice " << k
                             << " in a tensor3 of size (" << this->n[0] << ", "
                             << this->n[1] << ", " << this->n[2] << ")");
     return MatrixProxy<T>(this->values + k * this->n[0] * this->n[1],
                           this->n[0], this->n[1]);
   }
 
   inline MatrixProxy<T> operator[](UInt k) {
     return MatrixProxy<T>(this->values + k * this->n[0] * this->n[1],
                           this->n[0], this->n[1]);
   }
 
   inline const MatrixProxy<T> operator[](UInt k) const {
     return MatrixProxy<T>(this->values + k * this->n[0] * this->n[1],
                           this->n[0], this->n[1]);
   }
 };
 
 /* -------------------------------------------------------------------------- */
 // support operations for the creation of other vectors
 /* -------------------------------------------------------------------------- */
 template <typename T>
 Vector<T> operator*(const T & scalar, const Vector<T> & a) {
   Vector<T> r(a);
   r *= scalar;
   return r;
 }
 
 template <typename T>
 Vector<T> operator*(const Vector<T> & a, const T & scalar) {
   Vector<T> r(a);
   r *= scalar;
   return r;
 }
 
 template <typename T>
 Vector<T> operator/(const Vector<T> & a, const T & scalar) {
   Vector<T> r(a);
   r /= scalar;
   return r;
 }
 
 template <typename T>
 Vector<T> operator*(const Vector<T> & a, const Vector<T> & b) {
   Vector<T> r(a);
   r *= b;
   return r;
 }
 
 template <typename T>
 Vector<T> operator+(const Vector<T> & a, const Vector<T> & b) {
   Vector<T> r(a);
   r += b;
   return r;
 }
 
 template <typename T>
 Vector<T> operator-(const Vector<T> & a, const Vector<T> & b) {
   Vector<T> r(a);
   r -= b;
   return r;
 }
 
 template <typename T>
 Vector<T> operator*(const Matrix<T> & A, const Vector<T> & b) {
   Vector<T> r(b.size());
   r.template mul<false>(A, b);
   return r;
 }
 
 /* -------------------------------------------------------------------------- */
 template <typename T>
 Matrix<T> operator*(const T & scalar, const Matrix<T> & a) {
   Matrix<T> r(a);
   r *= scalar;
   return r;
 }
 
 template <typename T>
 Matrix<T> operator*(const Matrix<T> & a, const T & scalar) {
   Matrix<T> r(a);
   r *= scalar;
   return r;
 }
 
 template <typename T>
 Matrix<T> operator/(const Matrix<T> & a, const T & scalar) {
   Matrix<T> r(a);
   r /= scalar;
   return r;
 }
 
 template <typename T>
 Matrix<T> operator+(const Matrix<T> & a, const Matrix<T> & b) {
   Matrix<T> r(a);
   r += b;
   return r;
 }
 
 template <typename T>
 Matrix<T> operator-(const Matrix<T> & a, const Matrix<T> & b) {
   Matrix<T> r(a);
   r -= b;
   return r;
 }
 
 } // namespace akantu
 
 #endif /* __AKANTU_AKA_TYPES_HH__ */
diff --git a/src/common/aka_visitor.hh b/src/common/aka_visitor.hh
index b16fe120e..ad43690ff 100644
--- a/src/common/aka_visitor.hh
+++ b/src/common/aka_visitor.hh
@@ -1,164 +1,164 @@
 /**
  * @file   aka_visitor.hh
  *
  * @author Alejandro M. Aragón <alejandro.aragon@epfl.ch>
  *
  * @date creation: Fri Jan 04 2013
- * @date last modification: Sun Oct 19 2014
+ * @date last modification: Mon Jun 19 2017
  *
  * @brief  Objects that support the visitor design pattern
  *
  * @section LICENSE
  *
- * Copyright  (©)  2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de Lausanne)
+ * 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
+ * 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
+ * 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_VISITOR_HH__
 #define __AKANTU_VISITOR_HH__
 
 #include "aka_typelist.hh"
 
 namespace akantu {
 
 ///////////////////////////////////////////////////////////////////////////
 // visitor class template, adapted from the Andrei Alexandrescu's
 // "Modern C++ Design"
 
 enum Visit_type { Mutable, Immutable };
 
 template <class T, typename R = void, Visit_type = Mutable> class StrictVisitor;
 
 template <class T, typename R> class StrictVisitor<T, R, Mutable> {
 public:
   typedef R ReturnType;
   typedef T ParamType;
   virtual ~StrictVisitor() {}
   virtual ReturnType Visit(ParamType &) = 0;
 };
 
 template <class T, typename R> class StrictVisitor<T, R, Immutable> {
 public:
   typedef R ReturnType;
   typedef const T ParamType;
   virtual ~StrictVisitor() {}
   virtual ReturnType Visit(ParamType &) = 0;
 };
 
 /// class template StrictVisitor (specialization)
 
 template <class Head, class Tail, typename R>
 class StrictVisitor<Typelist<Head, Tail>, R, Mutable>
     : public StrictVisitor<Head, R, Mutable>,
       public StrictVisitor<Tail, R, Mutable> {
 public:
   typedef R ReturnType;
   typedef Head ParamType;
   //	using StrictVisitor<Head, R>::Visit;
   //	using StrictVisitor<Tail, R>::Visit;
 };
 
 template <class Head, typename R>
 class StrictVisitor<Typelist<Head, Null_type>, R, Mutable>
     : public StrictVisitor<Head, R, Mutable> {
 public:
   typedef R ReturnType;
   typedef Head ParamType;
   using StrictVisitor<Head, R, Mutable>::Visit;
 };
 
 template <class Head, class Tail, typename R>
 class StrictVisitor<Typelist<Head, Tail>, R, Immutable>
     : public StrictVisitor<Head, R, Immutable>,
       public StrictVisitor<Tail, R, Immutable> {
 public:
   typedef R ReturnType;
   typedef Head ParamType;
   //	using StrictVisitor<Head, R>::Visit;
   //	using StrictVisitor<Tail, R>::Visit;
 };
 
 template <class Head, typename R>
 class StrictVisitor<Typelist<Head, Null_type>, R, Immutable>
     : public StrictVisitor<Head, R, Immutable> {
 public:
   typedef R ReturnType;
   typedef Head ParamType;
   using StrictVisitor<Head, R, Immutable>::Visit;
 };
 
 ////////////////////////////////////////////////////////////////////////////////
 // class template NonStrictVisitor
 // Implements non-strict visitation (you can implement only part of the Visit
 //     functions)
 //
 
 template <class R> struct DefaultFunctor {
   template <class T> R operator()(T &) { return R(); }
 };
 
 template <class T, typename R = void, Visit_type V = Mutable,
           class F = DefaultFunctor<R>>
 class BaseVisitorImpl;
 
 template <class Head, class Tail, typename R, Visit_type V, class F>
 class BaseVisitorImpl<Typelist<Head, Tail>, R, V, F>
     : public StrictVisitor<Head, R, V>, public BaseVisitorImpl<Tail, R, V, F> {
 public:
   typedef typename StrictVisitor<Head, R, V>::ParamType ParamType;
   virtual R Visit(ParamType & h) { return F()(h); }
 };
 
 template <class Head, typename R, Visit_type V, class F>
 class BaseVisitorImpl<Typelist<Head, Null_type>, R, V, F>
     : public StrictVisitor<Head, R, V> {
 public:
   typedef typename StrictVisitor<Head, R, V>::ParamType ParamType;
   virtual R Visit(ParamType & h) { return F()(h); }
 };
 
 /// Visitor
 template <class R> struct Strict {};
 
 template <typename R, class TList, Visit_type V = Mutable,
           template <class> class FunctorPolicy = DefaultFunctor>
 class Visitor : public BaseVisitorImpl<TList, R, V, FunctorPolicy<R>> {
 public:
   typedef R ReturnType;
 
   template <class Visited> ReturnType GenericVisit(Visited & host) {
     StrictVisitor<Visited, ReturnType, V> & subObj = *this;
     return subObj.Visit(host);
   }
 };
 
 template <typename R, class TList, Visit_type V>
 class Visitor<R, TList, V, Strict> : public StrictVisitor<TList, R, V> {
 public:
   typedef R ReturnType;
 
   template <class Visited> ReturnType GenericVisit(Visited & host) {
     StrictVisitor<Visited, ReturnType, V> & subObj = *this;
     return subObj.Visit(host);
   }
 };
 
 } // akantu
 
 #endif /* __AKANTU_VISITOR_HH__ */
diff --git a/src/common/aka_voigthelper.cc b/src/common/aka_voigthelper.cc
index 13bdbbb3b..ddf66d62e 100644
--- a/src/common/aka_voigthelper.cc
+++ b/src/common/aka_voigthelper.cc
@@ -1,68 +1,68 @@
 /**
  * @file   aka_voigthelper.cc
  *
  * @author Lucas Frerot <lucas.frerot@epfl.ch>
  * @author Till Junge <till.junge@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Fri Dec 20 2013
- * @date last modification: Sun Oct 19 2014
+ * @date last modification: Mon Jun 19 2017
  *
  * @brief  Voigt indices
  *
  * @section LICENSE
  *
- * Copyright  (©)  2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de Lausanne)
+ * 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
+ * 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
+ * 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_voigthelper.hh"
 #include "aka_common.hh"
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 /* clang-format off */
 template <> const UInt VoigtHelper<1>::mat[][1] = {{0}};
 template <> const UInt VoigtHelper<2>::mat[][2] = {{0, 2},
                                                    {3, 1}};
 template <> const UInt VoigtHelper<3>::mat[][3] = {{0, 5, 4},
                                                    {8, 1, 3},
                                                    {7, 6, 2}};
 template <> const UInt VoigtHelper<1>::vec[][2] = {{0, 0}};
 template <> const UInt VoigtHelper<2>::vec[][2] = {{0, 0},
                                                    {1, 1},
                                                    {0, 1},
                                                    {1, 0}};
 template <> const UInt VoigtHelper<3>::vec[][2] = {{0, 0},
                                                    {1, 1},
                                                    {2, 2},
                                                    {1, 2},
                                                    {0, 2},
                                                    {0, 1},
                                                    {2, 1},
                                                    {2, 0},
                                                    {1, 0}};
 template <> const Real VoigtHelper<1>::factors[] = {1.};
 template <> const Real VoigtHelper<2>::factors[] = {1., 1., 2.};
 template <> const Real VoigtHelper<3>::factors[] = {1., 1., 1.,
                                                     2., 2., 2.};
 
 /* clang-format on */
 } // akantu
diff --git a/src/common/aka_voigthelper.hh b/src/common/aka_voigthelper.hh
index 25a0cd79b..ac3dfd893 100644
--- a/src/common/aka_voigthelper.hh
+++ b/src/common/aka_voigthelper.hh
@@ -1,79 +1,79 @@
-
 /**
  * @file   aka_voigthelper.hh
  *
+ * @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
  * @author Lucas Frerot <lucas.frerot@epfl.ch>
  * @author Till Junge <till.junge@epfl.ch>
  * @author Daniel Pino Muñoz <daniel.pinomunoz@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Fri Dec 20 2013
- * @date last modification: Fri Jan 22 2016
+ * @date last modification: Mon Jan 29 2018
  *
  * @brief  Helper file for Voigt notation
  *
  * @section LICENSE
  *
- * Copyright  (©)  2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de Lausanne)
+ * 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
+ * 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
+ * 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 __AKA_VOIGTHELPER_HH__
 #define __AKA_VOIGTHELPER_HH__
 
 #include "aka_common.hh"
 #include "aka_types.hh"
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 template <UInt dim> class VoigtHelper {
   static_assert(dim != 0, "Cannot be 0D");
 
 public:
   /// transfer the B matrix to a Voigt notation B matrix
   inline static void transferBMatrixToSymVoigtBMatrix(
       const Matrix<Real> & B, Matrix<Real> & Bvoigt, UInt nb_nodes_per_element);
 
   /// transfer the BNL matrix to a Voigt notation B matrix (See Bathe et al.
   /// IJNME vol 9, 1975)
   inline static void transferBMatrixToBNL(const Matrix<Real> & B,
                                           Matrix<Real> & Bvoigt,
                                           UInt nb_nodes_per_element);
 
   /// transfer the BL2 matrix to a Voigt notation B matrix (See Bathe et al.
   /// IJNME vol 9, 1975)
   inline static void transferBMatrixToBL2(const Matrix<Real> & B,
                                           const Matrix<Real> & grad_u,
                                           Matrix<Real> & Bvoigt,
                                           UInt nb_nodes_per_element);
 
 public:
   static constexpr UInt size{(dim * (dim - 1)) / 2 + dim};
   // matrix of vector index I as function of tensor indices i,j
   static const UInt mat[dim][dim];
   // array of matrix indices ij as function of vector index I
   static const UInt vec[dim * dim][2];
   // factors to multiply the strain by for voigt notation
   static const Real factors[size];
 };
 
 } // akantu
 
 #include "aka_voigthelper_tmpl.hh"
 
 #endif
diff --git a/src/common/aka_voigthelper_tmpl.hh b/src/common/aka_voigthelper_tmpl.hh
index 1c7cec16d..0582da0b8 100644
--- a/src/common/aka_voigthelper_tmpl.hh
+++ b/src/common/aka_voigthelper_tmpl.hh
@@ -1,149 +1,179 @@
+/**
+ * @file   aka_voigthelper_tmpl.hh
+ *
+ * @author Nicolas Richart <nicolas.richart@epfl.ch>
+ *
+ * @date creation: Fri Dec 20 2013
+ * @date last modification: Wed Dec 06 2017
+ *
+ * @brief  implementation of the voight helper
+ *
+ * @section LICENSE
+ *
+ * Copyright (©) 2014-2018 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ *
+ * Akantu is free  software: you can redistribute it and/or  modify it under the
+ * terms  of the  GNU Lesser  General Public  License as published by  the Free
+ * Software Foundation, either version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * Akantu is  distributed in the  hope that it  will be useful, but  WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
+ * details.
+ *
+ * You should  have received  a copy  of the GNU  Lesser General  Public License
+ * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
 /**
  * @file   aka_voigthelper_tmpl.hh
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  * @date   Wed Nov 16 12:22:58 2016
  */
 
 /* -------------------------------------------------------------------------- */
 #include "aka_voigthelper.hh"
 /* -------------------------------------------------------------------------- */
 
 #ifndef __AKANTU_AKA_VOIGTHELPER_TMPL_HH__
 #define __AKANTU_AKA_VOIGTHELPER_TMPL_HH__
 
 namespace akantu {
 
 template <UInt dim> constexpr UInt VoigtHelper<dim>::size;
 
 /* -------------------------------------------------------------------------- */
 template <UInt dim>
 inline void VoigtHelper<dim>::transferBMatrixToSymVoigtBMatrix(
     const Matrix<Real> & B, Matrix<Real> & Bvoigt, UInt nb_nodes_per_element) {
   Bvoigt.clear();
 
   for (UInt i = 0; i < dim; ++i)
     for (UInt n = 0; n < nb_nodes_per_element; ++n)
       Bvoigt(i, i + n * dim) = B(i, n);
 
   if (dim == 2) {
     /// in 2D, fill the @f$ [\frac{\partial N_i}{\partial x}, \frac{\partial
     /// N_i}{\partial y}]@f$ row
     for (UInt n = 0; n < nb_nodes_per_element; ++n) {
       Bvoigt(2, 1 + n * 2) = B(0, n);
       Bvoigt(2, 0 + n * 2) = B(1, n);
     }
   }
 
   if (dim == 3) {
     for (UInt n = 0; n < nb_nodes_per_element; ++n) {
       Real dndx = B(0, n);
       Real dndy = B(1, n);
       Real dndz = B(2, n);
 
       /// in 3D, fill the @f$ [0, \frac{\partial N_i}{\partial y},
       /// \frac{N_i}{\partial z}]@f$ row
       Bvoigt(3, 1 + n * 3) = dndz;
       Bvoigt(3, 2 + n * 3) = dndy;
 
       /// in 3D, fill the @f$ [\frac{\partial N_i}{\partial x}, 0,
       /// \frac{N_i}{\partial z}]@f$ row
       Bvoigt(4, 0 + n * 3) = dndz;
       Bvoigt(4, 2 + n * 3) = dndx;
 
       /// in 3D, fill the @f$ [\frac{\partial N_i}{\partial x},
       /// \frac{N_i}{\partial y}, 0]@f$ row
       Bvoigt(5, 0 + n * 3) = dndy;
       Bvoigt(5, 1 + n * 3) = dndx;
     }
   }
 }
 
 /* -------------------------------------------------------------------------- */
 template <UInt dim>
 inline void VoigtHelper<dim>::transferBMatrixToBNL(const Matrix<Real> & B,
                                                    Matrix<Real> & Bvoigt,
                                                    UInt nb_nodes_per_element) {
   Bvoigt.clear();
 
   // see Finite element formulations for large deformation dynamic analysis,
   // Bathe et al. IJNME vol 9, 1975, page 364 B_{NL}
   for (UInt i = 0; i < dim; ++i) {
     for (UInt m = 0; m < nb_nodes_per_element; ++m) {
       for (UInt n = 0; n < dim; ++n) {
         // std::cout << B(n, m) << std::endl;
         Bvoigt(i * dim + n, m * dim + i) = B(n, m);
       }
     }
   }
   // TODO: Verify the 2D and 1D case
 }
 
 /* -------------------------------------------------------------------------- */
 template <>
 inline void VoigtHelper<1>::transferBMatrixToBL2(const Matrix<Real> & B,
                                                  const Matrix<Real> & grad_u,
                                                  Matrix<Real> & Bvoigt,
                                                  UInt nb_nodes_per_element) {
   Bvoigt.clear();
   for (UInt j = 0; j < nb_nodes_per_element; ++j)
     for (UInt k = 0; k < 2; ++k)
       Bvoigt(0, j * 2 + k) = grad_u(k, 0) * B(0, j);
 }
 
 /* -------------------------------------------------------------------------- */
 template <>
 inline void VoigtHelper<3>::transferBMatrixToBL2(const Matrix<Real> & B,
                                                  const Matrix<Real> & grad_u,
                                                  Matrix<Real> & Bvoigt,
                                                  UInt nb_nodes_per_element) {
   Bvoigt.clear();
 
   for (UInt i = 0; i < 3; ++i)
     for (UInt j = 0; j < nb_nodes_per_element; ++j)
       for (UInt k = 0; k < 3; ++k)
         Bvoigt(i, j * 3 + k) = grad_u(k, i) * B(i, j);
 
   for (UInt i = 3; i < 6; ++i) {
     for (UInt j = 0; j < nb_nodes_per_element; ++j) {
       for (UInt k = 0; k < 3; ++k) {
         UInt aux = i - 3;
         for (UInt m = 0; m < 3; ++m) {
           if (m != aux) {
             UInt index1 = m;
             UInt index2 = 3 - m - aux;
             Bvoigt(i, j * 3 + k) += grad_u(k, index1) * B(index2, j);
           }
         }
       }
     }
   }
 }
 
 /* -------------------------------------------------------------------------- */
 template <>
 inline void VoigtHelper<2>::transferBMatrixToBL2(const Matrix<Real> & B,
                                                  const Matrix<Real> & grad_u,
                                                  Matrix<Real> & Bvoigt,
                                                  UInt nb_nodes_per_element) {
 
   Bvoigt.clear();
 
   for (UInt i = 0; i < 2; ++i)
     for (UInt j = 0; j < nb_nodes_per_element; ++j)
       for (UInt k = 0; k < 2; ++k)
         Bvoigt(i, j * 2 + k) = grad_u(k, i) * B(i, j);
 
   for (UInt j = 0; j < nb_nodes_per_element; ++j) {
     for (UInt k = 0; k < 2; ++k) {
       for (UInt m = 0; m < 2; ++m) {
         UInt index1 = m;
         UInt index2 = (2 - 1) - m;
         Bvoigt(2, j * 2 + k) += grad_u(k, index1) * B(index2, j);
       }
     }
   }
 }
 
 } // akantu
 
 #endif /* __AKANTU_AKA_VOIGTHELPER_TMPL_HH__ */
diff --git a/src/common/aka_warning.hh b/src/common/aka_warning.hh
index 21db7d188..13dd7c52e 100644
--- a/src/common/aka_warning.hh
+++ b/src/common/aka_warning.hh
@@ -1,25 +1,55 @@
+/**
+ * @file   aka_warning.hh
+ *
+ * @author Nicolas Richart <nicolas.richart@epfl.ch>
+ *
+ * @date creation: Mon Nov 14 2016
+ * @date last modification: Fri Dec 02 2016
+ *
+ * @brief  file to include to remove some warnings
+ *
+ * @section LICENSE
+ *
+ * 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/>.
+ *
+ */
+
 // Intel warnings
 #if defined(__INTEL_COMPILER)
 
 #if defined(AKANTU_WARNING_IGNORE_UNUSED_PARAMETER)
 #endif
 
 // Clang Warnings
 #elif defined(__clang__) // test clang to be sure that when we test for gnu it
-                         // is only gnu
+// is only gnu
 #pragma clang diagnostic push
 #if defined(AKANTU_WARNING_IGNORE_UNUSED_PARAMETER)
 #pragma clang diagnostic ignored "-Wunused-parameter"
 #endif
 
 // GCC warnings
 #elif (defined(__GNUC__) || defined(__GNUG__))
 #define GCC_VERSION                                                            \
   (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__)
 #if GCC_VERSION > 40600
 #pragma GCC diagnostic push
 #endif
 #if defined(AKANTU_WARNING_IGNORE_UNUSED_PARAMETER)
 #pragma GCC diagnostic ignored "-Wunused-parameter"
 #endif
 #endif
diff --git a/src/common/aka_warning_restore.hh b/src/common/aka_warning_restore.hh
index 6f123debb..0d142a18f 100644
--- a/src/common/aka_warning_restore.hh
+++ b/src/common/aka_warning_restore.hh
@@ -1,16 +1,46 @@
+/**
+ * @file   aka_warning_restore.hh
+ *
+ * @author Nicolas Richart <nicolas.richart@epfl.ch>
+ *
+ * @date creation: Mon Nov 14 2016
+ * @date last modification: Fri Dec 02 2016
+ *
+ * @brief  file to include to reactivate the previously deactivatied warnings
+ *
+ * @section LICENSE
+ *
+ * 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/>.
+ *
+ */
+
 #if defined(__INTEL_COMPILER)
 //#pragma warning ( disable : 383 )
 #elif defined(__clang__) // test clang to be sure that when we test for gnu it
-                         // is only gnu
+// is only gnu
 #pragma clang diagnostic pop
 #elif defined(__GNUG__)
 #if GCC_VERSION > 40600
 #pragma GCC diagnostic pop
 #else
 #if defined(AKANTU_WARNING_IGNORE_UNUSED_PARAMETER)
 #pragma GCC diagnostic warning "-Wunused-parameter"
 #endif
 #endif
 #endif
 
 #undef AKANTU_WARNING_IGNORE_UNUSED_PARAMETER
diff --git a/src/fe_engine/cohesive_element.hh b/src/fe_engine/cohesive_element.hh
index e6ab33817..143bf3fe9 100644
--- a/src/fe_engine/cohesive_element.hh
+++ b/src/fe_engine/cohesive_element.hh
@@ -1,91 +1,90 @@
 /**
  * @file   cohesive_element.hh
  *
  * @author Mauro Corrado <mauro.corrado@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  * @author Marco Vocialta <marco.vocialta@epfl.ch>
  *
  * @date creation: Fri Jun 18 2010
- * @date last modification: Thu Oct 22 2015
+ * @date last modification: Wed Oct 11 2017
  *
  * @brief  Generates the cohesive element structres (defined in
  * element_class.hh)
  *
  * @section LICENSE
  *
- * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
- * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
- * Solides)
+ * 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
+ * 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
+ * A PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 #include "element_class.hh"
 /* -------------------------------------------------------------------------- */
 
 #ifndef __AKANTU_COHESIVE_ELEMENT_HH__
 #define __AKANTU_COHESIVE_ELEMENT_HH__
 
 namespace akantu {
 
 AKANTU_DEFINE_ELEMENT_CLASS_PROPERTY(_cohesive_2d_4, _gt_cohesive_2d_4,
                                      _itp_lagrange_segment_2, _ek_cohesive, 2,
                                      _git_segment, 2);
 
 AKANTU_DEFINE_ELEMENT_CLASS_PROPERTY(_cohesive_2d_6, _gt_cohesive_2d_6,
                                      _itp_lagrange_segment_3, _ek_cohesive, 2,
                                      _git_segment, 3);
 
 AKANTU_DEFINE_ELEMENT_CLASS_PROPERTY(_cohesive_1d_2, _gt_cohesive_1d_2,
                                      _itp_lagrange_point_1, _ek_cohesive, 1,
                                      _git_point, 1);
 
 AKANTU_DEFINE_ELEMENT_CLASS_PROPERTY(_cohesive_3d_6, _gt_cohesive_3d_6,
                                      _itp_lagrange_triangle_3, _ek_cohesive, 3,
                                      _git_triangle, 2);
 
 AKANTU_DEFINE_ELEMENT_CLASS_PROPERTY(_cohesive_3d_12, _gt_cohesive_3d_12,
                                      _itp_lagrange_triangle_6, _ek_cohesive, 3,
                                      _git_triangle, 3);
 
 AKANTU_DEFINE_ELEMENT_CLASS_PROPERTY(_cohesive_3d_8, _gt_cohesive_3d_8,
                                      _itp_lagrange_quadrangle_4, _ek_cohesive,
                                      3, _git_segment, 2);
 
 AKANTU_DEFINE_ELEMENT_CLASS_PROPERTY(_cohesive_3d_16, _gt_cohesive_3d_16,
                                      _itp_serendip_quadrangle_8, _ek_cohesive,
                                      3, _git_segment, 3);
 
 template <ElementType> struct CohesiveFacetProperty {
   static const ElementType cohesive_type = _not_defined;
 };
 
 #define AKANTU_DEFINE_COHESIVE_FACET_PROPERTY(ftype, ctype)                    \
   template <> struct CohesiveFacetProperty<ftype> {                            \
     static const ElementType cohesive_type = ctype;                            \
   }
 
 AKANTU_DEFINE_COHESIVE_FACET_PROPERTY(_point_1, _cohesive_1d_2);
 AKANTU_DEFINE_COHESIVE_FACET_PROPERTY(_segment_2, _cohesive_2d_4);
 AKANTU_DEFINE_COHESIVE_FACET_PROPERTY(_segment_3, _cohesive_2d_6);
 AKANTU_DEFINE_COHESIVE_FACET_PROPERTY(_triangle_3, _cohesive_3d_6);
 AKANTU_DEFINE_COHESIVE_FACET_PROPERTY(_triangle_6, _cohesive_3d_12);
 AKANTU_DEFINE_COHESIVE_FACET_PROPERTY(_quadrangle_4, _cohesive_3d_8);
 AKANTU_DEFINE_COHESIVE_FACET_PROPERTY(_quadrangle_8, _cohesive_3d_16);
 
 } // namespace akantu
 
 #endif /* __AKANTU_COHESIVE_ELEMENT_HH__ */
diff --git a/src/fe_engine/element.hh b/src/fe_engine/element.hh
index fd5f4d668..02b8796a4 100644
--- a/src/fe_engine/element.hh
+++ b/src/fe_engine/element.hh
@@ -1,112 +1,113 @@
 /**
  * @file   element.hh
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Tue Sep 02 2014
- * @date last modification: Sat Jul 11 2015
+ * @date last modification: Tue Jan 23 2018
  *
  * @brief  Element helper class
  *
  * @section LICENSE
  *
- * Copyright  (©)  2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de Lausanne)
+ * 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
+ * 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
+ * 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"
 /* -------------------------------------------------------------------------- */
 
 #ifndef __AKANTU_ELEMENT_HH__
 #define __AKANTU_ELEMENT_HH__
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 /* Element                                                                    */
 /* -------------------------------------------------------------------------- */
 class Element {
 public:
   ElementType type;
   UInt element;
   GhostType ghost_type;
 
   // ElementKind kind;
   // ElementType type{_not_defined};
   // UInt element{0};
   // GhostType ghost_type{_not_ghost};
   // ElementKind kind{_ek_regular};
 
   /* ------------------------------------------------------------------------ */
   /* Methods                                                                  */
   /* ------------------------------------------------------------------------ */
 public:
   inline ElementKind kind() const;
 
   inline bool operator==(const Element & elem) const {
     return std::tie(type, element, ghost_type) ==
            std::tie(elem.type, elem.element, elem.ghost_type);
   }
 
   inline bool operator!=(const Element & elem) const {
     return std::tie(type, element, ghost_type) !=
            std::tie(elem.type, elem.element, elem.ghost_type);
   }
 
   // inline bool operator==(const Element & elem) const {
   //   return ((element == elem.element) && (type == elem.type) &&
   //           (ghost_type == elem.ghost_type) && (kind == elem.kind));
   // }
 
   // inline bool operator!=(const Element & elem) const {
   //   return ((element != elem.element) || (type != elem.type) ||
   //           (ghost_type != elem.ghost_type) || (kind != elem.kind));
   // }
 
   inline bool operator<(const Element & rhs) const;
 };
 
 /// standard output stream operator
 inline std::ostream & operator<<(std::ostream & stream, const Element & _this) {
   stream << "Element [" << _this.type << ", " << _this.element << ", "
          << _this.ghost_type << "]";
   return stream;
 }
 
 namespace {
   const Element ElementNull{_not_defined, UInt(-1), _casper};
   //      Element{_not_defined, 0, _casper, _ek_not_defined};
 }
 
 /* -------------------------------------------------------------------------- */
 inline bool Element::operator<(const Element & rhs) const {
   // bool res =
   //     (rhs == ElementNull) ||
   //     ((this->kind < rhs.kind) ||
   //      ((this->kind == rhs.kind) &&
   //       ((this->ghost_type < rhs.ghost_type) ||
   //        ((this->ghost_type == rhs.ghost_type) &&
   //         ((this->type < rhs.type) ||
   //          ((this->type == rhs.type) && (this->element < rhs.element)))))));
   return ((rhs == ElementNull) ||
           std::tie(ghost_type, type, element) <
               std::tie(rhs.ghost_type, rhs.type, rhs.element));
 }
 
 } // namespace akantu
 
 #endif /* __AKANTU_ELEMENT_HH__ */
diff --git a/src/fe_engine/element_class.hh b/src/fe_engine/element_class.hh
index fb89b5709..feddcdc69 100644
--- a/src/fe_engine/element_class.hh
+++ b/src/fe_engine/element_class.hh
@@ -1,401 +1,400 @@
 /**
  * @file   element_class.hh
  *
  * @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Fri Jun 18 2010
- * @date last modification: Thu Jan 21 2016
+ * @date last modification: Tue Feb 20 2018
  *
  * @brief  Declaration of the ElementClass main class and the
  * Integration and Interpolation elements
  *
  * @section LICENSE
  *
- * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
- * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
- * Solides)
+ * 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
+ * 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
+ * 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 "aka_types.hh"
 /* -------------------------------------------------------------------------- */
 
 #ifndef __AKANTU_ELEMENT_CLASS_HH__
 #define __AKANTU_ELEMENT_CLASS_HH__
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 /// default element class structure
 template <ElementType element_type> struct ElementClassProperty {
   static const GeometricalType geometrical_type{_gt_not_defined};
   static const InterpolationType interpolation_type{_itp_not_defined};
   static const ElementKind element_kind{_ek_regular};
   static const UInt spatial_dimension{0};
   static const GaussIntegrationType gauss_integration_type{_git_not_defined};
   static const UInt polynomial_degree{0};
 };
 
 /// Macro to generate the element class structures for different element types
 #define AKANTU_DEFINE_ELEMENT_CLASS_PROPERTY(elem_type, geom_type,             \
                                              interp_type, elem_kind, sp,       \
                                              gauss_int_type, min_int_order)    \
   template <> struct ElementClassProperty<elem_type> {                         \
     static const GeometricalType geometrical_type{geom_type};                  \
     static const InterpolationType interpolation_type{interp_type};            \
     static const ElementKind element_kind{elem_kind};                          \
     static const UInt spatial_dimension{sp};                                   \
     static const GaussIntegrationType gauss_integration_type{gauss_int_type};  \
     static const UInt polynomial_degree{min_int_order};                        \
   }
 
 /* -------------------------------------------------------------------------- */
 /* Geometry                                                                   */
 /* -------------------------------------------------------------------------- */
 /// Default GeometricalShape structure
 template <GeometricalType geometrical_type> struct GeometricalShape {
   static const GeometricalShapeType shape{_gst_point};
 };
 
 /// Templated GeometricalShape with function contains
 template <GeometricalShapeType shape> struct GeometricalShapeContains {
   /// Check if the point (vector in 2 and 3D) at natural coordinate coor
   template <class vector_type>
   static inline bool contains(const vector_type & coord);
 };
 
 /// Macro to generate the GeometricalShape structures for different geometrical
 /// types
 #define AKANTU_DEFINE_SHAPE(geom_type, geom_shape)                             \
   template <> struct GeometricalShape<geom_type> {                             \
     static const GeometricalShapeType shape{geom_shape};                       \
   }
 
 AKANTU_DEFINE_SHAPE(_gt_hexahedron_20, _gst_square);
 AKANTU_DEFINE_SHAPE(_gt_hexahedron_8, _gst_square);
 AKANTU_DEFINE_SHAPE(_gt_pentahedron_15, _gst_prism);
 AKANTU_DEFINE_SHAPE(_gt_pentahedron_6, _gst_prism);
 AKANTU_DEFINE_SHAPE(_gt_point, _gst_point);
 AKANTU_DEFINE_SHAPE(_gt_quadrangle_4, _gst_square);
 AKANTU_DEFINE_SHAPE(_gt_quadrangle_8, _gst_square);
 AKANTU_DEFINE_SHAPE(_gt_segment_2, _gst_square);
 AKANTU_DEFINE_SHAPE(_gt_segment_3, _gst_square);
 AKANTU_DEFINE_SHAPE(_gt_tetrahedron_10, _gst_triangle);
 AKANTU_DEFINE_SHAPE(_gt_tetrahedron_4, _gst_triangle);
 AKANTU_DEFINE_SHAPE(_gt_triangle_3, _gst_triangle);
 AKANTU_DEFINE_SHAPE(_gt_triangle_6, _gst_triangle);
 
 /* -------------------------------------------------------------------------- */
 template <GeometricalType geometrical_type>
 struct GeometricalElementProperty {};
 
 template <ElementType element_type>
 struct ElementClassExtraGeometryProperties {};
 
 /* -------------------------------------------------------------------------- */
 /// Templated GeometricalElement with function getInradius
 template <GeometricalType geometrical_type,
           GeometricalShapeType shape =
               GeometricalShape<geometrical_type>::shape>
 class GeometricalElement {
   using geometrical_property = GeometricalElementProperty<geometrical_type>;
 
 public:
   /// compute the in-radius
   static inline Real getInradius(__attribute__((unused))
                                  const Matrix<Real> & coord) {
     AKANTU_TO_IMPLEMENT();
   }
 
   /// true if the natural coordinates are in the element
   template <class vector_type>
   static inline bool contains(const vector_type & coord);
 
 public:
   static AKANTU_GET_MACRO_NOT_CONST(SpatialDimension,
                                     geometrical_property::spatial_dimension,
                                     UInt);
   static AKANTU_GET_MACRO_NOT_CONST(NbNodesPerElement,
                                     geometrical_property::nb_nodes_per_element,
                                     UInt);
   static inline constexpr auto getNbFacetTypes() {
     return geometrical_property::nb_facet_types;
   };
   static inline UInt getNbFacetsPerElement(UInt t);
   static inline UInt getNbFacetsPerElement();
   static inline constexpr auto getFacetLocalConnectivityPerElement(UInt t = 0);
 };
 
 /* -------------------------------------------------------------------------- */
 /* Interpolation                                                              */
 /* -------------------------------------------------------------------------- */
 /// default InterpolationProperty structure
 template <InterpolationType interpolation_type> struct InterpolationProperty {};
 
 /// Macro to generate the InterpolationProperty structures for different
 /// interpolation types
 #define AKANTU_DEFINE_INTERPOLATION_TYPE_PROPERTY(itp_type, itp_kind,          \
                                                   nb_nodes, ndim)              \
   template <> struct InterpolationProperty<itp_type> {                         \
     static constexpr InterpolationKind kind{itp_kind};                         \
     static constexpr UInt nb_nodes_per_element{nb_nodes};                      \
     static constexpr UInt natural_space_dimension{ndim};                       \
   }
 
 /* -------------------------------------------------------------------------- */
 /// Generic (templated by the enum InterpolationType which specifies the order
 /// and the dimension of the interpolation) class handling the elemental
 /// interpolation
 template <InterpolationType interpolation_type,
           InterpolationKind kind =
               InterpolationProperty<interpolation_type>::kind>
 class InterpolationElement {
 public:
   using interpolation_property = InterpolationProperty<interpolation_type>;
 
   /// compute the shape values for a given set of points in natural coordinates
   static inline void computeShapes(const Matrix<Real> & natural_coord,
                                    Matrix<Real> & N);
 
   /// compute the shape values for a given point in natural coordinates
   template <class vector_type>
   static inline void computeShapes(const vector_type &, vector_type &) {
     AKANTU_TO_IMPLEMENT();
   }
 
   /**
    * compute @f$ B_{ij} = \frac{\partial N_j}{\partial S_i} @f$ the variation of
    * shape functions along with variation of natural coordinates on a given set
    * of points in natural coordinates
    */
   static inline void computeDNDS(const Matrix<Real> & natural_coord,
                                  Tensor3<Real> & dnds);
   /**
    * compute @f$ B_{ij} = \frac{\partial N_j}{\partial S_i} @f$ the variation of
    * shape functions along with
    * variation of natural coordinates on a given point in natural
    * coordinates
    */
   template <class vector_type, class matrix_type>
   static inline void computeDNDS(const vector_type &, matrix_type &) {
     AKANTU_TO_IMPLEMENT();
   }
 
   /// compute jacobian (or integration variable change factor) for a given point
   /// in the case of spatial_dimension != natural_space_dimension
   static inline void computeSpecialJacobian(const Matrix<Real> &, Real &) {
     AKANTU_TO_IMPLEMENT();
   }
 
   /// interpolate a field given (arbitrary) natural coordinates
   static inline void
   interpolateOnNaturalCoordinates(const Vector<Real> & natural_coords,
                                   const Matrix<Real> & nodal_values,
                                   Vector<Real> & interpolated);
 
   /// interpolate a field given the shape functions on the interpolation point
   static inline void interpolate(const Matrix<Real> & nodal_values,
                                  const Vector<Real> & shapes,
                                  Vector<Real> & interpolated);
 
   /// interpolate a field given the shape functions on the interpolations points
   static inline void interpolate(const Matrix<Real> & nodal_values,
                                  const Matrix<Real> & shapes,
                                  Matrix<Real> & interpolated);
 
   /// compute the gradient of a given field on the given natural coordinates
   static inline void
   gradientOnNaturalCoordinates(const Vector<Real> & natural_coords,
                                const Matrix<Real> & f, Matrix<Real> & gradient);
 
 public:
   static AKANTU_GET_MACRO_NOT_CONST(
       ShapeSize,
       InterpolationProperty<interpolation_type>::nb_nodes_per_element, UInt);
   static AKANTU_GET_MACRO_NOT_CONST(
       ShapeDerivativesSize,
       (InterpolationProperty<interpolation_type>::nb_nodes_per_element *
        InterpolationProperty<interpolation_type>::natural_space_dimension),
       UInt);
   static AKANTU_GET_MACRO_NOT_CONST(
       NaturalSpaceDimension,
       InterpolationProperty<interpolation_type>::natural_space_dimension, UInt);
   static AKANTU_GET_MACRO_NOT_CONST(
       NbNodesPerInterpolationElement,
       InterpolationProperty<interpolation_type>::nb_nodes_per_element, UInt);
 };
 
 /* -------------------------------------------------------------------------- */
 /* Integration                                                                */
 /* -------------------------------------------------------------------------- */
 template <GaussIntegrationType git_class, UInt nb_points>
 struct GaussIntegrationTypeData {
   /// quadrature points in natural coordinates
   static Real quad_positions[];
   /// weights for the Gauss integration
   static Real quad_weights[];
 };
 
 template <ElementType type,
           UInt n = ElementClassProperty<type>::polynomial_degree>
 class GaussIntegrationElement {
 public:
   static UInt getNbQuadraturePoints();
   static const Matrix<Real> getQuadraturePoints();
   static const Vector<Real> getWeights();
 };
 
 /* -------------------------------------------------------------------------- */
 /* ElementClass                                                               */
 /* -------------------------------------------------------------------------- */
 template <ElementType element_type,
           ElementKind element_kind =
               ElementClassProperty<element_type>::element_kind>
 class ElementClass
     : public GeometricalElement<
           ElementClassProperty<element_type>::geometrical_type>,
       public InterpolationElement<
           ElementClassProperty<element_type>::interpolation_type> {
 protected:
   using geometrical_element =
       GeometricalElement<ElementClassProperty<element_type>::geometrical_type>;
   using interpolation_element = InterpolationElement<
       ElementClassProperty<element_type>::interpolation_type>;
 
   using element_property = ElementClassProperty<element_type>;
   using interpolation_property =
       typename interpolation_element::interpolation_property;
 
 public:
   /**
    * compute @f$ J = \frac{\partial x_j}{\partial s_i} @f$ the variation of real
    * coordinates along with variation of natural coordinates on a given point in
    * natural coordinates
    */
   static inline void computeJMat(const Matrix<Real> & dnds,
                                  const Matrix<Real> & node_coords,
                                  Matrix<Real> & J);
 
   /**
    * compute the Jacobian matrix by computing the variation of real coordinates
    * along with variation of natural coordinates on a given set of points in
    * natural coordinates
    */
   static inline void computeJMat(const Tensor3<Real> & dnds,
                                  const Matrix<Real> & node_coords,
                                  Tensor3<Real> & J);
 
   /// compute the jacobians of a serie of natural coordinates
   static inline void computeJacobian(const Matrix<Real> & natural_coords,
                                      const Matrix<Real> & node_coords,
                                      Vector<Real> & jacobians);
 
   /// compute jacobian (or integration variable change factor) for a set of
   /// points
   static inline void computeJacobian(const Tensor3<Real> & J,
                                      Vector<Real> & jacobians);
 
   /// compute jacobian (or integration variable change factor) for a given point
   static inline void computeJacobian(const Matrix<Real> & J, Real & jacobians);
 
   /// compute shape derivatives (input is dxds) for a set of points
   static inline void computeShapeDerivatives(const Tensor3<Real> & J,
                                              const Tensor3<Real> & dnds,
                                              Tensor3<Real> & shape_deriv);
 
   /// compute shape derivatives (input is dxds) for a given point
   static inline void computeShapeDerivatives(const Matrix<Real> & J,
                                              const Matrix<Real> & dnds,
                                              Matrix<Real> & shape_deriv);
 
   /// compute the normal of a surface defined by the function f
   static inline void
   computeNormalsOnNaturalCoordinates(const Matrix<Real> & coord,
                                      Matrix<Real> & f, Matrix<Real> & normals);
 
   /// get natural coordinates from real coordinates
   static inline void inverseMap(const Vector<Real> & real_coords,
                                 const Matrix<Real> & node_coords,
                                 Vector<Real> & natural_coords,
                                 Real tolerance = 1e-10);
 
   /// get natural coordinates from real coordinates
   static inline void inverseMap(const Matrix<Real> & real_coords,
                                 const Matrix<Real> & node_coords,
                                 Matrix<Real> & natural_coords,
                                 Real tolerance = 1e-10);
 
 public:
   static AKANTU_GET_MACRO_NOT_CONST(Kind, element_kind, ElementKind);
   static constexpr AKANTU_GET_MACRO_NOT_CONST(
       SpatialDimension, ElementClassProperty<element_type>::spatial_dimension,
       UInt);
 
   using element_class_extra_geom_property =
       ElementClassExtraGeometryProperties<element_type>;
 
   static constexpr auto getP1ElementType() {
     return element_class_extra_geom_property::p1_type;
   }
   static constexpr auto getFacetType(UInt t = 0) {
     return element_class_extra_geom_property::facet_type[t];
   }
   static constexpr auto getFacetTypes();
 };
 
 /* -------------------------------------------------------------------------- */
 } // namespace akantu
 
 /* -------------------------------------------------------------------------- */
 #include "geometrical_element_property.hh"
 #include "interpolation_element_tmpl.hh"
 /* -------------------------------------------------------------------------- */
 #include "element_class_tmpl.hh"
 /* -------------------------------------------------------------------------- */
 namespace akantu {
 #include "element_class_pentahedron_6_inline_impl.cc"
 /* keep order */
 #include "element_class_hexahedron_20_inline_impl.cc"
 #include "element_class_hexahedron_8_inline_impl.cc"
 #include "element_class_pentahedron_15_inline_impl.cc"
 #include "element_class_point_1_inline_impl.cc"
 #include "element_class_quadrangle_4_inline_impl.cc"
 #include "element_class_quadrangle_8_inline_impl.cc"
 #include "element_class_segment_2_inline_impl.cc"
 #include "element_class_segment_3_inline_impl.cc"
 #include "element_class_tetrahedron_10_inline_impl.cc"
 #include "element_class_tetrahedron_4_inline_impl.cc"
 #include "element_class_triangle_3_inline_impl.cc"
 #include "element_class_triangle_6_inline_impl.cc"
 } // namespace akantu
 
 /* -------------------------------------------------------------------------- */
 #if defined(AKANTU_STRUCTURAL_MECHANICS)
 #include "element_class_structural.hh"
 #endif
 
 #if defined(AKANTU_COHESIVE_ELEMENT)
 #include "cohesive_element.hh"
 #endif
 
 #if defined(AKANTU_IGFEM)
 #include "element_class_igfem.hh"
 #endif
 
 #endif /* __AKANTU_ELEMENT_CLASS_HH__ */
diff --git a/src/fe_engine/element_class_structural.hh b/src/fe_engine/element_class_structural.hh
index 0af2d1891..d719c6e11 100644
--- a/src/fe_engine/element_class_structural.hh
+++ b/src/fe_engine/element_class_structural.hh
@@ -1,252 +1,254 @@
 /**
  * @file   element_class_structural.hh
  *
  * @author Fabian Barras <fabian.barras@epfl.ch>
+ * @author Lucas Frerot <lucas.frerot@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  * @author Damien Spielmann <damien.spielmann@epfl.ch>
  *
  * @date creation: Thu Feb 21 2013
- * @date last modification: Thu Oct 22 2015
+ * @date last modification: Tue Feb 20 2018
  *
  * @brief  Specialization of the element classes for structural elements
  *
  * @section LICENSE
  *
- * Copyright  (©)  2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de Lausanne)
+ * 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
+ * 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
+ * A PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
+
 /* -------------------------------------------------------------------------- */
 #include "element_class.hh"
 /* -------------------------------------------------------------------------- */
 
 #ifndef __AKANTU_ELEMENT_CLASS_STRUCTURAL_HH__
 #define __AKANTU_ELEMENT_CLASS_STRUCTURAL_HH__
 
 namespace akantu {
 
 /// Macro to generate the InterpolationProperty structures for different
 /// interpolation types
 #define AKANTU_DEFINE_STRUCTURAL_INTERPOLATION_TYPE_PROPERTY(                  \
     itp_type, itp_geom_type, ndof, nb_stress, nb_dnds_cols)                    \
   template <> struct InterpolationProperty<itp_type> {                         \
     static const InterpolationKind kind{_itk_structural};                      \
     static const UInt nb_nodes_per_element{                                    \
         InterpolationProperty<itp_geom_type>::nb_nodes_per_element};           \
     static const InterpolationType itp_geometry_type{itp_geom_type};           \
     static const UInt natural_space_dimension{                                 \
         InterpolationProperty<itp_geom_type>::natural_space_dimension};        \
     static const UInt nb_degree_of_freedom{ndof};                              \
     static const UInt nb_stress_components{nb_stress};                         \
     static const UInt dnds_columns{nb_dnds_cols};                              \
   }
 
 /* -------------------------------------------------------------------------- */
 template <InterpolationType interpolation_type>
 class InterpolationElement<interpolation_type, _itk_structural> {
 public:
   using interpolation_property = InterpolationProperty<interpolation_type>;
 
   /// compute the shape values for a given set of points in natural coordinates
   static inline void computeShapes(const Matrix<Real> & natural_coord,
                                    const Matrix<Real> & real_coord,
                                    Tensor3<Real> & N) {
     for (UInt i = 0; i < natural_coord.cols(); ++i) {
       Matrix<Real> n_t = N(i);
       computeShapes(natural_coord(i), real_coord, n_t);
     }
   }
 
   /// compute the shape values for a given point in natural coordinates
   static inline void computeShapes(const Vector<Real> & natural_coord,
                                    const Matrix<Real> & real_coord,
                                    Matrix<Real> & N);
 
   /// compute shape derivatives (input is dxds) for a set of points
   static inline void computeShapeDerivatives(const Tensor3<Real> & Js,
                                              const Tensor3<Real> & DNDSs,
                                              const Matrix<Real> & R,
                                              Tensor3<Real> & Bs) {
     for (UInt i = 0; i < Js.size(2); ++i) {
       Matrix<Real> J = Js(i);
       Matrix<Real> DNDS = DNDSs(i);
       Matrix<Real> DNDX(DNDS.rows(), DNDS.cols());
       auto inv_J = J.inverse();
       DNDX.mul<false, false>(inv_J, DNDS);
       Matrix<Real> B_R = Bs(i);
       Matrix<Real> B(B_R.rows(), B_R.cols());
       arrangeInVoigt(DNDX, B);
       B_R.mul<false, false>(B, R);
     }
   }
 
   /**
    * compute @f$ B_{ij} = \frac{\partial N_j}{\partial S_i} @f$ the variation of
    * shape functions along with variation of natural coordinates on a given set
    * of points in natural coordinates
    */
   static inline void computeDNDS(const Matrix<Real> & natural_coord,
                                  const Matrix<Real> & real_coord,
                                  Tensor3<Real> & dnds) {
     for (UInt i = 0; i < natural_coord.cols(); ++i) {
       Matrix<Real> dnds_t = dnds(i);
       computeDNDS(natural_coord(i), real_coord, dnds_t);
     }
   }
 
   /**
    * compute @f$ B_{ij} = \frac{\partial N_j}{\partial S_i} @f$ the variation of
    * shape functions along with
    * variation of natural coordinates on a given point in natural
    * coordinates
    */
   static inline void computeDNDS(const Vector<Real> & natural_coord,
                                  const Matrix<Real> & real_coord,
                                  Matrix<Real> & dnds);
 
   /**
    * arrange B in Voigt notation from DNDS
    */
   static inline void arrangeInVoigt(const Matrix<Real> & dnds,
                                     Matrix<Real> & B) {
     // Default implementation assumes dnds is already in Voigt notation
     B.deepCopy(dnds);
   }
 
 public:
   static inline constexpr auto getNbNodesPerInterpolationElement() {
     return interpolation_property::nb_nodes_per_element;
   }
 
   static inline constexpr auto getShapeSize() {
     return interpolation_property::nb_nodes_per_element *
            interpolation_property::nb_degree_of_freedom *
            interpolation_property::nb_degree_of_freedom;
   }
   static inline constexpr auto getShapeDerivativesSize() {
     return interpolation_property::nb_nodes_per_element *
            interpolation_property::nb_degree_of_freedom *
            interpolation_property::nb_stress_components;
   }
   static inline constexpr auto getNaturalSpaceDimension() {
     return interpolation_property::natural_space_dimension;
   }
   static inline constexpr auto getNbDegreeOfFreedom() {
     return interpolation_property::nb_degree_of_freedom;
   }
   static inline constexpr auto getNbStressComponents() {
     return interpolation_property::nb_stress_components;
   }
 };
 
 /// Macro to generate the element class structures for different structural
 /// element types
 /* -------------------------------------------------------------------------- */
 #define AKANTU_DEFINE_STRUCTURAL_ELEMENT_CLASS_PROPERTY(                       \
     elem_type, geom_type, interp_type, parent_el_type, elem_kind, sp,          \
     gauss_int_type, min_int_order)                                             \
   template <> struct ElementClassProperty<elem_type> {                         \
     static const GeometricalType geometrical_type{geom_type};                  \
     static const InterpolationType interpolation_type{interp_type};            \
     static const ElementType parent_element_type{parent_el_type};              \
     static const ElementKind element_kind{elem_kind};                          \
     static const UInt spatial_dimension{sp};                                   \
     static const GaussIntegrationType gauss_integration_type{gauss_int_type};  \
     static const UInt polynomial_degree{min_int_order};                        \
   }
 
 /* -------------------------------------------------------------------------- */
 /* ElementClass for structural elements                                       */
 /* -------------------------------------------------------------------------- */
 template <ElementType element_type>
 class ElementClass<element_type, _ek_structural>
     : public GeometricalElement<
           ElementClassProperty<element_type>::geometrical_type>,
       public InterpolationElement<
           ElementClassProperty<element_type>::interpolation_type> {
 protected:
   using geometrical_element =
       GeometricalElement<ElementClassProperty<element_type>::geometrical_type>;
   using interpolation_element = InterpolationElement<
       ElementClassProperty<element_type>::interpolation_type>;
   using parent_element =
       ElementClass<ElementClassProperty<element_type>::parent_element_type>;
 
 public:
   static inline void
   computeRotationMatrix(Matrix<Real> & /*R*/, const Matrix<Real> & /*X*/,
                         const Vector<Real> & /*extra_normal*/) {
     AKANTU_TO_IMPLEMENT();
   }
 
   /// compute jacobian (or integration variable change factor) for a given point
   static inline void computeJMat(const Vector<Real> & natural_coords,
                                  const Matrix<Real> & Xs, Matrix<Real> & J) {
     Matrix<Real> dnds(Xs.rows(), Xs.cols());
     parent_element::computeDNDS(natural_coords, dnds);
     J.mul<false, true>(dnds, Xs);
   }
 
   static inline void computeJMat(const Matrix<Real> & natural_coords,
                                  const Matrix<Real> & Xs, Tensor3<Real> & Js) {
     for (UInt i = 0; i < natural_coords.cols(); ++i) {
       // because non-const l-value reference does not bind to r-value
       Matrix<Real> J = Js(i);
       computeJMat(Vector<Real>(natural_coords(i)), Xs, J);
     }
   }
 
   static inline void computeJacobian(const Matrix<Real> & natural_coords,
                                      const Matrix<Real> & node_coords,
                                      Vector<Real> & jacobians) {
     using itp = typename interpolation_element::interpolation_property;
     Tensor3<Real> Js(itp::natural_space_dimension, itp::natural_space_dimension,
                      natural_coords.cols());
     computeJMat(natural_coords, node_coords, Js);
     for (UInt i = 0; i < natural_coords.cols(); ++i) {
       Matrix<Real> J = Js(i);
       jacobians(i) = J.det();
     }
   }
 
   static inline void computeRotation(const Matrix<Real> & node_coords,
                                      Matrix<Real> & rotation);
 
 public:
   static AKANTU_GET_MACRO_NOT_CONST(Kind, _ek_structural, ElementKind);
   static AKANTU_GET_MACRO_NOT_CONST(P1ElementType, _not_defined, ElementType);
   static AKANTU_GET_MACRO_NOT_CONST(FacetType, _not_defined, ElementType);
   static constexpr auto getFacetType(__attribute__((unused)) UInt t = 0) {
     return _not_defined;
   }
   static constexpr AKANTU_GET_MACRO_NOT_CONST(
       SpatialDimension, ElementClassProperty<element_type>::spatial_dimension,
       UInt);
   static constexpr auto getFacetTypes() {
     return ElementClass<_not_defined>::getFacetTypes();
   }
 };
 
 } // namespace akantu
 
 /* -------------------------------------------------------------------------- */
 #include "element_classes/element_class_hermite_inline_impl.cc"
 /* keep order */
 #include "element_classes/element_class_bernoulli_beam_inline_impl.cc"
 #include "element_classes/element_class_kirchhoff_shell_inline_impl.cc"
 /* -------------------------------------------------------------------------- */
 
 #endif /* __AKANTU_ELEMENT_CLASS_STRUCTURAL_HH__ */
diff --git a/src/fe_engine/element_class_tmpl.hh b/src/fe_engine/element_class_tmpl.hh
index b58d164f1..4b8701579 100644
--- a/src/fe_engine/element_class_tmpl.hh
+++ b/src/fe_engine/element_class_tmpl.hh
@@ -1,531 +1,531 @@
 /**
  * @file   element_class_tmpl.hh
  *
  * @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
  * @author Thomas Menouillard <tmenouillard@stucky.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Thu Feb 21 2013
- * @date last modification: Thu Oct 22 2015
+ * @date last modification: Wed Nov 29 2017
  *
  * @brief  Implementation of the inline templated function of the element class
  * descriptions
  *
  * @section LICENSE
  *
- * Copyright  (©)  2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de Lausanne)
+ * 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
+ * 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
+ * A PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 #include "element_class.hh"
 #include "gauss_integration_tmpl.hh"
 /* -------------------------------------------------------------------------- */
 #include <type_traits>
 /* -------------------------------------------------------------------------- */
 
 #ifndef __AKANTU_ELEMENT_CLASS_TMPL_HH__
 #define __AKANTU_ELEMENT_CLASS_TMPL_HH__
 
 namespace akantu {
 
 template <ElementType element_type, ElementKind element_kind>
 inline constexpr auto
 ElementClass<element_type, element_kind>::getFacetTypes() {
   return VectorProxy<const ElementType>(
       element_class_extra_geom_property::facet_type.data(),
       geometrical_element::getNbFacetTypes());
 }
 
 /* -------------------------------------------------------------------------- */
 /* GeometricalElement                                                         */
 /* -------------------------------------------------------------------------- */
 template <GeometricalType geometrical_type, GeometricalShapeType shape>
 inline constexpr auto
 GeometricalElement<geometrical_type,
                    shape>::getFacetLocalConnectivityPerElement(UInt t) {
   int pos = 0;
   for (UInt i = 0; i < t; ++i) {
     pos += geometrical_property::nb_facets[i] *
            geometrical_property::nb_nodes_per_facet[i];
   }
 
   return MatrixProxy<const UInt>(
       geometrical_property::facet_connectivity_vect.data() + pos,
       geometrical_property::nb_facets[t],
       geometrical_property::nb_nodes_per_facet[t]);
 }
 
 /* -------------------------------------------------------------------------- */
 template <GeometricalType geometrical_type, GeometricalShapeType shape>
 inline UInt
 GeometricalElement<geometrical_type, shape>::getNbFacetsPerElement() {
   UInt total_nb_facets = 0;
   for (UInt n = 0; n < geometrical_property::nb_facet_types; ++n) {
     total_nb_facets += geometrical_property::nb_facets[n];
   }
 
   return total_nb_facets;
 }
 
 /* -------------------------------------------------------------------------- */
 template <GeometricalType geometrical_type, GeometricalShapeType shape>
 inline UInt
 GeometricalElement<geometrical_type, shape>::getNbFacetsPerElement(UInt t) {
   return geometrical_property::nb_facets[t];
 }
 
 /* -------------------------------------------------------------------------- */
 template <GeometricalType geometrical_type, GeometricalShapeType shape>
 template <class vector_type>
 inline bool GeometricalElement<geometrical_type, shape>::contains(
     const vector_type & coords) {
   return GeometricalShapeContains<shape>::contains(coords);
 }
 
 /* -------------------------------------------------------------------------- */
 template <>
 template <class vector_type>
 inline bool
 GeometricalShapeContains<_gst_point>::contains(const vector_type & coords) {
   return (coords(0) < std::numeric_limits<Real>::epsilon());
 }
 
 /* -------------------------------------------------------------------------- */
 template <>
 template <class vector_type>
 inline bool
 GeometricalShapeContains<_gst_square>::contains(const vector_type & coords) {
   bool in = true;
   for (UInt i = 0; i < coords.size() && in; ++i)
     in &= ((coords(i) >= -(1. + std::numeric_limits<Real>::epsilon())) &&
            (coords(i) <= (1. + std::numeric_limits<Real>::epsilon())));
   return in;
 }
 
 /* -------------------------------------------------------------------------- */
 template <>
 template <class vector_type>
 inline bool
 GeometricalShapeContains<_gst_triangle>::contains(const vector_type & coords) {
   bool in = true;
   Real sum = 0;
   for (UInt i = 0; (i < coords.size()) && in; ++i) {
     in &= ((coords(i) >= -(Math::getTolerance())) &&
            (coords(i) <= (1. + Math::getTolerance())));
     sum += coords(i);
   }
   if (in)
     return (in && (sum <= (1. + Math::getTolerance())));
   return in;
 }
 
 /* -------------------------------------------------------------------------- */
 template <>
 template <class vector_type>
 inline bool
 GeometricalShapeContains<_gst_prism>::contains(const vector_type & coords) {
   bool in = ((coords(0) >= -1.) && (coords(0) <= 1.)); // x in segment [-1, 1]
 
   // y and z in triangle
   in &= ((coords(1) >= 0) && (coords(1) <= 1.));
   in &= ((coords(2) >= 0) && (coords(2) <= 1.));
   Real sum = coords(1) + coords(2);
 
   return (in && (sum <= 1));
 }
 
 /* -------------------------------------------------------------------------- */
 /* InterpolationElement                                                       */
 /* -------------------------------------------------------------------------- */
 template <InterpolationType interpolation_type, InterpolationKind kind>
 inline void InterpolationElement<interpolation_type, kind>::computeShapes(
     const Matrix<Real> & natural_coord, Matrix<Real> & N) {
   UInt nb_points = natural_coord.cols();
   for (UInt p = 0; p < nb_points; ++p) {
     Vector<Real> Np(N(p));
     Vector<Real> ncoord_p(natural_coord(p));
     computeShapes(ncoord_p, Np);
   }
 }
 
 /* -------------------------------------------------------------------------- */
 template <InterpolationType interpolation_type, InterpolationKind kind>
 inline void InterpolationElement<interpolation_type, kind>::computeDNDS(
     const Matrix<Real> & natural_coord, Tensor3<Real> & dnds) {
   UInt nb_points = natural_coord.cols();
   for (UInt p = 0; p < nb_points; ++p) {
     Matrix<Real> dnds_p(dnds(p));
     Vector<Real> ncoord_p(natural_coord(p));
     computeDNDS(ncoord_p, dnds_p);
   }
 }
 
 /* -------------------------------------------------------------------------- */
 /**
  * interpolate on a point a field for which values are given on the
  * node of the element using the shape functions at this interpolation point
  *
  * @param nodal_values values of the function per node @f$ f_{ij} = f_{n_i j}
  *@f$ so it should be a matrix of size nb_nodes_per_element @f$\times@f$
  *nb_degree_of_freedom
  * @param shapes value of shape functions at the interpolation point
  * @param interpolated interpolated value of f @f$ f_j(\xi) = \sum_i f_{n_i j}
  *N_i @f$
  */
 template <InterpolationType interpolation_type, InterpolationKind kind>
 inline void InterpolationElement<interpolation_type, kind>::interpolate(
     const Matrix<Real> & nodal_values, const Vector<Real> & shapes,
     Vector<Real> & interpolated) {
   Matrix<Real> interpm(interpolated.storage(), nodal_values.rows(), 1);
   Matrix<Real> shapesm(
       shapes.storage(),
       InterpolationProperty<interpolation_type>::nb_nodes_per_element, 1);
   interpm.mul<false, false>(nodal_values, shapesm);
 }
 
 /* -------------------------------------------------------------------------- */
 /**
  * interpolate on several points a field  for which values are given on the
  * node of the element using the shape functions at the interpolation point
  *
  * @param nodal_values values of the function per node @f$ f_{ij} = f_{n_i j}
  *@f$ so it should be a matrix of size nb_nodes_per_element @f$\times@f$
  *nb_degree_of_freedom
  * @param shapes value of shape functions at the interpolation point
  * @param interpolated interpolated values of f @f$ f_j(\xi) = \sum_i f_{n_i j}
  *N_i @f$
  */
 template <InterpolationType interpolation_type, InterpolationKind kind>
 inline void InterpolationElement<interpolation_type, kind>::interpolate(
     const Matrix<Real> & nodal_values, const Matrix<Real> & shapes,
     Matrix<Real> & interpolated) {
   UInt nb_points = shapes.cols();
   for (UInt p = 0; p < nb_points; ++p) {
     Vector<Real> Np(shapes(p));
     Vector<Real> interpolated_p(interpolated(p));
     interpolate(nodal_values, Np, interpolated_p);
   }
 }
 
 /* -------------------------------------------------------------------------- */
 /**
  * interpolate the field on a point given in natural coordinates the field which
  * values are given on the node of the element
  *
  * @param natural_coords natural coordinates of point where to interpolate \xi
  * @param nodal_values values of the function per node @f$ f_{ij} = f_{n_i j}
  *@f$ so it should be a matrix of size nb_nodes_per_element @f$\times@f$
  *nb_degree_of_freedom
  * @param interpolated interpolated value of f @f$ f_j(\xi) = \sum_i f_{n_i j}
  *N_i @f$
  */
 template <InterpolationType interpolation_type, InterpolationKind kind>
 inline void
 InterpolationElement<interpolation_type, kind>::interpolateOnNaturalCoordinates(
     const Vector<Real> & natural_coords, const Matrix<Real> & nodal_values,
     Vector<Real> & interpolated) {
   Vector<Real> shapes(
       InterpolationProperty<interpolation_type>::nb_nodes_per_element);
   computeShapes(natural_coords, shapes);
 
   interpolate(nodal_values, shapes, interpolated);
 }
 
 /* -------------------------------------------------------------------------- */
 /// @f$ gradient_{ij} = \frac{\partial f_j}{\partial s_i} = \sum_k
 /// \frac{\partial N_k}{\partial s_i}f_{j n_k} @f$
 template <InterpolationType interpolation_type, InterpolationKind kind>
 inline void
 InterpolationElement<interpolation_type, kind>::gradientOnNaturalCoordinates(
     const Vector<Real> & natural_coords, const Matrix<Real> & f,
     Matrix<Real> & gradient) {
   Matrix<Real> dnds(
       InterpolationProperty<interpolation_type>::natural_space_dimension,
       InterpolationProperty<interpolation_type>::nb_nodes_per_element);
   computeDNDS(natural_coords, dnds);
   gradient.mul<false, true>(f, dnds);
 }
 
 /* -------------------------------------------------------------------------- */
 /* ElementClass                                                               */
 /* -------------------------------------------------------------------------- */
 
 /* -------------------------------------------------------------------------- */
 template <ElementType type, ElementKind kind>
 inline void
 ElementClass<type, kind>::computeJMat(const Tensor3<Real> & dnds,
                                       const Matrix<Real> & node_coords,
                                       Tensor3<Real> & J) {
   UInt nb_points = dnds.size(2);
   for (UInt p = 0; p < nb_points; ++p) {
     Matrix<Real> J_p(J(p));
     Matrix<Real> dnds_p(dnds(p));
     computeJMat(dnds_p, node_coords, J_p);
   }
 }
 
 /* -------------------------------------------------------------------------- */
 template <ElementType type, ElementKind kind>
 inline void
 ElementClass<type, kind>::computeJMat(const Matrix<Real> & dnds,
                                       const Matrix<Real> & node_coords,
                                       Matrix<Real> & J) {
   /// @f$ J = dxds = dnds * x @f$
   J.mul<false, true>(dnds, node_coords);
 }
 
 /* -------------------------------------------------------------------------- */
 template <ElementType type, ElementKind kind>
 inline void
 ElementClass<type, kind>::computeJacobian(const Matrix<Real> & natural_coords,
                                           const Matrix<Real> & node_coords,
                                           Vector<Real> & jacobians) {
   UInt nb_points = natural_coords.cols();
   Matrix<Real> dnds(interpolation_property::natural_space_dimension,
                     interpolation_property::nb_nodes_per_element);
   Matrix<Real> J(natural_coords.rows(), node_coords.rows());
 
   for (UInt p = 0; p < nb_points; ++p) {
     Vector<Real> ncoord_p(natural_coords(p));
     interpolation_element::computeDNDS(ncoord_p, dnds);
     computeJMat(dnds, node_coords, J);
     computeJacobian(J, jacobians(p));
   }
 }
 
 /* -------------------------------------------------------------------------- */
 template <ElementType type, ElementKind kind>
 inline void
 ElementClass<type, kind>::computeJacobian(const Tensor3<Real> & J,
                                           Vector<Real> & jacobians) {
   UInt nb_points = J.size(2);
   for (UInt p = 0; p < nb_points; ++p) {
     computeJacobian(J(p), jacobians(p));
   }
 }
 
 /* -------------------------------------------------------------------------- */
 template <ElementType type, ElementKind kind>
 inline void ElementClass<type, kind>::computeJacobian(const Matrix<Real> & J,
                                                       Real & jacobians) {
   if (J.rows() == J.cols()) {
     jacobians = Math::det<element_property::spatial_dimension>(J.storage());
   } else {
     interpolation_element::computeSpecialJacobian(J, jacobians);
   }
 }
 
 /* -------------------------------------------------------------------------- */
 template <ElementType type, ElementKind kind>
 inline void
 ElementClass<type, kind>::computeShapeDerivatives(const Tensor3<Real> & J,
                                                   const Tensor3<Real> & dnds,
                                                   Tensor3<Real> & shape_deriv) {
   UInt nb_points = J.size(2);
   for (UInt p = 0; p < nb_points; ++p) {
     Matrix<Real> shape_deriv_p(shape_deriv(p));
     computeShapeDerivatives(J(p), dnds(p), shape_deriv_p);
   }
 }
 
 /* -------------------------------------------------------------------------- */
 template <ElementType type, ElementKind kind>
 inline void
 ElementClass<type, kind>::computeShapeDerivatives(const Matrix<Real> & J,
                                                   const Matrix<Real> & dnds,
                                                   Matrix<Real> & shape_deriv) {
   Matrix<Real> inv_J(J.rows(), J.cols());
   Math::inv<element_property::spatial_dimension>(J.storage(), inv_J.storage());
 
   shape_deriv.mul<false, false>(inv_J, dnds);
 }
 
 /* -------------------------------------------------------------------------- */
 template <ElementType type, ElementKind kind>
 inline void ElementClass<type, kind>::computeNormalsOnNaturalCoordinates(
     const Matrix<Real> & coord, Matrix<Real> & f, Matrix<Real> & normals) {
   UInt dimension = normals.rows();
   UInt nb_points = coord.cols();
 
   AKANTU_DEBUG_ASSERT((dimension - 1) ==
                           interpolation_property::natural_space_dimension,
                       "cannot extract a normal because of dimension mismatch "
                           << dimension - 1 << " "
                           << interpolation_property::natural_space_dimension);
 
   Matrix<Real> J(dimension, interpolation_property::natural_space_dimension);
   for (UInt p = 0; p < nb_points; ++p) {
     interpolation_element::gradientOnNaturalCoordinates(coord(p), f, J);
     if (dimension == 2) {
       Math::normal2(J.storage(), normals(p).storage());
     }
     if (dimension == 3) {
       Math::normal3(J(0).storage(), J(1).storage(), normals(p).storage());
     }
   }
 }
 
 /* ------------------------------------------------------------------------- */
 /**
  * In the non linear cases we need to iterate to find the natural coordinates
  *@f$\xi@f$
  * provided real coordinates @f$x@f$.
  *
  * We want to solve: @f$ x- \phi(\xi) = 0@f$ with @f$\phi(\xi) = \sum_I N_I(\xi)
  *x_I@f$
  * the mapping function which uses the nodal coordinates @f$x_I@f$.
  *
  * To that end we use the Newton method and the following series:
  *
  * @f$ \frac{\partial \phi(x_k)}{\partial \xi} \left( \xi_{k+1} - \xi_k \right)
  *= x - \phi(x_k)@f$
  *
  * When we consider elements embedded in a dimension higher than them (2D
  *triangle in a 3D space for example)
  * @f$ J = \frac{\partial \phi(\xi_k)}{\partial \xi}@f$ is of dimension
  *@f$dim_{space} \times dim_{elem}@f$ which
  * is not invertible in most cases. Rather we can solve the problem:
  *
  * @f$ J^T J \left( \xi_{k+1} - \xi_k \right) = J^T \left( x - \phi(\xi_k)
  *\right) @f$
  *
  * So that
  *
  * @f$ d\xi = \xi_{k+1} - \xi_k = (J^T J)^{-1} J^T \left( x - \phi(\xi_k)
  *\right) @f$
  *
  * So that if the series converges we have:
  *
  * @f$ 0 = J^T \left( \phi(\xi_\infty) - x \right) @f$
  *
  * And we see that this is ill-posed only if @f$ J^T x = 0@f$ which means that
  *the vector provided
  * is normal to any tangent which means it is outside of the element itself.
  *
  * @param real_coords: the real coordinates the natural coordinates are sought
  *for
  * @param node_coords: the coordinates of the nodes forming the element
  * @param natural_coords: output->the sought natural coordinates
  * @param spatial_dimension: spatial dimension of the problem
  *
  **/
 template <ElementType type, ElementKind kind>
 inline void ElementClass<type, kind>::inverseMap(
     const Vector<Real> & real_coords, const Matrix<Real> & node_coords,
     Vector<Real> & natural_coords, Real tolerance) {
   UInt spatial_dimension = real_coords.size();
   UInt dimension = natural_coords.size();
 
   // matrix copy of the real_coords
   Matrix<Real> mreal_coords(real_coords.storage(), spatial_dimension, 1);
 
   // initial guess
   //  Matrix<Real> natural_guess(natural_coords.storage(), dimension, 1);
   natural_coords.clear();
 
   // real space coordinates provided by initial guess
   Matrix<Real> physical_guess(dimension, 1);
 
   // objective function f = real_coords - physical_guess
   Matrix<Real> f(dimension, 1);
 
   // dnds computed on the natural_guess
   //  Matrix<Real> dnds(interpolation_element::nb_nodes_per_element,
   //  spatial_dimension);
 
   // J Jacobian matrix computed on the natural_guess
   Matrix<Real> J(spatial_dimension, dimension);
 
   // G = J^t * J
   Matrix<Real> G(spatial_dimension, spatial_dimension);
 
   // Ginv = G^{-1}
   Matrix<Real> Ginv(spatial_dimension, spatial_dimension);
 
   // J = Ginv * J^t
   Matrix<Real> F(spatial_dimension, dimension);
 
   // dxi = \xi_{k+1} - \xi in the iterative process
   Matrix<Real> dxi(spatial_dimension, 1);
 
   /* --------------------------- */
   /* init before iteration loop  */
   /* --------------------------- */
   // do interpolation
   auto update_f = [&f, &physical_guess, &natural_coords, &node_coords,
                    &mreal_coords, dimension]() {
     Vector<Real> physical_guess_v(physical_guess.storage(), dimension);
     interpolation_element::interpolateOnNaturalCoordinates(
         natural_coords, node_coords, physical_guess_v);
 
     // compute initial objective function value f = real_coords - physical_guess
     f = mreal_coords;
     f -= physical_guess;
 
     // compute initial error
     auto error = f.norm<L_2>();
     return error;
   };
 
   auto inverse_map_error = update_f();
 
   /* --------------------------- */
   /* iteration loop              */
   /* --------------------------- */
   while (tolerance < inverse_map_error) {
     // compute J^t
     interpolation_element::gradientOnNaturalCoordinates(natural_coords,
                                                         node_coords, J);
 
     // compute G
     G.mul<true, false>(J, J);
 
     // inverse G
     Ginv.inverse(G);
 
     // compute F
     F.mul<false, true>(Ginv, J);
 
     // compute increment
     dxi.mul<false, false>(F, f);
 
     // update our guess
     natural_coords += Vector<Real>(dxi(0));
 
     inverse_map_error = update_f();
   }
   //  memcpy(natural_coords.storage(), natural_guess.storage(), sizeof(Real) *
   //  natural_coords.size());
 }
 
 /* -------------------------------------------------------------------------- */
 template <ElementType type, ElementKind kind>
 inline void ElementClass<type, kind>::inverseMap(
     const Matrix<Real> & real_coords, const Matrix<Real> & node_coords,
     Matrix<Real> & natural_coords, Real tolerance) {
   UInt nb_points = real_coords.cols();
   for (UInt p = 0; p < nb_points; ++p) {
     Vector<Real> X(real_coords(p));
     Vector<Real> ncoord_p(natural_coords(p));
     inverseMap(X, node_coords, ncoord_p, tolerance);
   }
 }
 
 } // namespace akantu
 
 #endif /* __AKANTU_ELEMENT_CLASS_TMPL_HH__ */
diff --git a/src/fe_engine/element_classes/element_class_bernoulli_beam_inline_impl.cc b/src/fe_engine/element_classes/element_class_bernoulli_beam_inline_impl.cc
index 407cb0af0..417f631c6 100644
--- a/src/fe_engine/element_classes/element_class_bernoulli_beam_inline_impl.cc
+++ b/src/fe_engine/element_classes/element_class_bernoulli_beam_inline_impl.cc
@@ -1,222 +1,223 @@
 /**
  * @file   element_class_bernoulli_beam_inline_impl.cc
  *
  * @author Fabian Barras <fabian.barras@epfl.ch>
+ * @author Lucas Frerot <lucas.frerot@epfl.ch>
  *
  * @date creation: Fri Jul 15 2011
- * @date last modification: Sun Oct 19 2014
+ * @date last modification: Mon Feb 19 2018
  *
  * @brief  Specialization of the element_class class for the type
- _bernoulli_beam_2
+ * _bernoulli_beam_2
  *
  * @section LICENSE
  *
- * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
- * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
- * Solides)
+ * 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
+ * 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
+ * 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/>.
  *
  * @section DESCRIPTION
  *
  * @verbatim
    --x-----q1----|----q2-----x---> x
     -1          0            1
  @endverbatim
  *
  */
+
 /* -------------------------------------------------------------------------- */
 #include "aka_static_if.hh"
 #include "element_class_structural.hh"
 //#include "aka_element_classes_info.hh"
 /* -------------------------------------------------------------------------- */
 
 #ifndef __AKANTU_ELEMENT_CLASS_BERNOULLI_BEAM_INLINE_IMPL_CC__
 #define __AKANTU_ELEMENT_CLASS_BERNOULLI_BEAM_INLINE_IMPL_CC__
 
 namespace akantu {
 /* -------------------------------------------------------------------------- */
 AKANTU_DEFINE_STRUCTURAL_INTERPOLATION_TYPE_PROPERTY(_itp_bernoulli_beam_2,
                                                      _itp_lagrange_segment_2, 3,
                                                      2, 6);
 
 AKANTU_DEFINE_STRUCTURAL_INTERPOLATION_TYPE_PROPERTY(_itp_bernoulli_beam_3,
                                                      _itp_lagrange_segment_2, 6,
                                                      4, 6);
 
 AKANTU_DEFINE_STRUCTURAL_ELEMENT_CLASS_PROPERTY(_bernoulli_beam_2,
                                                 _gt_segment_2,
                                                 _itp_bernoulli_beam_2,
                                                 _segment_2, _ek_structural, 2,
                                                 _git_segment, 3);
 
 AKANTU_DEFINE_STRUCTURAL_ELEMENT_CLASS_PROPERTY(_bernoulli_beam_3,
                                                 _gt_segment_2,
                                                 _itp_bernoulli_beam_3,
                                                 _segment_2, _ek_structural, 3,
                                                 _git_segment, 3);
 
 /* -------------------------------------------------------------------------- */
 template <>
 inline void
 InterpolationElement<_itp_bernoulli_beam_2, _itk_structural>::computeShapes(
     const Vector<Real> & natural_coords, const Matrix<Real> & real_coord,
     Matrix<Real> & N) {
   Vector<Real> L(2);
   InterpolationElement<_itp_lagrange_segment_2, _itk_lagrangian>::computeShapes(
       natural_coords, L);
   Matrix<Real> H(2, 4);
   InterpolationElement<_itp_hermite_2, _itk_structural>::computeShapes(
       natural_coords, real_coord, H);
 
   // clang-format off
   //    u1   v1      t1      u2   v2      t2
   N = {{L(0), 0      , 0      , L(1), 0      , 0      },  // u
        {0   , H(0, 0), H(0, 1), 0   , H(0, 2), H(0, 3)},  // v
        {0   , H(1, 0), H(1, 1), 0   , H(1, 2), H(1, 3)}}; // theta
   // clang-format on
 }
 
 template <>
 inline void
 InterpolationElement<_itp_bernoulli_beam_3, _itk_structural>::computeShapes(
     const Vector<Real> & natural_coords, const Matrix<Real> & real_coord,
     Matrix<Real> & N) {
   Vector<Real> L(2);
   InterpolationElement<_itp_lagrange_segment_2, _itk_lagrangian>::computeShapes(
       natural_coords, L);
   Matrix<Real> H(2, 4);
   InterpolationElement<_itp_hermite_2, _itk_structural>::computeShapes(
       natural_coords, real_coord, H);
 
   // clang-format off
   //   u1    v1      w1      x1   y1      z1      u2   v2      w2      x2   y2      z2
   N = {{L(0), 0      , 0      , 0   , 0      , 0      , L(1), 0      , 0      , 0   , 0      , 0      },  // u
        {0   , H(0, 0), 0      , 0   , H(0, 1), 0      , 0   , H(0, 2), 0      , 0   , H(0, 3), 0      },  // v
        {0   , 0      , H(0, 0), 0   , 0      , H(0, 1), 0   , 0      , H(0, 2), 0   , 0      , H(0, 3)},  // w
        {0   , 0      , 0      , L(0), 0      , 0      , 0   , 0      , 0      , L(1), 0      , 0      },  // thetax
        {0   , H(1, 0), 0      , 0   , H(1, 1), 0      , 0   , H(1, 2), 0      , 0   , H(1, 3), 0      },  // thetay
        {0   , 0      , H(1, 0), 0   , 0      , H(1, 1), 0   , 0      , H(1, 2), 0   , 0      , H(1, 3)}}; // thetaz
   // clang-format on
 }
 
 /* -------------------------------------------------------------------------- */
 template <>
 inline void
 InterpolationElement<_itp_bernoulli_beam_2, _itk_structural>::computeDNDS(
     const Vector<Real> & natural_coords, const Matrix<Real> & real_coord,
     Matrix<Real> & dnds) {
   Matrix<Real> L(1, 2);
   InterpolationElement<_itp_lagrange_segment_2, _itk_lagrangian>::computeDNDS(
       natural_coords, L);
   Matrix<Real> H(1, 4);
   InterpolationElement<_itp_hermite_2, _itk_structural>::computeDNDS(
       natural_coords, real_coord, H);
 
   // Storing the derivatives in dnds
   dnds.block(L, 0, 0);
   dnds.block(H, 0, 2);
 }
 
 /* -------------------------------------------------------------------------- */
 template <>
 inline void
 InterpolationElement<_itp_bernoulli_beam_2, _itk_structural>::arrangeInVoigt(
     const Matrix<Real> & dnds, Matrix<Real> & B) {
   auto L = dnds.block(0, 0, 1, 2); // Lagrange shape derivatives
   auto H = dnds.block(0, 2, 1, 4); // Hermite shape derivatives
   // clang-format off
   //    u1       v1       t1       u2       v2       t2
   B = {{L(0, 0), 0,       0,       L(0, 1), 0,       0      },
        {0,       H(0, 0), H(0, 1), 0,       H(0, 2), H(0, 3)}};
   // clang-format on
 }
 
 /* -------------------------------------------------------------------------- */
 template <>
 inline void
 InterpolationElement<_itp_bernoulli_beam_3, _itk_structural>::computeDNDS(
     const Vector<Real> & natural_coords, const Matrix<Real> & real_coord,
     Matrix<Real> & dnds) {
   InterpolationElement<_itp_bernoulli_beam_2, _itk_structural>::computeDNDS(
       natural_coords, real_coord, dnds);
 }
 
 /* -------------------------------------------------------------------------- */
 template <>
 inline void
 InterpolationElement<_itp_bernoulli_beam_3, _itk_structural>::arrangeInVoigt(
     const Matrix<Real> & dnds, Matrix<Real> & B) {
   auto L = dnds.block(0, 0, 1, 2); // Lagrange shape derivatives
   auto H = dnds.block(0, 2, 1, 4); // Hermite shape derivatives
 
   // clang-format off
   //    u1       v1       w1       x1       y1       z1       u2       v2       w2       x2       y2       z2
   B = {{L(0, 0), 0      , 0      , 0      , 0      , 0      , L(0, 1), 0      , 0      , 0      , 0      , 0      },  // eps
        {0      , H(0, 0), 0      , 0      , 0      , H(0, 1), 0      , H(0, 2), 0      , 0      , 0      , H(0, 3)},  // chi strong axis
        {0      , 0      ,-H(0, 0), 0      , H(0, 1), 0      , 0      , 0      ,-H(0, 2), 0      , H(0, 3), 0      },  // chi weak axis
        {0      , 0      , 0      , L(0, 0), 0      , 0      , 0      , 0      , 0      , L(0, 1), 0      , 0      }}; // chi torsion
   // clang-format on
 }
 
 /* -------------------------------------------------------------------------- */
 template <>
 inline void ElementClass<_bernoulli_beam_2>::computeRotationMatrix(
     Matrix<Real> & R, const Matrix<Real> & X, const Vector<Real> &) {
   Vector<Real> x2 = X(1); // X2
   Vector<Real> x1 = X(0); // X1
 
   auto cs = (x2 - x1);
   cs.normalize();
 
   auto c = cs(0);
   auto s = cs(1);
 
   // clang-format off
   /// Definition of the rotation matrix
   R = {{ c,  s,  0.},
        {-s,  c,  0.},
        { 0., 0., 1.}};
   // clang-format on
 }
 
 /* -------------------------------------------------------------------------- */
 template <>
 inline void ElementClass<_bernoulli_beam_3>::computeRotationMatrix(
     Matrix<Real> & R, const Matrix<Real> & X, const Vector<Real> & n) {
   Vector<Real> x2 = X(1); // X2
   Vector<Real> x1 = X(0); // X1
   auto dim = X.rows();
   auto x = (x2 - x1);
   x.normalize();
   auto x_n = x.crossProduct(n);
 
   Matrix<Real> Pe = {{1., 0., 0.}, {0., -1., 0.}, {0., 0., 1.}};
 
   Matrix<Real> Pg(dim, dim);
   Pg(0) = x;
   Pg(1) = x_n;
   Pg(2) = n;
 
   Pe *= Pg.inverse();
 
   R.clear();
   /// Definition of the rotation matrix
   for (UInt i = 0; i < dim; ++i)
     for (UInt j = 0; j < dim; ++j)
       R(i + dim, j + dim) = R(i, j) = Pe(i, j);
 }
 
 } // namespace akantu
 #endif /* __AKANTU_ELEMENT_CLASS_BERNOULLI_BEAM_INLINE_IMPL_CC__ */
diff --git a/src/fe_engine/element_classes/element_class_hermite_inline_impl.cc b/src/fe_engine/element_classes/element_class_hermite_inline_impl.cc
index 03972b2a0..33ac526aa 100644
--- a/src/fe_engine/element_classes/element_class_hermite_inline_impl.cc
+++ b/src/fe_engine/element_classes/element_class_hermite_inline_impl.cc
@@ -1,179 +1,179 @@
 /**
  * @file   element_class_hermite_inline_impl.cc
  *
  * @author Fabian Barras <fabian.barras@epfl.ch>
- * @author Lucas Frérot <lucas.frerot@epfl.ch>
+ * @author Lucas Frerot <lucas.frerot@epfl.ch>
  *
- * @date creation: Fri Jul 15 2011
- * @date last modification: Sun Oct 19 2014
+ * @date creation: Fri Nov 10 2017
+ * @date last modification: Mon Feb 19 2018
  *
  * @brief  Specialization of the element_class class for the type
- _hermite
+ * _hermite
  *
  * @section LICENSE
  *
- * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
- * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
- * Solides)
+ * 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.
+ 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.
+ 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/>.
+ along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  * @section DESCRIPTION
  *
  * @verbatim
    --x-----q1----|----q2-----x---> x
     -1          0            1
  @endverbatim
  *
  * @subsection shapes Shape functions
  * @f[
  *   \begin{array}{ll}
  *     M_1(\xi) &= 1/4(\xi^{3}/-3\xi+2)\\
  *     M_2(\xi) &= -1/4(\xi^{3}-3\xi-2)
  *   \end{array}
  *
  *   \begin{array}{ll}
  *     L_1(\xi) &= 1/4(\xi^{3}-\xi^{2}-\xi+1)\\
  *     L_2(\xi) &= 1/4(\xi^{3}+\xi^{2}-\xi-1)
  *   \end{array}
  *
  *   \begin{array}{ll}
  *     M'_1(\xi) &= 3/4(\xi^{2}-1)\\
  *     M'_2(\xi) &= -3/4(\xi^{2}-1)
  *   \end{array}
  *
  *   \begin{array}{ll}
  *     L'_1(\xi) &= 1/4(3\xi^{2}-2\xi-1)\\
  *     L'_2(\xi) &= 1/4(3\xi^{2}+2\xi-1)
  *   \end{array}
  *@f]
  *
  * @subsection dnds Shape derivatives
  *
  *@f[
  * \begin{array}{ll}
  *   N'_1(\xi) &= -1/2\\
  *   N'_2(\xi) &= 1/2
  * \end{array}]
  *
  * \begin{array}{ll}
  *   -M''_1(\xi) &= -3\xi/2\\
  *   -M''_2(\xi) &= 3\xi/2\\
  * \end{array}
  *
  * \begin{array}{ll}
  *   -L''_1(\xi) &= -1/2a(3\xi/a-1)\\
  *   -L''_2(\xi) &= -1/2a(3\xi/a+1)
  * \end{array}
  *@f]
  *
  */
+
 /* -------------------------------------------------------------------------- */
 #include "aka_static_if.hh"
 #include "element_class_structural.hh"
 /* -------------------------------------------------------------------------- */
 
 #ifndef __AKANTU_ELEMENT_CLASS_HERMITE_INLINE_IMPL_CC__
 #define __AKANTU_ELEMENT_CLASS_HERMITE_INLINE_IMPL_CC__
 
 namespace akantu {
 /* -------------------------------------------------------------------------- */
 
 AKANTU_DEFINE_STRUCTURAL_INTERPOLATION_TYPE_PROPERTY(_itp_hermite_2,
                                                      _itp_lagrange_segment_2, 2,
                                                      1, 4);
 
 /* -------------------------------------------------------------------------- */
 
 namespace {
   namespace details {
     inline Real computeLength(const Matrix<Real> & real_coord) {
       Vector<Real> x1 = real_coord(0);
       Vector<Real> x2 = real_coord(1);
       return x1.distance(x2);
     }
 
     inline void computeShapes(const Vector<Real> & natural_coords, Real a,
                               Matrix<Real> & N) {
       /// natural coordinate
       Real xi = natural_coords(0);
 
       // Cubic Hermite splines interpolating displacement
       auto M1 = 1. / 4. * Math::pow<2>(xi - 1) * (xi + 2);
       auto M2 = 1. / 4. * Math::pow<2>(xi + 1) * (2 - xi);
       auto L1 = a / 4. * Math::pow<2>(xi - 1) * (xi + 1);
       auto L2 = a / 4. * Math::pow<2>(xi + 1) * (xi - 1);
 
 #if 1 // Version where we also interpolate the rotations
       // Derivatives (with respect to x) of previous functions interpolating
       // rotations
       auto M1_ = 3. / (4. * a) * (xi * xi - 1);
       auto M2_ = 3. / (4. * a) * (1 - xi * xi);
       auto L1_ = 1 / 4. * (3 * xi * xi - 2 * xi - 1);
       auto L2_ = 1 / 4. * (3 * xi * xi + 2 * xi - 1);
 
       // clang-format off
       //    v1   t1   v2   t2
       N = {{M1 , L1 , M2 , L2},   // displacement interpolation
 	   {M1_, L1_, M2_, L2_}}; // rotation interpolation
 // clang-format on
 
 #else // Version where we only interpolate displacements
       // clang-format off
       //    v1  t1  v2  t2
       N = {{M1, L1, M2, L2}};
 // clang-format on
 #endif
     }
 
     /* ---------------------------------------------------------------------- */
 
     inline void computeDNDS(const Vector<Real> & natural_coords, Real a,
                             Matrix<Real> & B) {
       // natural coordinate
       Real xi = natural_coords(0);
       // Derivatives with respect to xi for rotations
       auto M1__ = 3. / 2. * xi;
       auto M2__ = 3. / 2. * (-xi);
       auto L1__ = a / 2. * (3 * xi - 1);
       auto L2__ = a / 2. * (3 * xi + 1);
 
       //    v1    t1    v2    t2
       B = {{M1__, L1__, M2__, L2__}}; // computing curvature : {chi} = [B]{d}
       B /= a; // to account for first order deriv w/r to x
     }
   } // namespace details
 } // namespace
 
 /* -------------------------------------------------------------------------- */
 template <>
 inline void
 InterpolationElement<_itp_hermite_2, _itk_structural>::computeShapes(
     const Vector<Real> & natural_coords, const Matrix<Real> & real_coord,
     Matrix<Real> & N) {
   auto L = details::computeLength(real_coord);
   details::computeShapes(natural_coords, L / 2, N);
 }
 
 /* -------------------------------------------------------------------------- */
 template <>
 inline void InterpolationElement<_itp_hermite_2, _itk_structural>::computeDNDS(
     const Vector<Real> & natural_coords, const Matrix<Real> & real_coord,
     Matrix<Real> & B) {
   auto L = details::computeLength(real_coord);
   details::computeDNDS(natural_coords, L / 2, B);
 }
 
 } // namespace akantu
 #endif /* __AKANTU_ELEMENT_CLASS_HERMITE_INLINE_IMPL_CC__ */
diff --git a/src/fe_engine/element_classes/element_class_hexahedron_20_inline_impl.cc b/src/fe_engine/element_classes/element_class_hexahedron_20_inline_impl.cc
index da0c877fc..0906a90be 100644
--- a/src/fe_engine/element_classes/element_class_hexahedron_20_inline_impl.cc
+++ b/src/fe_engine/element_classes/element_class_hexahedron_20_inline_impl.cc
@@ -1,259 +1,259 @@
 /**
  * @file   element_class_hexahedron_20_inline_impl.cc
  *
  * @author Mauro Corrado <mauro.corrado@epfl.ch>
  * @author Sacha Laffely <sacha.laffely@epfl.ch>
  * @author Damien Scantamburlo <damien.scantamburlo@epfl.ch>
  *
  * @date creation: Tue Mar 31 2015
- * @date last modification: Thu Jul 16 2015
+ * @date last modification: Wed Oct 11 2017
  *
  * @brief  Specialization of the element_class class for the type _hexahedron_20
  *
  * @section LICENSE
  *
- * Copyright (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne) Laboratory
- * (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * Copyright (©) 2015-2018 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
- * terms  of the  GNU Lesser  General Public  License as  published by  the Free
- * Software Foundation, either version 3 of the License, or (at your option) any
- * later version.
+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.
+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/>.
+along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  * @section DESCRIPTION
  *
  * @verbatim
                                    \y
                          \z       /
                          |       /
                    7-----|18--------6
                   /|     |     /   /|
                  / |     |    /   / |
                19  |     |   /  17  |
                /  15     |  /   /   14
               /    |     | /   /    |
              4-------16---/---5     |
              |     |     +----|------------\x
              |     3-------10-|-----2
              |    /           |    /
             12   /           13   /
              |  11            |  9
              | /              | /
              |/               |/
              0--------8-------1
        x   y    z
 * N0  -1  -1   -1
 * N1   1  -1   -1
 * N2   1   1   -1
 * N3  -1   1   -1
 * N4  -1  -1    1
 * N5   1  -1    1
 * N6   1   1    1
 * N7  -1   1    1
 * N8   0  -1   -1
 * N9   1   0   -1
 * N10  0   1   -1
 * N11 -1   0   -1
 * N12 -1  -1    0
 * N13  1  -1    0
 * N14  1   1    0
 * N15 -1   1    0
 * N16  0  -1    1
 * N17  1   0    1
 * N18  0   1    1
 * N19 -1   0    1
  */
 
 /* -------------------------------------------------------------------------- */
 AKANTU_DEFINE_ELEMENT_CLASS_PROPERTY(_hexahedron_20, _gt_hexahedron_20,
                                      _itp_serendip_hexahedron_20, _ek_regular,
                                      3, _git_segment, 3);
 
 /* -------------------------------------------------------------------------- */
 template <>
 template <class vector_type>
 inline void InterpolationElement<_itp_serendip_hexahedron_20>::computeShapes(
     const vector_type & c, vector_type & N) {
 
   // Shape function , Natural coordinates
   N(0) =
       0.125 * (1 - c(0)) * (1 - c(1)) * (1 - c(2)) * (-2 - c(0) - c(1) - c(2));
   N(1) =
       0.125 * (1 + c(0)) * (1 - c(1)) * (1 - c(2)) * (-2 + c(0) - c(1) - c(2));
   N(2) =
       0.125 * (1 + c(0)) * (1 + c(1)) * (1 - c(2)) * (-2 + c(0) + c(1) - c(2));
   N(3) =
       0.125 * (1 - c(0)) * (1 + c(1)) * (1 - c(2)) * (-2 - c(0) + c(1) - c(2));
   N(4) =
       0.125 * (1 - c(0)) * (1 - c(1)) * (1 + c(2)) * (-2 - c(0) - c(1) + c(2));
   N(5) =
       0.125 * (1 + c(0)) * (1 - c(1)) * (1 + c(2)) * (-2 + c(0) - c(1) + c(2));
   N(6) =
       0.125 * (1 + c(0)) * (1 + c(1)) * (1 + c(2)) * (-2 + c(0) + c(1) + c(2));
   N(7) =
       0.125 * (1 - c(0)) * (1 + c(1)) * (1 + c(2)) * (-2 - c(0) + c(1) + c(2));
   N(8) = 0.25 * (1 - c(0) * c(0)) * (1 - c(1)) * (1 - c(2));
   N(9) = 0.25 * (1 - c(1) * c(1)) * (1 + c(0)) * (1 - c(2));
   N(10) = 0.25 * (1 - c(0) * c(0)) * (1 + c(1)) * (1 - c(2));
   N(11) = 0.25 * (1 - c(1) * c(1)) * (1 - c(0)) * (1 - c(2));
   N(12) = 0.25 * (1 - c(2) * c(2)) * (1 - c(0)) * (1 - c(1));
   N(13) = 0.25 * (1 - c(2) * c(2)) * (1 + c(0)) * (1 - c(1));
   N(14) = 0.25 * (1 - c(2) * c(2)) * (1 + c(0)) * (1 + c(1));
   N(15) = 0.25 * (1 - c(2) * c(2)) * (1 - c(0)) * (1 + c(1));
   N(16) = 0.25 * (1 - c(0) * c(0)) * (1 - c(1)) * (1 + c(2));
   N(17) = 0.25 * (1 - c(1) * c(1)) * (1 + c(0)) * (1 + c(2));
   N(18) = 0.25 * (1 - c(0) * c(0)) * (1 + c(1)) * (1 + c(2));
   N(19) = 0.25 * (1 - c(1) * c(1)) * (1 - c(0)) * (1 + c(2));
 }
 /* -------------------------------------------------------------------------- */
 
 template <>
 template <class vector_type, class matrix_type>
 inline void InterpolationElement<_itp_serendip_hexahedron_20>::computeDNDS(
     const vector_type & c, matrix_type & dnds) {
   // derivatives
   // ddx
   dnds(0, 0) =
       0.25 * (c(0) + 0.5 * (c(1) + c(2) + 1)) * (c(1) - 1) * (c(2) - 1);
   dnds(0, 1) =
       0.25 * (c(0) - 0.5 * (c(1) + c(2) + 1)) * (c(1) - 1) * (c(2) - 1);
   dnds(0, 2) =
       -0.25 * (c(0) + 0.5 * (c(1) - c(2) - 1)) * (c(1) + 1) * (c(2) - 1);
   dnds(0, 3) =
       -0.25 * (c(0) - 0.5 * (c(1) - c(2) - 1)) * (c(1) + 1) * (c(2) - 1);
   dnds(0, 4) =
       -0.25 * (c(0) + 0.5 * (c(1) - c(2) + 1)) * (c(1) - 1) * (c(2) + 1);
   dnds(0, 5) =
       -0.25 * (c(0) - 0.5 * (c(1) - c(2) + 1)) * (c(1) - 1) * (c(2) + 1);
   dnds(0, 6) =
       0.25 * (c(0) + 0.5 * (c(1) + c(2) - 1)) * (c(1) + 1) * (c(2) + 1);
   dnds(0, 7) =
       0.25 * (c(0) - 0.5 * (c(1) + c(2) - 1)) * (c(1) + 1) * (c(2) + 1);
   dnds(0, 8) = -0.5 * c(0) * (c(1) - 1) * (c(2) - 1);
   dnds(0, 9) = 0.25 * (c(1) * c(1) - 1) * (c(2) - 1);
   dnds(0, 10) = 0.5 * c(0) * (c(1) + 1) * (c(2) - 1);
   dnds(0, 11) = -0.25 * (c(1) * c(1) - 1) * (c(2) - 1);
   dnds(0, 12) = -0.25 * (c(2) * c(2) - 1) * (c(1) - 1);
   dnds(0, 13) = 0.25 * (c(1) - 1) * (c(2) * c(2) - 1);
   dnds(0, 14) = -0.25 * (c(1) + 1) * (c(2) * c(2) - 1);
   dnds(0, 15) = 0.25 * (c(1) + 1) * (c(2) * c(2) - 1);
   dnds(0, 16) = 0.5 * c(0) * (c(1) - 1) * (c(2) + 1);
   dnds(0, 17) = -0.25 * (c(2) + 1) * (c(1) * c(1) - 1);
   dnds(0, 18) = -0.5 * c(0) * (c(1) + 1) * (c(2) + 1);
   dnds(0, 19) = 0.25 * (c(2) + 1) * (c(1) * c(1) - 1);
 
   // ddy
   dnds(1, 0) =
       0.25 * (c(1) + 0.5 * (c(0) + c(2) + 1)) * (c(0) - 1) * (c(2) - 1);
   dnds(1, 1) =
       -0.25 * (c(1) - 0.5 * (c(0) - c(2) - 1)) * (c(0) + 1) * (c(2) - 1);
   dnds(1, 2) =
       -0.25 * (c(1) + 0.5 * (c(0) - c(2) - 1)) * (c(0) + 1) * (c(2) - 1);
   dnds(1, 3) =
       0.25 * (c(1) - 0.5 * (c(0) + c(2) + 1)) * (c(0) - 1) * (c(2) - 1);
   dnds(1, 4) =
       -0.25 * (c(1) + 0.5 * (c(0) - c(2) + 1)) * (c(0) - 1) * (c(2) + 1);
   dnds(1, 5) =
       0.25 * (c(1) - 0.5 * (c(0) + c(2) - 1)) * (c(0) + 1) * (c(2) + 1);
   dnds(1, 6) =
       0.25 * (c(1) + 0.5 * (c(0) + c(2) - 1)) * (c(0) + 1) * (c(2) + 1);
   dnds(1, 7) =
       -0.25 * (c(1) - 0.5 * (c(0) - c(2) + 1)) * (c(0) - 1) * (c(2) + 1);
   dnds(1, 8) = -0.25 * (c(0) * c(0) - 1) * (c(2) - 1);
   dnds(1, 9) = 0.5 * c(1) * (c(0) + 1) * (c(2) - 1);
   dnds(1, 10) = 0.25 * (c(0) * c(0) - 1) * (c(2) - 1);
   dnds(1, 11) = -0.5 * c(1) * (c(0) - 1) * (c(2) - 1);
   dnds(1, 12) = -0.25 * (c(2) * c(2) - 1) * (c(0) - 1);
   dnds(1, 13) = 0.25 * (c(0) + 1) * (c(2) * c(2) - 1);
   dnds(1, 14) = -0.25 * (c(0) + 1) * (c(2) * c(2) - 1);
   dnds(1, 15) = 0.25 * (c(0) - 1) * (c(2) * c(2) - 1);
   dnds(1, 16) = 0.25 * (c(2) + 1) * (c(0) * c(0) - 1);
   dnds(1, 17) = -0.5 * c(1) * (c(0) + 1) * (c(2) + 1);
   dnds(1, 18) = -0.25 * (c(2) + 1) * (c(0) * c(0) - 1);
   dnds(1, 19) = 0.5 * c(1) * (c(0) - 1) * (c(2) + 1);
 
   // ddz
   dnds(2, 0) =
       0.25 * (c(2) + 0.5 * (c(0) + c(1) + 1)) * (c(0) - 1) * (c(1) - 1);
   dnds(2, 1) =
       -0.25 * (c(2) - 0.5 * (c(0) - c(1) - 1)) * (c(0) + 1) * (c(1) - 1);
   dnds(2, 2) =
       0.25 * (c(2) - 0.5 * (c(0) + c(1) - 1)) * (c(0) + 1) * (c(1) + 1);
   dnds(2, 3) =
       -0.25 * (c(2) + 0.5 * (c(0) - c(1) + 1)) * (c(0) - 1) * (c(1) + 1);
   dnds(2, 4) =
       0.25 * (c(2) - 0.5 * (c(0) + c(1) + 1)) * (c(0) - 1) * (c(1) - 1);
   dnds(2, 5) =
       -0.25 * (c(2) + 0.5 * (c(0) - c(1) - 1)) * (c(0) + 1) * (c(1) - 1);
   dnds(2, 6) =
       0.25 * (c(2) + 0.5 * (c(0) + c(1) - 1)) * (c(0) + 1) * (c(1) + 1);
   dnds(2, 7) =
       -0.25 * (c(2) - 0.5 * (c(0) - c(1) + 1)) * (c(0) - 1) * (c(1) + 1);
   dnds(2, 8) = -0.25 * (c(0) * c(0) - 1) * (c(1) - 1);
   dnds(2, 9) = 0.25 * (c(1) * c(1) - 1) * (c(0) + 1);
   dnds(2, 10) = 0.25 * (c(0) * c(0) - 1) * (c(1) + 1);
   dnds(2, 11) = -0.25 * (c(1) * c(1) - 1) * (c(0) - 1);
   dnds(2, 12) = -0.5 * c(2) * (c(1) - 1) * (c(0) - 1);
   dnds(2, 13) = 0.5 * c(2) * (c(0) + 1) * (c(1) - 1);
   dnds(2, 14) = -0.5 * c(2) * (c(0) + 1) * (c(1) + 1);
   dnds(2, 15) = 0.5 * c(2) * (c(0) - 1) * (c(1) + 1);
   dnds(2, 16) = 0.25 * (c(1) - 1) * (c(0) * c(0) - 1);
   dnds(2, 17) = -0.25 * (c(0) + 1) * (c(1) * c(1) - 1);
   dnds(2, 18) = -0.25 * (c(1) + 1) * (c(0) * c(0) - 1);
   dnds(2, 19) = 0.25 * (c(0) - 1) * (c(1) * c(1) - 1);
 }
 
 /* -------------------------------------------------------------------------- */
 
 template <>
 inline Real
 GeometricalElement<_gt_hexahedron_20>::getInradius(const Matrix<Real> & coord) {
   Vector<Real> u0 = coord(0);
   Vector<Real> u1 = coord(1);
   Vector<Real> u2 = coord(2);
   Vector<Real> u3 = coord(3);
   Vector<Real> u4 = coord(4);
   Vector<Real> u5 = coord(5);
   Vector<Real> u6 = coord(6);
   Vector<Real> u7 = coord(7);
   Vector<Real> u8 = coord(8);
   Vector<Real> u9 = coord(9);
   Vector<Real> u10 = coord(10);
   Vector<Real> u11 = coord(11);
   Vector<Real> u12 = coord(12);
   Vector<Real> u13 = coord(13);
   Vector<Real> u14 = coord(14);
   Vector<Real> u15 = coord(15);
   Vector<Real> u16 = coord(16);
   Vector<Real> u17 = coord(17);
   Vector<Real> u18 = coord(18);
   Vector<Real> u19 = coord(19);
 
   Real a = u0.distance(u1);
   Real b = u1.distance(u2);
   Real c = u2.distance(u3);
   Real d = u3.distance(u0);
   Real e = u0.distance(u4);
   Real f = u1.distance(u5);
   Real g = u2.distance(u6);
   Real h = u3.distance(u7);
   Real i = u4.distance(u5);
   Real j = u5.distance(u6);
   Real k = u6.distance(u7);
   Real l = u7.distance(u4);
 
   Real x = std::min(a, std::min(b, std::min(c, d)));
   Real y = std::min(e, std::min(f, std::min(g, h)));
   Real z = std::min(i, std::min(j, std::min(k, l)));
   Real p = std::min(x, std::min(y, z));
 
   return p;
 }
diff --git a/src/fe_engine/element_classes/element_class_hexahedron_8_inline_impl.cc b/src/fe_engine/element_classes/element_class_hexahedron_8_inline_impl.cc
index 9fb1cc1ac..7a96249a3 100644
--- a/src/fe_engine/element_classes/element_class_hexahedron_8_inline_impl.cc
+++ b/src/fe_engine/element_classes/element_class_hexahedron_8_inline_impl.cc
@@ -1,254 +1,253 @@
 /**
  * @file   element_class_hexahedron_8_inline_impl.cc
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  * @author Peter Spijker <peter.spijker@epfl.ch>
  *
  * @date creation: Mon Mar 14 2011
- * @date last modification: Sat Sep 12 2015
+ * @date last modification: Wed Oct 11 2017
  *
  * @brief  Specialization of the element_class class for the type _hexahedron_8
  *
  * @section LICENSE
  *
- * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
- * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
- * Solides)
+ * 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.
+ 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.
+ 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/>.
+ along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  * @section DESCRIPTION
  *
  * @verbatim
                    \zeta
                     ^
          (-1,1,1)   |     (1,1,1)
                 7---|------6
                /|   |     /|
               / |   |    / |
    (-1,-1,1) 4----------5  | (1,-1,1)
              |  |   |   |  |
              |  |   |   |  |
              |  |   +---|-------> \xi
              |  |  /    |  |
    (-1,1,-1) |  3-/-----|--2 (1,1,-1)
              | / /      | /
              |/ /       |/
              0-/--------1
    (-1,-1,-1) /        (1,-1,-1)
              /
             \eta
  @endverbatim
  *
  * @subsection shapes Shape functions
  * @f[
  * \begin{array}{llll}
  * N1 = (1 - \xi) (1 - \eta) (1 - \zeta) / 8
  *       & \frac{\partial N1}{\partial \xi}  = - (1 - \eta) (1 - \zeta) / 8
  *       & \frac{\partial N1}{\partial \eta} = - (1 - \xi) (1 - \zeta) / 8
  *       & \frac{\partial N1}{\partial \zeta} = - (1 - \xi) (1 - \eta) / 8 \\
  * N2 = (1 + \xi) (1 - \eta) (1 - \zeta) / 8
  *       & \frac{\partial N2}{\partial \xi}  = (1 - \eta) (1 - \zeta) / 8
  *       & \frac{\partial N2}{\partial \eta} = - (1 + \xi) (1 - \zeta) / 8
  *       & \frac{\partial N2}{\partial \zeta} = - (1 + \xi) (1 - \eta) / 8 \\
  * N3 = (1 + \xi) (1 + \eta) (1 - \zeta) / 8
  *       & \frac{\partial N3}{\partial \xi}  = (1 + \eta) (1 - \zeta) / 8
  *       & \frac{\partial N3}{\partial \eta} = (1 + \xi) (1 - \zeta) / 8
  *       & \frac{\partial N3}{\partial \zeta} = - (1 + \xi) (1 + \eta) / 8 \\
  * N4 = (1 - \xi) (1 + \eta) (1 - \zeta) / 8
  *       & \frac{\partial N4}{\partial \xi}  = - (1 + \eta) (1 - \zeta) / 8
  *       & \frac{\partial N4}{\partial \eta} = (1 - \xi) (1 - \zeta) / 8
  *       & \frac{\partial N4}{\partial \zeta} = - (1 - \xi) (1 + \eta) / 8 \\
  * N5 = (1 - \xi) (1 - \eta) (1 + \zeta) / 8
  *       & \frac{\partial N5}{\partial \xi}  = - (1 - \eta) (1 + \zeta) / 8
  *       & \frac{\partial N5}{\partial \eta} = - (1 - \xi) (1 + \zeta) / 8
  *       & \frac{\partial N5}{\partial \zeta} = (1 - \xi) (1 - \eta) / 8 \\
  * N6 = (1 + \xi) (1 - \eta) (1 + \zeta) / 8
  *       & \frac{\partial N6}{\partial \xi}  = (1 - \eta) (1 + \zeta) / 8
  *       & \frac{\partial N6}{\partial \eta} = - (1 + \xi) (1 + \zeta) / 8
  *       & \frac{\partial N6}{\partial \zeta} = (1 + \xi) (1 - \eta) / 8 \\
  * N7 = (1 + \xi) (1 + \eta) (1 + \zeta) / 8
  *       & \frac{\partial N7}{\partial \xi}  = (1 + \eta) (1 + \zeta) / 8
  *       & \frac{\partial N7}{\partial \eta} = (1 + \xi) (1 + \zeta) / 8
  *       & \frac{\partial N7}{\partial \zeta} = (1 + \xi) (1 + \eta) / 8 \\
  * N8 = (1 - \xi) (1 + \eta) (1 + \zeta) / 8
  *       & \frac{\partial N8}{\partial \xi}  = - (1 + \eta) (1 + \zeta) / 8
  *       & \frac{\partial N8}{\partial \eta} = (1 - \xi) (1 + \zeta) / 8
  *       & \frac{\partial N8}{\partial \zeta} = (1 - \xi) (1 + \eta) / 8 \\
  * \end{array}
  * @f]
  *
  * @subsection quad_points Position of quadrature points
  * @f{eqnarray*}{
  * \xi_{q0}  &=& -1/\sqrt{3} \qquad  \eta_{q0} = -1/\sqrt{3} \qquad \zeta_{q0} =
  -1/\sqrt{3} \\
  * \xi_{q1}  &=&  1/\sqrt{3} \qquad  \eta_{q1} = -1/\sqrt{3} \qquad \zeta_{q1} =
  -1/\sqrt{3} \\
  * \xi_{q2}  &=&  1/\sqrt{3} \qquad  \eta_{q2} =  1/\sqrt{3} \qquad \zeta_{q2} =
  -1/\sqrt{3} \\
  * \xi_{q3}  &=& -1/\sqrt{3} \qquad  \eta_{q3} =  1/\sqrt{3} \qquad \zeta_{q3} =
  -1/\sqrt{3} \\
  * \xi_{q4}  &=& -1/\sqrt{3} \qquad  \eta_{q4} = -1/\sqrt{3} \qquad \zeta_{q4} =
  1/\sqrt{3} \\
  * \xi_{q5}  &=&  1/\sqrt{3} \qquad  \eta_{q5} = -1/\sqrt{3} \qquad \zeta_{q5} =
  1/\sqrt{3} \\
  * \xi_{q6}  &=&  1/\sqrt{3} \qquad  \eta_{q6} =  1/\sqrt{3} \qquad \zeta_{q6} =
  1/\sqrt{3} \\
  * \xi_{q7}  &=& -1/\sqrt{3} \qquad  \eta_{q7} =  1/\sqrt{3} \qquad \zeta_{q7} =
  1/\sqrt{3} \\
  * @f}
  */
 
 /* -------------------------------------------------------------------------- */
 AKANTU_DEFINE_ELEMENT_CLASS_PROPERTY(_hexahedron_8, _gt_hexahedron_8,
                                      _itp_lagrange_hexahedron_8, _ek_regular, 3,
                                      _git_segment, 2);
 
 /* -------------------------------------------------------------------------- */
 template <>
 template <class vector_type>
 inline void InterpolationElement<_itp_lagrange_hexahedron_8>::computeShapes(
     const vector_type & c, vector_type & N) {
   /// Natural coordinates
   N(0) = .125 * (1 - c(0)) * (1 - c(1)) * (1 - c(2)); /// N1(q_0)
   N(1) = .125 * (1 + c(0)) * (1 - c(1)) * (1 - c(2)); /// N2(q_0)
   N(2) = .125 * (1 + c(0)) * (1 + c(1)) * (1 - c(2)); /// N3(q_0)
   N(3) = .125 * (1 - c(0)) * (1 + c(1)) * (1 - c(2)); /// N4(q_0)
   N(4) = .125 * (1 - c(0)) * (1 - c(1)) * (1 + c(2)); /// N5(q_0)
   N(5) = .125 * (1 + c(0)) * (1 - c(1)) * (1 + c(2)); /// N6(q_0)
   N(6) = .125 * (1 + c(0)) * (1 + c(1)) * (1 + c(2)); /// N7(q_0)
   N(7) = .125 * (1 - c(0)) * (1 + c(1)) * (1 + c(2)); /// N8(q_0)
 }
 /* -------------------------------------------------------------------------- */
 template <>
 template <class vector_type, class matrix_type>
 inline void InterpolationElement<_itp_lagrange_hexahedron_8>::computeDNDS(
     const vector_type & c, matrix_type & dnds) {
   /**
    * @f[
    * dnds = \left(
    *          \begin{array}{cccccccc}
    *            \frac{\partial N1}{\partial \xi}  & \frac{\partial N2}{\partial
    * \xi}
    *               & \frac{\partial N3}{\partial \xi}  & \frac{\partial
    * N4}{\partial \xi}
    *               & \frac{\partial N5}{\partial \xi}  & \frac{\partial
    * N6}{\partial \xi}
    *               & \frac{\partial N7}{\partial \xi}  & \frac{\partial
    * N8}{\partial \xi}\\
    *            \frac{\partial N1}{\partial \eta} & \frac{\partial N2}{\partial
    * \eta}
    *               & \frac{\partial N3}{\partial \eta} & \frac{\partial
    * N4}{\partial \eta}
    *               & \frac{\partial N5}{\partial \eta} & \frac{\partial
    * N6}{\partial \eta}
    *               & \frac{\partial N7}{\partial \eta} & \frac{\partial
    * N8}{\partial \eta}\\
    *            \frac{\partial N1}{\partial \zeta} & \frac{\partial N2}{\partial
    * \zeta}
    *               & \frac{\partial N3}{\partial \zeta} & \frac{\partial
    * N4}{\partial \zeta}
    *               & \frac{\partial N5}{\partial \zeta} & \frac{\partial
    * N6}{\partial \zeta}
    *               & \frac{\partial N7}{\partial \zeta} & \frac{\partial
    * N8}{\partial \zeta}
    *          \end{array}
    *        \right)
    * @f]
    */
   dnds(0, 0) = -.125 * (1 - c(1)) * (1 - c(2));
   ;
   dnds(0, 1) = .125 * (1 - c(1)) * (1 - c(2));
   ;
   dnds(0, 2) = .125 * (1 + c(1)) * (1 - c(2));
   ;
   dnds(0, 3) = -.125 * (1 + c(1)) * (1 - c(2));
   ;
   dnds(0, 4) = -.125 * (1 - c(1)) * (1 + c(2));
   ;
   dnds(0, 5) = .125 * (1 - c(1)) * (1 + c(2));
   ;
   dnds(0, 6) = .125 * (1 + c(1)) * (1 + c(2));
   ;
   dnds(0, 7) = -.125 * (1 + c(1)) * (1 + c(2));
   ;
 
   dnds(1, 0) = -.125 * (1 - c(0)) * (1 - c(2));
   ;
   dnds(1, 1) = -.125 * (1 + c(0)) * (1 - c(2));
   ;
   dnds(1, 2) = .125 * (1 + c(0)) * (1 - c(2));
   ;
   dnds(1, 3) = .125 * (1 - c(0)) * (1 - c(2));
   ;
   dnds(1, 4) = -.125 * (1 - c(0)) * (1 + c(2));
   ;
   dnds(1, 5) = -.125 * (1 + c(0)) * (1 + c(2));
   ;
   dnds(1, 6) = .125 * (1 + c(0)) * (1 + c(2));
   ;
   dnds(1, 7) = .125 * (1 - c(0)) * (1 + c(2));
   ;
 
   dnds(2, 0) = -.125 * (1 - c(0)) * (1 - c(1));
   ;
   dnds(2, 1) = -.125 * (1 + c(0)) * (1 - c(1));
   ;
   dnds(2, 2) = -.125 * (1 + c(0)) * (1 + c(1));
   ;
   dnds(2, 3) = -.125 * (1 - c(0)) * (1 + c(1));
   ;
   dnds(2, 4) = .125 * (1 - c(0)) * (1 - c(1));
   ;
   dnds(2, 5) = .125 * (1 + c(0)) * (1 - c(1));
   ;
   dnds(2, 6) = .125 * (1 + c(0)) * (1 + c(1));
   ;
   dnds(2, 7) = .125 * (1 - c(0)) * (1 + c(1));
   ;
 }
 
 /* -------------------------------------------------------------------------- */
 template <>
 inline Real
 GeometricalElement<_gt_hexahedron_8>::getInradius(const Matrix<Real> & coord) {
   Vector<Real> u0 = coord(0);
   Vector<Real> u1 = coord(1);
   Vector<Real> u2 = coord(2);
   Vector<Real> u3 = coord(3);
   Vector<Real> u4 = coord(4);
   Vector<Real> u5 = coord(5);
   Vector<Real> u6 = coord(6);
   Vector<Real> u7 = coord(7);
 
   Real a = u0.distance(u1);
   Real b = u1.distance(u2);
   Real c = u2.distance(u3);
   Real d = u3.distance(u0);
   Real e = u0.distance(u4);
   Real f = u1.distance(u5);
   Real g = u2.distance(u6);
   Real h = u3.distance(u7);
   Real i = u4.distance(u5);
   Real j = u5.distance(u6);
   Real k = u6.distance(u7);
   Real l = u7.distance(u4);
 
   Real x = std::min(a, std::min(b, std::min(c, d)));
   Real y = std::min(e, std::min(f, std::min(g, h)));
   Real z = std::min(i, std::min(j, std::min(k, l)));
   Real p = std::min(x, std::min(y, z));
 
   return p;
 }
diff --git a/src/fe_engine/element_classes/element_class_kirchhoff_shell_inline_impl.cc b/src/fe_engine/element_classes/element_class_kirchhoff_shell_inline_impl.cc
index b74beaa9e..1f75e71c8 100644
--- a/src/fe_engine/element_classes/element_class_kirchhoff_shell_inline_impl.cc
+++ b/src/fe_engine/element_classes/element_class_kirchhoff_shell_inline_impl.cc
@@ -1,212 +1,214 @@
 /**
  * @file   element_class_kirchhoff_shell_inline_impl.cc
  *
+ * @author Lucas Frerot <lucas.frerot@epfl.ch>
  * @author Damien Spielmann <damien.spielmann@epfl.ch>
  *
  * @date creation: Fri Jul 04 2014
- * @date last modification: Sun Oct 19 2014
+ * @date last modification: Wed Feb 21 2018
  *
  * @brief  Element class Kirchhoff Shell
  *
  * @section LICENSE
  *
- * Copyright  (©)  2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de Lausanne)
+ * 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
+ * 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
+ * A PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
+
 /* -------------------------------------------------------------------------- */
 #include "element_class_structural.hh"
 /* -------------------------------------------------------------------------- */
 
 #ifndef __AKANTU_ELEMENT_CLASS_KIRCHHOFF_SHELL_INLINE_IMPL_CC__
 #define __AKANTU_ELEMENT_CLASS_KIRCHHOFF_SHELL_INLINE_IMPL_CC__
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 AKANTU_DEFINE_STRUCTURAL_INTERPOLATION_TYPE_PROPERTY(
     _itp_discrete_kirchhoff_triangle_18, _itp_lagrange_triangle_3, 6, 6, 21);
 AKANTU_DEFINE_STRUCTURAL_ELEMENT_CLASS_PROPERTY(
     _discrete_kirchhoff_triangle_18, _gt_triangle_3,
     _itp_discrete_kirchhoff_triangle_18, _triangle_3, _ek_structural, 3,
     _git_triangle, 2);
 
 /* -------------------------------------------------------------------------- */
 namespace detail {
   inline void computeBasisChangeMatrix(Matrix<Real> & P,
                                        const Matrix<Real> & X) {
     Vector<Real> X1 = X(0);
     Vector<Real> X2 = X(1);
     Vector<Real> X3 = X(2);
 
     Vector<Real> a1 = X2 - X1;
     Vector<Real> a2 = X3 - X1;
 
     a1.normalize();
     Vector<Real> e3 = a1.crossProduct(a2);
     e3.normalize();
     Vector<Real> e2 = e3.crossProduct(a1);
 
     P(0) = a1;
     P(1) = e2;
     P(2) = e3;
     P = P.transpose();
   }
 }
 
 /* -------------------------------------------------------------------------- */
 template <>
 inline void
 ElementClass<_discrete_kirchhoff_triangle_18>::computeRotationMatrix(
     Matrix<Real> & R, const Matrix<Real> & X, const Vector<Real> &) {
   auto dim = X.rows();
   Matrix<Real> P(dim, dim);
   detail::computeBasisChangeMatrix(P, X);
 
   R.clear();
   for (UInt i = 0; i < dim; ++i)
     for (UInt j = 0; j < dim; ++j)
       R(i + dim, j + dim) = R(i, j) = P(i, j);
 }
 
 /* -------------------------------------------------------------------------- */
 template <>
 inline void
 InterpolationElement<_itp_discrete_kirchhoff_triangle_18>::computeShapes(
     const Vector<Real> & /*natural_coords*/,
     const Matrix<Real> & /*real_coord*/, Matrix<Real> & /*N*/) {}
 
 /* -------------------------------------------------------------------------- */
 template <>
 inline void
 InterpolationElement<_itp_discrete_kirchhoff_triangle_18>::computeDNDS(
     const Vector<Real> & natural_coords, const Matrix<Real> & real_coordinates,
     Matrix<Real> & B) {
 
   auto dim = real_coordinates.cols();
   Matrix<Real> P(dim, dim);
   detail::computeBasisChangeMatrix(P, real_coordinates);
   auto X = P * real_coordinates;
   Vector<Real> X1 = X(0);
   Vector<Real> X2 = X(1);
   Vector<Real> X3 = X(2);
 
   std::array<Vector<Real>, 3> A = {X2 - X1, X3 - X2, X1 - X3};
   std::array<Real, 3> L, C, S;
 
   // Setting all last coordinates to 0
   std::for_each(A.begin(), A.end(), [](auto & a) { a(2) = 0; });
   // Computing lengths
   std::transform(A.begin(), A.end(), L.begin(),
                  [](auto & a) { return a.template norm<L_2>(); });
   // Computing cosines
   std::transform(A.begin(), A.end(), L.begin(), C.begin(),
                  [](auto & a, auto & l) { return a(0) / l; });
   // Computing sines
   std::transform(A.begin(), A.end(), L.begin(), S.begin(),
                  [](auto & a, auto & l) { return a(1) / l; });
 
   // Natural coordinates
   Real xi = natural_coords(0);
   Real eta = natural_coords(1);
 
   // Derivative of quadratic interpolation functions
   Matrix<Real> dP = {{4 * (1 - 2 * xi - eta), 4 * eta, -4 * eta},
                      {-4 * xi, 4 * xi, 4 * (1 - xi - 2 * eta)}};
 
   Matrix<Real> dNx1 = {
       {3. / 2 * (dP(0, 0) * C[0] / L[0] - dP(0, 2) * C[2] / L[2]),
        3. / 2 * (dP(0, 1) * C[1] / L[1] - dP(0, 0) * C[0] / L[0]),
        3. / 2 * (dP(0, 2) * C[2] / L[2] - dP(0, 1) * C[1] / L[1])},
       {3. / 2 * (dP(1, 0) * C[0] / L[0] - dP(1, 2) * C[2] / L[2]),
        3. / 2 * (dP(1, 1) * C[1] / L[1] - dP(1, 0) * C[0] / L[0]),
        3. / 2 * (dP(1, 2) * C[2] / L[2] - dP(1, 1) * C[1] / L[1])}};
   Matrix<Real> dNx2 = {
       // clang-format off
       {-1 - 3. / 4 * (dP(0, 0) * C[0] * C[0] + dP(0, 2) * C[2] * C[2]),
 	1 - 3. / 4 * (dP(0, 1) * C[1] * C[1] + dP(0, 0) * C[0] * C[0]),
 	  - 3. / 4 * (dP(0, 2) * C[2] * C[2] + dP(0, 1) * C[1] * C[1])},
       {-1 - 3. / 4 * (dP(1, 0) * C[0] * C[0] + dP(1, 2) * C[2] * C[2]),
 	  - 3. / 4 * (dP(1, 1) * C[1] * C[1] + dP(1, 0) * C[0] * C[0]),
 	1 - 3. / 4 * (dP(1, 2) * C[2] * C[2] + dP(1, 1) * C[1] * C[1])}};
   // clang-format on
   Matrix<Real> dNx3 = {
       {-3. / 4 * (dP(0, 0) * C[0] * S[0] + dP(0, 2) * C[2] * S[2]),
        -3. / 4 * (dP(0, 1) * C[1] * S[1] + dP(0, 0) * C[0] * S[0]),
        -3. / 4 * (dP(0, 2) * C[2] * S[2] + dP(0, 1) * C[1] * S[1])},
       {-3. / 4 * (dP(1, 0) * C[0] * S[0] + dP(1, 2) * C[2] * S[2]),
        -3. / 4 * (dP(1, 1) * C[1] * S[1] + dP(1, 0) * C[0] * S[0]),
        -3. / 4 * (dP(1, 2) * C[2] * S[2] + dP(1, 1) * C[1] * S[1])}};
   Matrix<Real> dNy1 = {
       {3. / 2 * (dP(0, 0) * S[0] / L[0] - dP(0, 2) * S[2] / L[2]),
        3. / 2 * (dP(0, 1) * S[1] / L[1] - dP(0, 0) * S[0] / L[0]),
        3. / 2 * (dP(0, 2) * S[2] / L[2] - dP(0, 1) * S[1] / L[1])},
       {3. / 2 * (dP(1, 0) * S[0] / L[0] - dP(1, 2) * S[2] / L[2]),
        3. / 2 * (dP(1, 1) * S[1] / L[1] - dP(1, 0) * S[0] / L[0]),
        3. / 2 * (dP(1, 2) * S[2] / L[2] - dP(1, 1) * S[1] / L[1])}};
   Matrix<Real> dNy2 = dNx3;
   Matrix<Real> dNy3 = {
       // clang-format off
       {-1 - 3. / 4 * (dP(0, 0) * S[0] * S[0] + dP(0, 2) * S[2] * S[2]),
 	1 - 3. / 4 * (dP(0, 1) * S[1] * S[1] + dP(0, 0) * S[0] * S[0]),
 	  - 3. / 4 * (dP(0, 2) * S[2] * S[2] + dP(0, 1) * S[1] * S[1])},
       {-1 - 3. / 4 * (dP(1, 0) * S[0] * S[0] + dP(1, 2) * S[2] * S[2]),
 	  - 3. / 4 * (dP(1, 1) * S[1] * S[1] + dP(1, 0) * S[0] * S[0]),
 	1 - 3. / 4 * (dP(1, 2) * S[2] * S[2] + dP(1, 1) * S[1] * S[1])}};
   // clang-format on
 
   // Derivative of linear (membrane mode) functions
   Matrix<Real> dNm(2, 3);
   InterpolationElement<_itp_lagrange_triangle_3, _itk_lagrangian>::computeDNDS(
       natural_coords, dNm);
 
   UInt i = 0;
   for (const Matrix<Real> & mat : {dNm, dNx1, dNx2, dNx3, dNy1, dNy2, dNy3}) {
     B.block(mat, 0, i);
     i += mat.cols();
   }
 }
 /* -------------------------------------------------------------------------- */
 template <>
 inline void
 InterpolationElement<_itp_discrete_kirchhoff_triangle_18,
                      _itk_structural>::arrangeInVoigt(const Matrix<Real> & dnds,
                                                       Matrix<Real> & B) {
   Matrix<Real> dNm(2, 3), dNx1(2, 3), dNx2(2, 3), dNx3(2, 3), dNy1(2, 3),
       dNy2(2, 3), dNy3(2, 3);
   UInt i = 0;
   for (Matrix<Real> * mat : {&dNm, &dNx1, &dNx2, &dNx3, &dNy1, &dNy2, &dNy3}) {
     *mat = dnds.block(0, i, 2, 3);
     i += mat->cols();
   }
 
   for (UInt i = 0; i < 3; ++i) {
     // clang-format off
     Matrix<Real> Bm = {{dNm(0, i), 0,         0, 0, 0, 0},
                        {0,         dNm(1, i), 0, 0, 0, 0},
                        {dNm(1, i), dNm(0, i), 0, 0, 0, 0}};
     Matrix<Real> Bf = {{0, 0, dNx1(0, i),              -dNx3(0, i),              dNx2(0, i),              0},
                        {0, 0, dNy1(1, i),              -dNy3(1, i),              dNy2(1, i),              0},
                        {0, 0, dNx1(1, i) + dNy1(0, i), -dNx3(1, i) - dNy3(0, i), dNx2(1, i) + dNy2(0, i), 0}};
     // clang-format on
     B.block(Bm, 0, i * 6);
     B.block(Bf, 3, i * 6);
   }
 }
 
 } // namespace akantu
 
 #endif /* __AKANTU_ELEMENT_CLASS_KIRCHHOFF_SHELL_INLINE_IMPL_CC__ */
diff --git a/src/fe_engine/element_classes/element_class_pentahedron_15_inline_impl.cc b/src/fe_engine/element_classes/element_class_pentahedron_15_inline_impl.cc
index 55b8b9d92..74b08b40c 100644
--- a/src/fe_engine/element_classes/element_class_pentahedron_15_inline_impl.cc
+++ b/src/fe_engine/element_classes/element_class_pentahedron_15_inline_impl.cc
@@ -1,173 +1,173 @@
 /**
  * @file   element_class_pentahedron_15_inline_impl.cc
  *
  * @author Mauro Corrado <mauro.corrado@epfl.ch>
  * @author Sacha Laffely <sacha.laffely@epfl.ch>
  * @author Damien Scantamburlo <damien.scantamburlo@epfl.ch>
  *
  * @date creation: Tue Mar 31 2015
- * @date last modification: Wed Sep 16 2015
+ * @date last modification: Thu Dec 28 2017
  *
  * @brief  Specialization of the element_class class for the type
-_pentahedron_15
+ * _pentahedron_15
  *
  * @section LICENSE
  *
- * Copyright (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne) Laboratory
- * (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * Copyright (©) 2015-2018 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
- * terms  of the  GNU Lesser  General Public  License as  published by  the Free
- * Software Foundation, either version 3 of the License, or (at your option) any
- * later version.
+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.
+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/>.
+along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  * @section DESCRIPTION
  *
  * @verbatim
              z
              ^
              |
              |
              |  1
              | /|\
              |/ | \
              10 7  6
             /   |   \
            /    |    \
            4    2--8--0
           | \  /      /
           |  \11     /
           13  12    9---------->y
           | /  \   /
           |/    \ /
           5--14--3
          /
         /
        /
       v
      x
        x   y    z
 * N0  -1   1    0
 * N1  -1   0    1
 * N2  -1   0    0
 * N3   1   1    0
 * N4   1   0    1
 * N5   1   0    0
 * N6  -1   0.5  0.5
 * N7  -1   0    0.5
 * N8  -1   0.5  0
 * N9   0   1    0
 * N10  0   0    1
 * N11  0   0    0
 * N12  1   0.5  0.5
 * N13  1   0    0.5
 * N14  1   0.5  0
  */
 
 /* -------------------------------------------------------------------------- */
 AKANTU_DEFINE_ELEMENT_CLASS_PROPERTY(_pentahedron_15, _gt_pentahedron_15,
                                      _itp_lagrange_pentahedron_15, _ek_regular,
                                      3, _git_pentahedron, 2);
 
 /* -------------------------------------------------------------------------- */
 template <>
 template <class vector_type>
 inline void InterpolationElement<_itp_lagrange_pentahedron_15>::computeShapes(
     const vector_type & c, vector_type & N) {
   auto & x = c(0);
   auto & y = c(1);
   auto & z = c(2);
 
   // Shape Functions, Natural coordinates
   N(0) = 0.5 * y * (1 - x) * (2 * y - 2 - x);
   N(1) = 0.5 * z * (1 - x) * (2 * z - 2 - x);
   N(2) = 0.5 * (x - 1) * (1 - y - z) * (x + 2 * y + 2 * z);
   N(3) = 0.5 * y * (1 + x) * (2 * y - 2 + x);
   N(4) = 0.5 * z * (1 + x) * (2 * z - 2 + x);
   N(5) = 0.5 * (-x - 1) * (1 - y - z) * (-x + 2 * y + 2 * z);
   N(6) = 2.0 * y * z * (1 - x);
   N(7) = 2.0 * z * (1 - y - z) * (1 - x);
   N(8) = 2.0 * y * (1 - x) * (1 - y - z);
   N(9) = y * (1 - x * x);
   N(10) = z * (1 - x * x);
   N(11) = (1 - y - z) * (1 - x * x);
   N(12) = 2.0 * y * z * (1 + x);
   N(13) = 2.0 * z * (1 - y - z) * (1 + x);
   N(14) = 2.0 * y * (1 - y - z) * (1 + x);
 }
 
 /* -------------------------------------------------------------------------- */
 template <>
 template <class vector_type, class matrix_type>
 inline void InterpolationElement<_itp_lagrange_pentahedron_15>::computeDNDS(
     const vector_type & c, matrix_type & dnds) {
   auto & x = c(0);
   auto & y = c(1);
   auto & z = c(2);
 
   // ddx
   dnds(0, 0) = 0.5 * y * (2 * x - 2 * y + 1);
   dnds(0, 1) = 0.5 * z * (2 * x - 2 * z + 1);
   dnds(0, 2) = -0.5 * (2 * x + 2 * y + 2 * z - 1) * (y + z - 1);
   dnds(0, 3) = 0.5 * y * (2 * x + 2 * y - 1);
   dnds(0, 4) = 0.5 * z * (2 * x + 2 * z - 1);
   dnds(0, 5) = -0.5 * (y + z - 1) * (2 * x - 2 * y - 2 * z + 1);
   dnds(0, 6) = -2.0 * y * z;
   dnds(0, 7) = 2.0 * z * (y + z - 1);
   dnds(0, 8) = 2.0 * y * (y + z - 1);
   dnds(0, 9) = -2.0 * x * y;
   dnds(0, 10) = -2.0 * x * z;
   dnds(0, 11) = 2.0 * x * (y + z - 1);
   dnds(0, 12) = 2.0 * y * z;
   dnds(0, 13) = -2.0 * z * (y + z - 1);
   dnds(0, 14) = -2.0 * y * (y + z - 1);
 
   // ddy
   dnds(1, 0) = -0.5 * (x - 1) * (4 * y - x - 2);
   dnds(1, 1) = 0.0;
   dnds(1, 2) = -0.5 * (x - 1) * (4 * y + x + 2 * (2 * z - 1));
   dnds(1, 3) = 0.5 * (x + 1) * (4 * y + x - 2);
   dnds(1, 4) = 0.0;
   dnds(1, 5) = 0.5 * (x + 1) * (4 * y - x + 2 * (2 * z - 1));
   dnds(1, 6) = -2.0 * (x - 1) * z;
   dnds(1, 7) = 2.0 * z * (x - 1);
   dnds(1, 8) = 2.0 * (2 * y + z - 1) * (x - 1);
   dnds(1, 9) = -(x * x - 1);
   dnds(1, 10) = 0.0;
   dnds(1, 11) = (x * x - 1);
   dnds(1, 12) = 2.0 * z * (x + 1);
   dnds(1, 13) = -2.0 * z * (x + 1);
   dnds(1, 14) = -2.0 * (2 * y + z - 1) * (x + 1);
 
   // ddz
   dnds(2, 0) = 0.0;
   dnds(2, 1) = -0.5 * (x - 1) * (4 * z - x - 2);
   dnds(2, 2) = -0.5 * (x - 1) * (4 * z + x + 2 * (2 * y - 1));
   dnds(2, 3) = 0.0;
   dnds(2, 4) = 0.5 * (x + 1) * (4 * z + x - 2);
   dnds(2, 5) = 0.5 * (x + 1) * (4 * z - x + 2 * (2 * y - 1));
   dnds(2, 6) = -2.0 * (x - 1) * y;
   dnds(2, 7) = 2.0 * (x - 1) * (2 * z + y - 1);
   dnds(2, 8) = 2.0 * y * (x - 1);
   dnds(2, 9) = 0.0;
   dnds(2, 10) = -(x * x - 1);
   dnds(2, 11) = (x * x - 1);
   dnds(2, 12) = 2.0 * (x + 1) * y;
   dnds(2, 13) = -2.0 * (x + 1) * (2 * z + y - 1);
   dnds(2, 14) = -2.0 * (x + 1) * y;
 }
 
 /* -------------------------------------------------------------------------- */
 template <>
 inline Real GeometricalElement<_gt_pentahedron_15>::getInradius(
     const Matrix<Real> & coord) {
   return GeometricalElement<_gt_pentahedron_6>::getInradius(coord);
 }
diff --git a/src/fe_engine/element_classes/element_class_pentahedron_6_inline_impl.cc b/src/fe_engine/element_classes/element_class_pentahedron_6_inline_impl.cc
index 806c0370b..1f7de539e 100644
--- a/src/fe_engine/element_classes/element_class_pentahedron_6_inline_impl.cc
+++ b/src/fe_engine/element_classes/element_class_pentahedron_6_inline_impl.cc
@@ -1,128 +1,127 @@
 /**
  * @file   element_class_pentahedron_6_inline_impl.cc
  *
  * @author Marion Estelle Chambart <mchambart@stucky.ch>
  * @author Mauro Corrado <mauro.corrado@epfl.ch>
  * @author Thomas Menouillard <tmenouillard@stucky.ch>
  *
  * @date creation: Mon Mar 14 2011
- * @date last modification: Tue Sep 01 2015
+ * @date last modification: Wed Oct 11 2017
  *
  * @brief  Specialization of the element_class class for the type _pentahedron_6
  *
  * @section LICENSE
  *
- * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
- * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
- * Solides)
+ * 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.
+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.
+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/>.
+along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  * @section DESCRIPTION
  *
  * @verbatim
              /z
              |
              |
              |  1
              | /|\
              |/ | \
              /  |  \
             /   |   \
            /    |    \
            4    2-----0
           | \  /      /
           |  \/      /
           |   \     /----------/y
           | /  \   /
           |/    \ /
           5---.--3
          /
         /
        /
       \x
        x   y    z
 * N0  -1   1    0
 * N1  -1   0    1
 * N2  -1   0    0
 * N3   1   1    0
 * N4   1   0    1
 * N5   1   0    0
  */
 
 /* -------------------------------------------------------------------------- */
 AKANTU_DEFINE_ELEMENT_CLASS_PROPERTY(_pentahedron_6, _gt_pentahedron_6,
                                      _itp_lagrange_pentahedron_6, _ek_regular,
                                      3, _git_pentahedron, 1);
 
 /* -------------------------------------------------------------------------- */
 template <>
 template <class vector_type>
 inline void InterpolationElement<_itp_lagrange_pentahedron_6>::computeShapes(
     const vector_type & c, vector_type & N) {
   /// Natural coordinates
   N(0) = 0.5 * c(1) * (1 - c(0));              // N1(q)
   N(1) = 0.5 * c(2) * (1 - c(0));              // N2(q)
   N(2) = 0.5 * (1 - c(1) - c(2)) * (1 - c(0)); // N3(q)
   N(3) = 0.5 * c(1) * (1 + c(0));              // N4(q)
   N(4) = 0.5 * c(2) * (1 + c(0));              // N5(q)
   N(5) = 0.5 * (1 - c(1) - c(2)) * (1 + c(0)); // N6(q)
 }
 /* -------------------------------------------------------------------------- */
 template <>
 template <class vector_type, class matrix_type>
 inline void InterpolationElement<_itp_lagrange_pentahedron_6>::computeDNDS(
     const vector_type & c, matrix_type & dnds) {
   dnds(0, 0) = -0.5 * c(1);
   dnds(0, 1) = -0.5 * c(2);
   dnds(0, 2) = -0.5 * (1 - c(1) - c(2));
   dnds(0, 3) = 0.5 * c(1);
   dnds(0, 4) = 0.5 * c(2);
   dnds(0, 5) = 0.5 * (1 - c(1) - c(2));
 
   dnds(1, 0) = 0.5 * (1 - c(0));
   dnds(1, 1) = 0.0;
   dnds(1, 2) = -0.5 * (1 - c(0));
   dnds(1, 3) = 0.5 * (1 + c(0));
   dnds(1, 4) = 0.0;
   dnds(1, 5) = -0.5 * (1 + c(0));
 
   dnds(2, 0) = 0.0;
   dnds(2, 1) = 0.5 * (1 - c(0));
   dnds(2, 2) = -0.5 * (1 - c(0));
   dnds(2, 3) = 0.0;
   dnds(2, 4) = 0.5 * (1 + c(0));
   dnds(2, 5) = -0.5 * (1 + c(0));
 }
 
 /* -------------------------------------------------------------------------- */
 template <>
 inline Real
 GeometricalElement<_gt_pentahedron_6>::getInradius(const Matrix<Real> & coord) {
   Vector<Real> u0 = coord(0);
   Vector<Real> u1 = coord(1);
   Vector<Real> u2 = coord(2);
   Vector<Real> u3 = coord(3);
 
   Real a = u0.distance(u1);
   Real b = u1.distance(u2);
   Real c = u2.distance(u3);
   Real d = u3.distance(u0);
   Real s = (a + b + c) / 2;
   Real A = std::sqrt(s * (s - a) * (s - b) * (s - c));
   Real ra = 2 * s / A;
   Real p = std::min(ra, d);
 
   return p;
 }
diff --git a/src/fe_engine/element_classes/element_class_point_1_inline_impl.cc b/src/fe_engine/element_classes/element_class_point_1_inline_impl.cc
index ff0fbb514..838767d4f 100644
--- a/src/fe_engine/element_classes/element_class_point_1_inline_impl.cc
+++ b/src/fe_engine/element_classes/element_class_point_1_inline_impl.cc
@@ -1,79 +1,78 @@
 /**
  * @file   element_class_point_1_inline_impl.cc
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Fri Jun 18 2010
- * @date last modification: Sun Oct 19 2014
+ * @date last modification: Wed Oct 11 2017
  *
  * @brief  Specialization of the element_class class for the type _point_1
  *
  * @section LICENSE
  *
- * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
- * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
- * Solides)
+ * 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.
+ 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.
+ 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/>.
+ along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  * @section DESCRIPTION
  *
  * @verbatim
       x
     (0)
  @endverbatim
  *
  * @subsection shapes Shape functions
  * @f{eqnarray*}{
  * N1 &=& 1
  * @f}
  *
  * @subsection quad_points Position of quadrature points
  * @f{eqnarray*}{
  * q_0 &=& 0
  * @f}
  */
 
 AKANTU_DEFINE_ELEMENT_CLASS_PROPERTY(_point_1, _gt_point, _itp_lagrange_point_1,
                                      _ek_regular, 0, _git_point, 1);
 
 /* -------------------------------------------------------------------------- */
 template <>
 template <class vector_type>
 inline void InterpolationElement<_itp_lagrange_point_1>::computeShapes(
     __attribute__((unused)) const vector_type & natural_coords,
     vector_type & N) {
   N(0) = 1; /// N1(q_0)
 }
 /* -------------------------------------------------------------------------- */
 template <>
 template <class vector_type, class matrix_type>
 inline void InterpolationElement<_itp_lagrange_point_1>::computeDNDS(
     __attribute__((unused)) const vector_type & natural_coords,
     __attribute__((unused)) matrix_type & dnds) {}
 
 /* -------------------------------------------------------------------------- */
 template <>
 inline void InterpolationElement<_itp_lagrange_point_1>::computeSpecialJacobian(
     __attribute__((unused)) const Matrix<Real> & J, Real & jac) {
   jac = 0.;
 }
 
 /* -------------------------------------------------------------------------- */
 template <>
 inline Real
 GeometricalElement<_gt_point>::getInradius(__attribute__((unused))
                                            const Matrix<Real> & coord) {
   return 0.;
 }
diff --git a/src/fe_engine/element_classes/element_class_quadrangle_4_inline_impl.cc b/src/fe_engine/element_classes/element_class_quadrangle_4_inline_impl.cc
index f204bc660..db3a606ad 100644
--- a/src/fe_engine/element_classes/element_class_quadrangle_4_inline_impl.cc
+++ b/src/fe_engine/element_classes/element_class_quadrangle_4_inline_impl.cc
@@ -1,155 +1,154 @@
 /**
  * @file   element_class_quadrangle_4_inline_impl.cc
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Mon Dec 13 2010
- * @date last modification: Mon Dec 08 2014
+ * @date last modification: Wed Oct 11 2017
  *
  * @brief  Specialization of the element_class class for the type _quadrangle_4
  *
  * @section LICENSE
  *
- * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
- * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
- * Solides)
+ * 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.
+ 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.
+ 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/>.
+ along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  * @section DESCRIPTION
  *
  * @verbatim
          \eta
       ^
  (-1,1)   |   (1,1)
      x---------x
      |    |    |
      |    |    |
    --|---------|----->  \xi
      |    |    |
      |    |    |
      x---------x
  (-1,-1)  |   (1,-1)
  @endverbatim
  *
  * @subsection shapes Shape functions
  * @f[
  * \begin{array}{lll}
  * N1 = (1 - \xi) (1 - \eta) / 4
  *       & \frac{\partial N1}{\partial \xi}  = - (1 - \eta) / 4
  *       & \frac{\partial N1}{\partial \eta} = - (1 - \xi) / 4 \\
  * N2 = (1 + \xi) (1 - \eta) / 4 \\
  *       & \frac{\partial N2}{\partial \xi}  = (1 - \eta) / 4
  *       & \frac{\partial N2}{\partial \eta} = - (1 + \xi) / 4 \\
  * N3 = (1 + \xi) (1 + \eta) / 4 \\
  *       & \frac{\partial N3}{\partial \xi}  = (1 + \eta) / 4
  *       & \frac{\partial N3}{\partial \eta} = (1 + \xi) / 4 \\
  * N4 = (1 - \xi) (1 + \eta) / 4
  *       & \frac{\partial N4}{\partial \xi}  = - (1 + \eta) / 4
  *       & \frac{\partial N4}{\partial \eta} = (1 - \xi) / 4 \\
  * \end{array}
  * @f]
  *
  * @subsection quad_points Position of quadrature points
  * @f{eqnarray*}{
  * \xi_{q0}  &=& 0 \qquad  \eta_{q0} = 0
  * @f}
  */
 
 /* -------------------------------------------------------------------------- */
 AKANTU_DEFINE_ELEMENT_CLASS_PROPERTY(_quadrangle_4, _gt_quadrangle_4,
                                      _itp_lagrange_quadrangle_4, _ek_regular, 2,
                                      _git_segment, 2);
 
 /* -------------------------------------------------------------------------- */
 template <>
 template <class vector_type>
 inline void InterpolationElement<_itp_lagrange_quadrangle_4>::computeShapes(
     const vector_type & c, vector_type & N) {
   N(0) = 1. / 4. * (1. - c(0)) * (1. - c(1)); /// N1(q_0)
   N(1) = 1. / 4. * (1. + c(0)) * (1. - c(1)); /// N2(q_0)
   N(2) = 1. / 4. * (1. + c(0)) * (1. + c(1)); /// N3(q_0)
   N(3) = 1. / 4. * (1. - c(0)) * (1. + c(1)); /// N4(q_0)
 }
 /* -------------------------------------------------------------------------- */
 template <>
 template <class vector_type, class matrix_type>
 inline void InterpolationElement<_itp_lagrange_quadrangle_4>::computeDNDS(
     const vector_type & c, matrix_type & dnds) {
   /**
    * @f[
    * dnds = \left(
    *          \begin{array}{cccc}
    *            \frac{\partial N1}{\partial \xi}  & \frac{\partial N2}{\partial
    * \xi}
    *               & \frac{\partial N3}{\partial \xi}  & \frac{\partial
    * N4}{\partial \xi}\\
    *            \frac{\partial N1}{\partial \eta} & \frac{\partial N2}{\partial
    * \eta}
    *               & \frac{\partial N3}{\partial \eta} & \frac{\partial
    * N4}{\partial \eta}
    *          \end{array}
    *        \right)
    * @f]
    */
 
   dnds(0, 0) = -1. / 4. * (1. - c(1));
   dnds(0, 1) = 1. / 4. * (1. - c(1));
   dnds(0, 2) = 1. / 4. * (1. + c(1));
   dnds(0, 3) = -1. / 4. * (1. + c(1));
 
   dnds(1, 0) = -1. / 4. * (1. - c(0));
   dnds(1, 1) = -1. / 4. * (1. + c(0));
   dnds(1, 2) = 1. / 4. * (1. + c(0));
   dnds(1, 3) = 1. / 4. * (1. - c(0));
 }
 
 /* -------------------------------------------------------------------------- */
 template <>
 inline void
 InterpolationElement<_itp_lagrange_quadrangle_4>::computeSpecialJacobian(
     const Matrix<Real> & J, Real & jac) {
   Vector<Real> vprod(J.cols());
   Matrix<Real> Jt(J.transpose(), true);
   vprod.crossProduct(Jt(0), Jt(1));
   jac = vprod.norm();
 }
 
 /* -------------------------------------------------------------------------- */
 template <>
 inline Real
 GeometricalElement<_gt_quadrangle_4>::getInradius(const Matrix<Real> & coord) {
   Vector<Real> u0 = coord(0);
   Vector<Real> u1 = coord(1);
   Vector<Real> u2 = coord(2);
   Vector<Real> u3 = coord(3);
   Real a = u0.distance(u1);
   Real b = u1.distance(u2);
   Real c = u2.distance(u3);
   Real d = u3.distance(u0);
 
   // Real septimetre = (a + b + c + d) / 2.;
 
   // Real p = Math::distance_2d(coord + 0, coord + 4);
   // Real q = Math::distance_2d(coord + 2, coord + 6);
 
   // Real area = sqrt(4*(p*p * q*q) - (a*a + b*b + c*c + d*d)*(a*a + c*c - b*b -
   // d*d)) / 4.;
   // Real h = sqrt(area);  // to get a length
   // Real h = area / septimetre;  // formula of inradius for circumscritable
   // quadrelateral
   Real h = std::min(a, std::min(b, std::min(c, d)));
 
   return h;
 }
diff --git a/src/fe_engine/element_classes/element_class_quadrangle_8_inline_impl.cc b/src/fe_engine/element_classes/element_class_quadrangle_8_inline_impl.cc
index df4f635ca..632d27125 100644
--- a/src/fe_engine/element_classes/element_class_quadrangle_8_inline_impl.cc
+++ b/src/fe_engine/element_classes/element_class_quadrangle_8_inline_impl.cc
@@ -1,186 +1,185 @@
 /**
  * @file   element_class_quadrangle_8_inline_impl.cc
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Wed May 18 2011
- * @date last modification: Tue Apr 07 2015
+ * @date last modification: Wed Oct 11 2017
  *
  * @brief  Specialization of the ElementClass for the _quadrangle_8
  *
  * @section LICENSE
  *
- * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
- * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
- * Solides)
+ * 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.
+ 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.
+ 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/>.
+ along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  * @section DESCRIPTION
  *
  * @verbatim
               \eta
                ^
                |
    (-1,1)    (0,1)   (1,1)
        x-------x-------x
        |       |       |
        |       |       |
        |       |       |
  (-1,0)|       |       |(1,0)
    ----x---------------X----->  \xi
        |       |       |
        |       |       |
        |       |       |
        |       |       |
        x-------x-------x
    (-1,-1)   (0,-1)  (1,-1)
                |
  @endverbatim
  *
  * @subsection shapes Shape functions
  * @f[
  * \begin{array}{lll}
  * N1 = (1 - \xi) (1 - \eta)(- 1 - \xi - \eta) / 4
  *       & \frac{\partial N1}{\partial \xi}  = (1 - \eta)(2 \xi + \eta) / 4
  *       & \frac{\partial N1}{\partial \eta} = (1 - \xi)(\xi + 2 \eta) / 4 \\
  * N2 = (1 + \xi) (1 - \eta)(- 1 + \xi - \eta) / 4 \\
  *       & \frac{\partial N2}{\partial \xi}  = (1 - \eta)(2 \xi - \eta) / 4
  *       & \frac{\partial N2}{\partial \eta} = - (1 + \xi)(\xi - 2 \eta) / 4 \\
  * N3 = (1 + \xi) (1 + \eta)(- 1 + \xi + \eta) / 4 \\
  *       & \frac{\partial N3}{\partial \xi}  = (1 + \eta)(2 \xi + \eta) / 4
  *       & \frac{\partial N3}{\partial \eta} = (1 + \xi)(\xi + 2 \eta) / 4 \\
  * N4 = (1 - \xi) (1 + \eta)(- 1 - \xi + \eta) / 4
  *       & \frac{\partial N4}{\partial \xi}  = (1 + \eta)(2 \xi - \eta) / 4
  *       & \frac{\partial N4}{\partial \eta} = - (1 - \xi)(\xi - 2 \eta) / 4 \\
  * N5 = (1 - \xi^2) (1 - \eta) / 2
  *       & \frac{\partial N1}{\partial \xi}  = - \xi (1 - \eta)
  *       & \frac{\partial N1}{\partial \eta} = - (1 - \xi^2) / 2  \\
  * N6 = (1 + \xi) (1 - \eta^2) / 2 \\
  *       & \frac{\partial N2}{\partial \xi}  = (1 - \eta^2) / 2
  *       & \frac{\partial N2}{\partial \eta} = - \eta (1 + \xi) \\
  * N7 = (1 - \xi^2) (1 + \eta) / 2 \\
  *       & \frac{\partial N3}{\partial \xi}  = - \xi (1 + \eta)
  *       & \frac{\partial N3}{\partial \eta} = (1 - \xi^2) / 2 \\
  * N8 = (1 - \xi) (1 - \eta^2) / 2
  *       & \frac{\partial N4}{\partial \xi}  = - (1 - \eta^2) / 2
  *       & \frac{\partial N4}{\partial \eta} = - \eta (1 - \xi) \\
  * \end{array}
  * @f]
  *
  * @subsection quad_points Position of quadrature points
  * @f{eqnarray*}{
  * \xi_{q0}  &=& 0 \qquad  \eta_{q0} = 0
  * @f}
  */
 
 /* -------------------------------------------------------------------------- */
 AKANTU_DEFINE_ELEMENT_CLASS_PROPERTY(_quadrangle_8, _gt_quadrangle_8,
                                      _itp_serendip_quadrangle_8, _ek_regular, 2,
                                      _git_segment, 3);
 
 /* -------------------------------------------------------------------------- */
 template <>
 template <class vector_type>
 inline void InterpolationElement<_itp_serendip_quadrangle_8>::computeShapes(
     const vector_type & c, vector_type & N) {
 
   /// Natural coordinates
   const Real xi = c(0);
   const Real eta = c(1);
 
   N(0) = .25 * (1 - xi) * (1 - eta) * (-1 - xi - eta);
   N(1) = .25 * (1 + xi) * (1 - eta) * (-1 + xi - eta);
   N(2) = .25 * (1 + xi) * (1 + eta) * (-1 + xi + eta);
   N(3) = .25 * (1 - xi) * (1 + eta) * (-1 - xi + eta);
   N(4) = .5 * (1 - xi * xi) * (1 - eta);
   N(5) = .5 * (1 + xi) * (1 - eta * eta);
   N(6) = .5 * (1 - xi * xi) * (1 + eta);
   N(7) = .5 * (1 - xi) * (1 - eta * eta);
 }
 
 /* -------------------------------------------------------------------------- */
 template <>
 template <class vector_type, class matrix_type>
 inline void InterpolationElement<_itp_serendip_quadrangle_8>::computeDNDS(
     const vector_type & c, matrix_type & dnds) {
 
   const Real xi = c(0);
   const Real eta = c(1);
 
   /// dN/dxi
   dnds(0, 0) = .25 * (1 - eta) * (2 * xi + eta);
   dnds(0, 1) = .25 * (1 - eta) * (2 * xi - eta);
   dnds(0, 2) = .25 * (1 + eta) * (2 * xi + eta);
   dnds(0, 3) = .25 * (1 + eta) * (2 * xi - eta);
   dnds(0, 4) = -xi * (1 - eta);
   dnds(0, 5) = .5 * (1 - eta * eta);
   dnds(0, 6) = -xi * (1 + eta);
   dnds(0, 7) = -.5 * (1 - eta * eta);
 
   /// dN/deta
   dnds(1, 0) = .25 * (1 - xi) * (2 * eta + xi);
   dnds(1, 1) = .25 * (1 + xi) * (2 * eta - xi);
   dnds(1, 2) = .25 * (1 + xi) * (2 * eta + xi);
   dnds(1, 3) = .25 * (1 - xi) * (2 * eta - xi);
   dnds(1, 4) = -.5 * (1 - xi * xi);
   dnds(1, 5) = -eta * (1 + xi);
   dnds(1, 6) = .5 * (1 - xi * xi);
   dnds(1, 7) = -eta * (1 - xi);
 }
 
 /* -------------------------------------------------------------------------- */
 template <>
 inline Real
 GeometricalElement<_gt_quadrangle_8>::getInradius(const Matrix<Real> & coord) {
   Real a, b, h;
 
   Vector<Real> u0 = coord(0);
   Vector<Real> u1 = coord(1);
   Vector<Real> u2 = coord(2);
   Vector<Real> u3 = coord(3);
   Vector<Real> u4 = coord(4);
   Vector<Real> u5 = coord(5);
   Vector<Real> u6 = coord(6);
   Vector<Real> u7 = coord(7);
 
   a = u0.distance(u4);
   b = u4.distance(u1);
   h = std::min(a, b);
 
   a = u1.distance(u5);
   b = u5.distance(u2);
   h = std::min(h, std::min(a, b));
 
   a = u2.distance(u6);
   b = u6.distance(u3);
   h = std::min(h, std::min(a, b));
 
   a = u3.distance(u7);
   b = u7.distance(u0);
   h = std::min(h, std::min(a, b));
 
   return h;
 }
 
 /* -------------------------------------------------------------------------- */
 template <>
 inline void
 InterpolationElement<_itp_serendip_quadrangle_8>::computeSpecialJacobian(
     const Matrix<Real> & J, Real & jac) {
   Vector<Real> vprod(J.cols());
   Matrix<Real> Jt(J.transpose(), true);
   vprod.crossProduct(Jt(0), Jt(1));
   jac = vprod.norm();
 }
diff --git a/src/fe_engine/element_classes/element_class_segment_2_inline_impl.cc b/src/fe_engine/element_classes/element_class_segment_2_inline_impl.cc
index 0ac10eca0..60a78a17c 100644
--- a/src/fe_engine/element_classes/element_class_segment_2_inline_impl.cc
+++ b/src/fe_engine/element_classes/element_class_segment_2_inline_impl.cc
@@ -1,105 +1,104 @@
 /**
  * @file   element_class_segment_2_inline_impl.cc
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Fri Jul 16 2010
- * @date last modification: Sun Oct 19 2014
+ * @date last modification: Wed Oct 11 2017
  *
  * @brief  Specialization of the element_class class for the type _segment_2
  *
  * @section LICENSE
  *
- * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
- * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
- * Solides)
+ * 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.
+ 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.
+ 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/>.
+ along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  * @section DESCRIPTION
  *
  * @verbatim
               q
    --x--------|--------x---> x
     -1        0        1
  @endverbatim
  *
  * @subsection shapes Shape functions
  * @f{eqnarray*}{
  * w_1(x) &=& 1/2(1 - x) \\
  * w_2(x) &=& 1/2(1 + x)
  * @f}
  *
  * @subsection quad_points Position of quadrature points
  * @f{eqnarray*}{
  * x_{q}  &=& 0
  * @f}
  */
 
 /* -------------------------------------------------------------------------- */
 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 <>
 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) {
   return std::abs(coord(0, 0) - coord(0, 1));
 }
 
 // /* --------------------------------------------------------------------------
 // */
 // 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;
 // }
 
 /* -------------------------------------------------------------------------- */
diff --git a/src/fe_engine/element_classes/element_class_segment_3_inline_impl.cc b/src/fe_engine/element_classes/element_class_segment_3_inline_impl.cc
index 710de16f9..3fa470a40 100644
--- a/src/fe_engine/element_classes/element_class_segment_3_inline_impl.cc
+++ b/src/fe_engine/element_classes/element_class_segment_3_inline_impl.cc
@@ -1,106 +1,105 @@
 /**
  * @file   element_class_segment_3_inline_impl.cc
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Fri Jul 16 2010
- * @date last modification: Sun Oct 19 2014
+ * @date last modification: Wed Oct 11 2017
  *
  * @brief  Specialization of the element_class class for the type _segment_3
  *
  * @section LICENSE
  *
- * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
- * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
- * Solides)
+ * 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.
+ 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.
+ 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/>.
+ along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  * @section DESCRIPTION
  *
  * @verbatim
          -1         0         1
      -----x---------x---------x-----> x
           1         3         2
  @endverbatim
  *
  * @subsection coords Nodes coordinates
  *
  * @f[
  * \begin{array}{lll}
  *   x_{1}  = -1   &  x_{2} = 1 & x_{3} = 0
  * \end{array}
  * @f]
  *
  * @subsection shapes Shape functions
  * @f[
  * \begin{array}{ll}
  *   w_1(x) = \frac{x}{2}(x - 1) & w'_1(x) = x - \frac{1}{2}\\
  *   w_2(x) = \frac{x}{2}(x + 1) & w'_2(x) = x + \frac{1}{2}\\
  *   w_3(x) =  1-x^2 & w'_3(x) = -2x
  * \end{array}
  * @f]
  *
  * @subsection quad_points Position of quadrature points
  * @f[
  * \begin{array}{ll}
  * x_{q1}  = -1/\sqrt{3} & x_{q2} = 1/\sqrt{3}
  * \end{array}
  * @f]
  */
 
 /* -------------------------------------------------------------------------- */
 AKANTU_DEFINE_ELEMENT_CLASS_PROPERTY(_segment_3, _gt_segment_3,
                                      _itp_lagrange_segment_3, _ek_regular, 1,
                                      _git_segment, 2);
 
 /* -------------------------------------------------------------------------- */
 template <>
 template <class vector_type>
 inline void InterpolationElement<_itp_lagrange_segment_3>::computeShapes(
     const vector_type & natural_coords, vector_type & N) {
 
   Real c = natural_coords(0);
   N(0) = (c - 1) * c / 2;
   N(1) = (c + 1) * c / 2;
   N(2) = 1 - c * c;
 }
 /* -------------------------------------------------------------------------- */
 template <>
 template <class vector_type, class matrix_type>
 inline void InterpolationElement<_itp_lagrange_segment_3>::computeDNDS(
     const vector_type & natural_coords, matrix_type & dnds) {
 
   Real c = natural_coords(0);
   dnds(0, 0) = c - .5;
   dnds(0, 1) = c + .5;
   dnds(0, 2) = -2 * c;
 }
 
 /* -------------------------------------------------------------------------- */
 template <>
 inline void
 InterpolationElement<_itp_lagrange_segment_3>::computeSpecialJacobian(
     const Matrix<Real> & dxds, Real & jac) {
   jac = Math::norm2(dxds.storage());
 }
 
 /* -------------------------------------------------------------------------- */
 template <>
 inline Real
 GeometricalElement<_gt_segment_3>::getInradius(const Matrix<Real> & coord) {
   Real dist1 = std::abs(coord(0, 0) - coord(0, 1));
   Real dist2 = std::abs(coord(0, 1) - coord(0, 2));
   return std::min(dist1, dist2);
 }
diff --git a/src/fe_engine/element_classes/element_class_tetrahedron_10_inline_impl.cc b/src/fe_engine/element_classes/element_class_tetrahedron_10_inline_impl.cc
index f5dab36fa..f1df60b6e 100644
--- a/src/fe_engine/element_classes/element_class_tetrahedron_10_inline_impl.cc
+++ b/src/fe_engine/element_classes/element_class_tetrahedron_10_inline_impl.cc
@@ -1,278 +1,277 @@
 /**
  * @file   element_class_tetrahedron_10_inline_impl.cc
  *
  * @author Peter Spijker <peter.spijker@epfl.ch>
  *
  * @date creation: Fri Jul 16 2010
- * @date last modification: Sun Oct 19 2014
+ * @date last modification: Wed Oct 11 2017
  *
  * @brief  Specialization of the element_class class for the type
- _tetrahedron_10
+ * _tetrahedron_10
  *
  * @section LICENSE
  *
- * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
- * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
- * Solides)
+ * 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.
+ 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.
+ 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/>.
+ along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  * @section DESCRIPTION
  *
  * @verbatim
  \zeta
  ^
  |
  (0,0,1)
  x
  |` .
  |  `  .
  |    `   .
  |      `    .  (0,0.5,0.5)
  |        `    x.
  |     q4 o `      .                   \eta
  |            `       .             -,
  (0,0,0.5) x             ` x (0.5,0,0.5)  -
  |                `        x-(0,1,0)
  |              q3 o`   -   '
  |       (0,0.5,0)  - `      '
  |             x-       `     x (0.5,0.5,0)
  |     q1 o -         o q2`    '
  |      -                   `   '
  |  -                         `  '
  x---------------x--------------` x-----> \xi
  (0,0,0)        (0.5,0,0)        (1,0,0)
  @endverbatim
  *
  * @subsection coords Nodes coordinates
  *
  * @f[
  * \begin{array}{lll}
  *   \xi_{0}  = 0   &  \eta_{0}  = 0   &  \zeta_{0}  = 0   \\
  *   \xi_{1}  = 1   &  \eta_{1}  = 0   &  \zeta_{1}  = 0   \\
  *   \xi_{2}  = 0   &  \eta_{2}  = 1   &  \zeta_{2}  = 0   \\
  *   \xi_{3}  = 0   &  \eta_{3}  = 0   &  \zeta_{3}  = 1   \\
  *   \xi_{4}  = 1/2 &  \eta_{4}  = 0   &  \zeta_{4}  = 0   \\
  *   \xi_{5}  = 1/2 &  \eta_{5}  = 1/2 &  \zeta_{5}  = 0   \\
  *   \xi_{6}  = 0   &  \eta_{6}  = 1/2 &  \zeta_{6}  = 0   \\
  *   \xi_{7}  = 0   &  \eta_{7}  = 0   &  \zeta_{7}  = 1/2 \\
  *   \xi_{8}  = 1/2 &  \eta_{8}  = 0   &  \zeta_{8}  = 1/2 \\
  *   \xi_{9}  = 0   &  \eta_{9}  = 1/2 &  \zeta_{9}  = 1/2
  * \end{array}
  * @f]
  *
  * @subsection shapes Shape functions
  * @f[
  * \begin{array}{llll}
  *     N1  = (1 - \xi - \eta - \zeta) (1 - 2 \xi - 2 \eta - 2 \zeta)
  *           & \frac{\partial N1}{\partial \xi}    = 4 \xi + 4 \eta + 4 \zeta -
  3
  *           & \frac{\partial N1}{\partial \eta}   = 4 \xi + 4 \eta + 4 \zeta -
  3
  *           & \frac{\partial N1}{\partial \zeta}  = 4 \xi + 4 \eta + 4 \zeta -
  3 \\
  *     N2  = \xi (2 \xi - 1)
  *           & \frac{\partial N2}{\partial \xi}    = 4 \xi - 1
  *           & \frac{\partial N2}{\partial \eta}   = 0
  *           & \frac{\partial N2}{\partial \zeta}  = 0 \\
  *     N3  = \eta (2 \eta - 1)
  *           & \frac{\partial N3}{\partial \xi}    = 0
  *           & \frac{\partial N3}{\partial \eta}   = 4 \eta - 1
  *           & \frac{\partial N3}{\partial \zeta}  = 0 \\
  *     N4  = \zeta (2 \zeta - 1)
  *           & \frac{\partial N4}{\partial \xi}    = 0
  *           & \frac{\partial N4}{\partial \eta}   = 0
  *           & \frac{\partial N4}{\partial \zeta}  = 4 \zeta - 1 \\
  *     N5  = 4 \xi (1 - \xi - \eta - \zeta)
  *           & \frac{\partial N5}{\partial \xi}    = 4 - 8 \xi - 4 \eta - 4
  \zeta
  *           & \frac{\partial N5}{\partial \eta}   = -4 \xi
  *           & \frac{\partial N5}{\partial \zeta}  = -4 \xi \\
  *     N6  = 4 \xi \eta
  *           & \frac{\partial N6}{\partial \xi}    = 4 \eta
  *           & \frac{\partial N6}{\partial \eta}   = 4 \xi
  *           & \frac{\partial N6}{\partial \zeta}  = 0 \\
  *     N7  = 4 \eta (1 - \xi - \eta - \zeta)
  *           & \frac{\partial N7}{\partial \xi}    = -4 \eta
  *           & \frac{\partial N7}{\partial \eta}   = 4 - 4 \xi - 8 \eta - 4
  \zeta
  *           & \frac{\partial N7}{\partial \zeta}  = -4 \eta \\
  *     N8  = 4 \zeta (1 - \xi - \eta - \zeta)
  *           & \frac{\partial N8}{\partial \xi}    = -4 \zeta
  *           & \frac{\partial N8}{\partial \eta}   = -4 \zeta
  *           & \frac{\partial N8}{\partial \zeta}  = 4 - 4 \xi - 4 \eta - 8
  \zeta \\
  *     N9  = 4 \zeta \xi
  *           & \frac{\partial N9}{\partial \xi}    = 4 \zeta
  *           & \frac{\partial N9}{\partial \eta}   = 0
  *           & \frac{\partial N9}{\partial \zeta}  = 4 \xi \\
  *     N10 = 4 \eta \zeta
  *           & \frac{\partial N10}{\partial \xi}   = 0
  *           & \frac{\partial N10}{\partial \eta}  = 4 \zeta
  *           & \frac{\partial N10}{\partial \zeta} = 4 \eta \\
  * \end{array}
  * @f]
  *
  * @subsection quad_points Position of quadrature points
  * @f[
  * a = \frac{5 - \sqrt{5}}{20}\\
  * b = \frac{5 + 3 \sqrt{5}}{20}
  * \begin{array}{lll}
  *   \xi_{q_0}  = a   &  \eta_{q_0}  = a   &  \zeta_{q_0}  = a \\
  *   \xi_{q_1}  = b   &  \eta_{q_1}  = a   &  \zeta_{q_1}  = a \\
  *   \xi_{q_2}  = a   &  \eta_{q_2}  = b   &  \zeta_{q_2}  = a \\
  *   \xi_{q_3}  = a   &  \eta_{q_3}  = a   &  \zeta_{q_3}  = b
  * \end{array}
  * @f]
  */
 
 /* -------------------------------------------------------------------------- */
 AKANTU_DEFINE_ELEMENT_CLASS_PROPERTY(_tetrahedron_10, _gt_tetrahedron_10,
                                      _itp_lagrange_tetrahedron_10, _ek_regular,
                                      3, _git_tetrahedron, 2);
 
 /* -------------------------------------------------------------------------- */
 template <>
 template <class vector_type>
 inline void InterpolationElement<_itp_lagrange_tetrahedron_10>::computeShapes(
     const vector_type & natural_coords, vector_type & N) {
   /// Natural coordinates
   Real xi = natural_coords(0);
   Real eta = natural_coords(1);
   Real zeta = natural_coords(2);
   Real sum = xi + eta + zeta;
   Real c0 = 1 - sum;
   Real c1 = 1 - 2 * sum;
   Real c2 = 2 * xi - 1;
   Real c3 = 2 * eta - 1;
   Real c4 = 2 * zeta - 1;
 
   /// Shape functions
   N(0) = c0 * c1;
   N(1) = xi * c2;
   N(2) = eta * c3;
   N(3) = zeta * c4;
   N(4) = 4 * xi * c0;
   N(5) = 4 * xi * eta;
   N(6) = 4 * eta * c0;
   N(7) = 4 * zeta * c0;
   N(8) = 4 * xi * zeta;
   N(9) = 4 * eta * zeta;
 }
 
 /* -------------------------------------------------------------------------- */
 template <>
 template <class vector_type, class matrix_type>
 inline void InterpolationElement<_itp_lagrange_tetrahedron_10>::computeDNDS(
     const vector_type & natural_coords, matrix_type & dnds) {
   /**
    * @f[
    * dnds = \left(
    *          \begin{array}{cccccccccc}
    *            \frac{\partial N1}{\partial \xi}   & \frac{\partial N2}{\partial
    * \xi}
    *          & \frac{\partial N3}{\partial \xi}   & \frac{\partial N4}{\partial
    * \xi}
    *          & \frac{\partial N5}{\partial \xi}   & \frac{\partial N6}{\partial
    * \xi}
    *          & \frac{\partial N7}{\partial \xi}   & \frac{\partial N8}{\partial
    * \xi}
    *          & \frac{\partial N9}{\partial \xi}   & \frac{\partial
    * N10}{\partial \xi} \\
    *            \frac{\partial N1}{\partial \eta}  & \frac{\partial N2}{\partial
    * \eta}
    *          & \frac{\partial N3}{\partial \eta}  & \frac{\partial N4}{\partial
    * \eta}
    *          & \frac{\partial N5}{\partial \eta}  & \frac{\partial N6}{\partial
    * \eta}
    *          & \frac{\partial N7}{\partial \eta}  & \frac{\partial N8}{\partial
    * \eta}
    *          & \frac{\partial N9}{\partial \eta}  & \frac{\partial
    * N10}{\partial \eta} \\
    *            \frac{\partial N1}{\partial \zeta} & \frac{\partial N2}{\partial
    * \zeta}
    *          & \frac{\partial N3}{\partial \zeta} & \frac{\partial N4}{\partial
    * \zeta}
    *          & \frac{\partial N5}{\partial \zeta} & \frac{\partial N6}{\partial
    * \zeta}
    *          & \frac{\partial N7}{\partial \zeta} & \frac{\partial N8}{\partial
    * \zeta}
    *          & \frac{\partial N9}{\partial \zeta} & \frac{\partial
    * N10}{\partial \zeta}
    *          \end{array}
    *        \right)
    * @f]
    */
 
   /// Natural coordinates
   Real xi = natural_coords(0);
   Real eta = natural_coords(1);
   Real zeta = natural_coords(2);
   Real sum = xi + eta + zeta;
 
   /// \frac{\partial N_i}{\partial \xi}
   dnds(0, 0) = 4 * sum - 3;
   dnds(0, 1) = 4 * xi - 1;
   dnds(0, 2) = 0;
   dnds(0, 3) = 0;
   dnds(0, 4) = 4 * (1 - sum - xi);
   dnds(0, 5) = 4 * eta;
   dnds(0, 6) = -4 * eta;
   dnds(0, 7) = -4 * zeta;
   dnds(0, 8) = 4 * zeta;
   dnds(0, 9) = 0;
 
   /// \frac{\partial N_i}{\partial \eta}
   dnds(1, 0) = 4 * sum - 3;
   dnds(1, 1) = 0;
   dnds(1, 2) = 4 * eta - 1;
   dnds(1, 3) = 0;
   dnds(1, 4) = -4 * xi;
   dnds(1, 5) = 4 * xi;
   dnds(1, 6) = 4 * (1 - sum - eta);
   dnds(1, 7) = -4 * zeta;
   dnds(1, 8) = 0;
   dnds(1, 9) = 4 * zeta;
 
   /// \frac{\partial N_i}{\partial \zeta}
   dnds(2, 0) = 4 * sum - 3;
   dnds(2, 1) = 0;
   dnds(2, 2) = 0;
   dnds(2, 3) = 4 * zeta - 1;
   dnds(2, 4) = -4 * xi;
   dnds(2, 5) = 0;
   dnds(2, 6) = -4 * eta;
   dnds(2, 7) = 4 * (1 - sum - zeta);
   dnds(2, 8) = 4 * xi;
   dnds(2, 9) = 4 * eta;
 }
 
 /* -------------------------------------------------------------------------- */
 template <>
 inline Real GeometricalElement<_gt_tetrahedron_10>::getInradius(
     const Matrix<Real> & coord) {
   // Only take the four corner tetrahedra
   UInt tetrahedra[4][4] = {
       {0, 4, 6, 7}, {4, 1, 5, 8}, {6, 5, 2, 9}, {7, 8, 9, 3}};
 
   Real inradius = std::numeric_limits<Real>::max();
   for (UInt t = 0; t < 4; t++) {
     Real ir = Math::tetrahedron_inradius(
         coord(tetrahedra[t][0]).storage(), coord(tetrahedra[t][1]).storage(),
         coord(tetrahedra[t][2]).storage(), coord(tetrahedra[t][3]).storage());
     inradius = std::min(ir, inradius);
   }
 
   return inradius;
 }
diff --git a/src/fe_engine/element_classes/element_class_tetrahedron_4_inline_impl.cc b/src/fe_engine/element_classes/element_class_tetrahedron_4_inline_impl.cc
index 76f6d85bc..5577d6c3b 100644
--- a/src/fe_engine/element_classes/element_class_tetrahedron_4_inline_impl.cc
+++ b/src/fe_engine/element_classes/element_class_tetrahedron_4_inline_impl.cc
@@ -1,134 +1,133 @@
 /**
  * @file   element_class_tetrahedron_4_inline_impl.cc
  *
  * @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Fri Jul 16 2010
- * @date last modification: Sun Oct 19 2014
+ * @date last modification: Wed Oct 11 2017
  *
  * @brief  Specialization of the element_class class for the type _tetrahedron_4
  *
  * @section LICENSE
  *
- * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
- * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
- * Solides)
+ * 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.
+ 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.
+ 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/>.
+ along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  * @section DESCRIPTION
  *
  * @verbatim
    \eta
      ^
      |
      x (0,0,1,0)
      |`
      |  `  °             \xi
      |    `    °       -
      |      `       x (0,0,0,1)
      |      q.`   -  '
      |         -`     '
      |     -       `   '
      | -             `  '
      x------------------x-----> \zeta
  (1,0,0,0)           (0,1,0,0)
  @endverbatim
  *
  * @subsection shapes Shape functions
  * @f{eqnarray*}{
  * N1 &=& 1 - \xi - \eta - \zeta \\
  * N2 &=& \xi \\
  * N3 &=& \eta \\
  * N4 &=& \zeta
  * @f}
  *
  * @subsection quad_points Position of quadrature points
  * @f[
  * \xi_{q0} = 1/4 \qquad  \eta_{q0} = 1/4  \qquad  \zeta_{q0} = 1/4
  * @f]
  */
 
 /* -------------------------------------------------------------------------- */
 AKANTU_DEFINE_ELEMENT_CLASS_PROPERTY(_tetrahedron_4, _gt_tetrahedron_4,
                                      _itp_lagrange_tetrahedron_4, _ek_regular,
                                      3, _git_tetrahedron, 1);
 
 /* -------------------------------------------------------------------------- */
 template <>
 template <class vector_type>
 inline void InterpolationElement<_itp_lagrange_tetrahedron_4>::computeShapes(
     const vector_type & natural_coords, vector_type & N) {
 
   Real c0 = 1 - natural_coords(0) - natural_coords(1) -
             natural_coords(2); /// @f$ c2 = 1 - \xi - \eta - \zeta @f$
   Real c1 = natural_coords(1); /// @f$ c0 = \xi @f$
   Real c2 = natural_coords(2); /// @f$ c1 = \eta @f$
   Real c3 = natural_coords(0); /// @f$ c2 = \zeta @f$
 
   N(0) = c0;
   N(1) = c1;
   N(2) = c2;
   N(3) = c3;
 }
 /* -------------------------------------------------------------------------- */
 template <>
 template <class vector_type, class matrix_type>
 inline void InterpolationElement<_itp_lagrange_tetrahedron_4>::computeDNDS(
     __attribute__((unused)) const vector_type & natural_coords,
     matrix_type & dnds) {
 
   /**
    * @f[
    * dnds = \left(
    *          \begin{array}{cccccc}
    *            \frac{\partial N1}{\partial \xi}   & \frac{\partial N2}{\partial
    * \xi}
    *          & \frac{\partial N3}{\partial \xi}   & \frac{\partial N4}{\partial
    * \xi} \\
    *            \frac{\partial N1}{\partial \eta}  & \frac{\partial N2}{\partial
    * \eta}
    *          & \frac{\partial N3}{\partial \eta}  & \frac{\partial N4}{\partial
    * \eta} \\
    *            \frac{\partial N1}{\partial \zeta} & \frac{\partial N2}{\partial
    * \zeta}
    *          & \frac{\partial N3}{\partial \zeta} & \frac{\partial N4}{\partial
    * \zeta}
    *          \end{array}
    *        \right)
    * @f]
    */
 
   dnds(0, 0) = -1.;
   dnds(0, 1) = 1.;
   dnds(0, 2) = 0.;
   dnds(0, 3) = 0.;
   dnds(1, 0) = -1.;
   dnds(1, 1) = 0.;
   dnds(1, 2) = 1.;
   dnds(1, 3) = 0.;
   dnds(2, 0) = -1.;
   dnds(2, 1) = 0.;
   dnds(2, 2) = 0.;
   dnds(2, 3) = 1.;
 }
 
 /* -------------------------------------------------------------------------- */
 template <>
 inline Real
 GeometricalElement<_gt_tetrahedron_4>::getInradius(const Matrix<Real> & coord) {
   return Math::tetrahedron_inradius(coord(0).storage(), coord(1).storage(),
                                     coord(2).storage(), coord(3).storage());
 }
diff --git a/src/fe_engine/element_classes/element_class_triangle_3_inline_impl.cc b/src/fe_engine/element_classes/element_class_triangle_3_inline_impl.cc
index 1b17994d1..77ff9458e 100644
--- a/src/fe_engine/element_classes/element_class_triangle_3_inline_impl.cc
+++ b/src/fe_engine/element_classes/element_class_triangle_3_inline_impl.cc
@@ -1,134 +1,133 @@
 /**
  * @file   element_class_triangle_3_inline_impl.cc
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Fri Jul 16 2010
- * @date last modification: Sun Oct 19 2014
+ * @date last modification: Wed Oct 11 2017
  *
  * @brief  Specialization of the element_class class for the type _triangle_3
  *
  * @section LICENSE
  *
- * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
- * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
- * Solides)
+ * 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.
+ 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.
+ 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/>.
+ along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  * @section DESCRIPTION
  *
  * @verbatim
        \eta
      ^
      |
      x (0,0,1)
      |`
      |  `
      |  q `
      |  °   `
      x--------x----->  \xi
     (1,0,0)      (0,1,0)
  @endverbatim
  *
  * @subsection shapes Shape functions
  * @f{eqnarray*}{
  * N1 &=& 1 - \xi - \eta \\
  * N2 &=& \xi \\
  * N3 &=& \eta
  * @f}
  *
  * @subsection quad_points Position of quadrature points
  * @f{eqnarray*}{
  * \xi_{q0}  &=& 1/3 \qquad  \eta_{q0} = 1/3
  * @f}
  */
 
 /* -------------------------------------------------------------------------- */
 AKANTU_DEFINE_ELEMENT_CLASS_PROPERTY(_triangle_3, _gt_triangle_3,
                                      _itp_lagrange_triangle_3, _ek_regular, 2,
                                      _git_triangle, 1);
 
 /* -------------------------------------------------------------------------- */
 template <>
 template <class vector_type>
 inline void InterpolationElement<_itp_lagrange_triangle_3>::computeShapes(
     const vector_type & natural_coords, vector_type & N) {
 
   /// Natural coordinates
   Real c0 =
       1 - natural_coords(0) - natural_coords(1); /// @f$ c0 = 1 - \xi - \eta @f$
   Real c1 = natural_coords(0);                   /// @f$ c1 = \xi @f$
   Real c2 = natural_coords(1);                   /// @f$ c2 = \eta @f$
 
   N(0) = c0; /// N1(q_0)
   N(1) = c1; /// N2(q_0)
   N(2) = c2; /// N3(q_0)
 }
 /* -------------------------------------------------------------------------- */
 template <>
 template <class vector_type, class matrix_type>
 inline void InterpolationElement<_itp_lagrange_triangle_3>::computeDNDS(
     __attribute__((unused)) const vector_type & natural_coords,
     matrix_type & dnds) {
   /**
    * @f[
    * dnds = \left(
    *          \begin{array}{cccccc}
    *            \frac{\partial N1}{\partial \xi}  & \frac{\partial N2}{\partial
    * \xi}  & \frac{\partial N3}{\partial \xi} \\
    *            \frac{\partial N1}{\partial \eta} & \frac{\partial N2}{\partial
    * \eta} & \frac{\partial N3}{\partial \eta}
    *          \end{array}
    *        \right)
    * @f]
    */
   dnds(0, 0) = -1.;
   dnds(0, 1) = 1.;
   dnds(0, 2) = 0.;
   dnds(1, 0) = -1.;
   dnds(1, 1) = 0.;
   dnds(1, 2) = 1.;
 }
 
 /* -------------------------------------------------------------------------- */
 template <>
 inline void
 InterpolationElement<_itp_lagrange_triangle_3>::computeSpecialJacobian(
     const Matrix<Real> & J, Real & jac) {
   Vector<Real> vprod(J.cols());
   Matrix<Real> Jt(J.transpose(), true);
   vprod.crossProduct(Jt(0), Jt(1));
   jac = vprod.norm();
 }
 
 /* -------------------------------------------------------------------------- */
 template <>
 inline Real
 GeometricalElement<_gt_triangle_3>::getInradius(const Matrix<Real> & coord) {
   return Math::triangle_inradius(coord(0).storage(), coord(1).storage(),
                                  coord(2).storage());
 }
 
 /* -------------------------------------------------------------------------- */
 // template<> inline bool ElementClass<_triangle_3>::contains(const Vector<Real>
 // & natural_coords) {
 //   if (natural_coords[0] < 0.) return false;
 //   if (natural_coords[0] > 1.) return false;
 //   if (natural_coords[1] < 0.) return false;
 //   if (natural_coords[1] > 1.) return false;
 //   if (natural_coords[0]+natural_coords[1] > 1.) return false;
 //   return true;
 // }
 /* -------------------------------------------------------------------------- */
diff --git a/src/fe_engine/element_classes/element_class_triangle_6_inline_impl.cc b/src/fe_engine/element_classes/element_class_triangle_6_inline_impl.cc
index 7ccb1a5a3..aa8b3a53d 100644
--- a/src/fe_engine/element_classes/element_class_triangle_6_inline_impl.cc
+++ b/src/fe_engine/element_classes/element_class_triangle_6_inline_impl.cc
@@ -1,200 +1,199 @@
 /**
  * @file   element_class_triangle_6_inline_impl.cc
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Fri Jul 16 2010
- * @date last modification: Sun Oct 19 2014
+ * @date last modification: Wed Oct 11 2017
  *
  * @brief  Specialization of the element_class class for the type _triangle_6
  *
  * @section LICENSE
  *
- * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
- * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
- * Solides)
+ * 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.
+ 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.
+ 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/>.
+ along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  * @section DESCRIPTION
  *
  * @verbatim
         \eta
           ^
           |
           x 2
           | `
           |   `
           |  .  `
           |   q2  `
         5 x          x 4
           |           `
           |             `
           |  .q0     q1.  `
           |                 `
           x---------x---------x-----> \xi
           0         3         1
  @endverbatim
  *
  * @subsection coords Nodes coordinates
  *
  * @f[
  * \begin{array}{ll}
  *   \xi_{0}  = 0   &  \eta_{0} = 0   \\
  *   \xi_{1}  = 1   &  \eta_{1} = 0   \\
  *   \xi_{2}  = 0   &  \eta_{2} = 1   \\
  *   \xi_{3}  = 1/2 &  \eta_{3} = 0   \\
  *   \xi_{4}  = 1/2 &  \eta_{4} = 1/2 \\
  *   \xi_{5}  = 0   &  \eta_{5} = 1/2
  * \end{array}
  * @f]
  *
  * @subsection shapes Shape functions
  * @f[
  * \begin{array}{lll}
  * N1 = -(1 - \xi - \eta) (1 - 2 (1 - \xi - \eta))
  *       & \frac{\partial N1}{\partial \xi}  = 1 - 4(1 - \xi - \eta)
  *       & \frac{\partial N1}{\partial \eta} = 1 - 4(1 - \xi - \eta) \\
  * N2 = - \xi (1 - 2 \xi)
  *       & \frac{\partial N2}{\partial \xi}  = - 1 + 4 \xi
  *       & \frac{\partial N2}{\partial \eta} = 0 \\
  * N3 = - \eta (1 - 2 \eta)
  *       & \frac{\partial N3}{\partial \xi}  = 0
  *       & \frac{\partial N3}{\partial \eta} = - 1 + 4 \eta \\
  * N4 = 4 \xi (1 - \xi - \eta)
  *       & \frac{\partial N4}{\partial \xi}  = 4 (1 - 2 \xi - \eta)
  *       & \frac{\partial N4}{\partial \eta} = - 4 \xi \\
  * N5 = 4 \xi \eta
  *       & \frac{\partial N5}{\partial \xi}  = 4 \eta
  *       & \frac{\partial N5}{\partial \eta} = 4 \xi \\
  * N6 = 4 \eta (1 - \xi - \eta)
  *       & \frac{\partial N6}{\partial \xi}  = - 4 \eta
  *       & \frac{\partial N6}{\partial \eta} = 4 (1 - \xi - 2 \eta)
  * \end{array}
  * @f]
  *
  * @subsection quad_points Position of quadrature points
  * @f{eqnarray*}{
  * \xi_{q0}  &=& 1/6 \qquad  \eta_{q0} = 1/6 \\
  * \xi_{q1}  &=& 2/3 \qquad  \eta_{q1} = 1/6 \\
  * \xi_{q2}  &=& 1/6 \qquad  \eta_{q2} = 2/3
  * @f}
  */
 
 /* -------------------------------------------------------------------------- */
 AKANTU_DEFINE_ELEMENT_CLASS_PROPERTY(_triangle_6, _gt_triangle_6,
                                      _itp_lagrange_triangle_6, _ek_regular, 2,
                                      _git_triangle, 2);
 
 /* -------------------------------------------------------------------------- */
 
 template <>
 template <class vector_type>
 inline void InterpolationElement<_itp_lagrange_triangle_6>::computeShapes(
     const vector_type & natural_coords, vector_type & N) {
   /// Natural coordinates
   Real c0 =
       1 - natural_coords(0) - natural_coords(1); /// @f$ c0 = 1 - \xi - \eta @f$
   Real c1 = natural_coords(0);                   /// @f$ c1 = \xi @f$
   Real c2 = natural_coords(1);                   /// @f$ c2 = \eta @f$
 
   N(0) = c0 * (2 * c0 - 1.);
   N(1) = c1 * (2 * c1 - 1.);
   N(2) = c2 * (2 * c2 - 1.);
   N(3) = 4 * c0 * c1;
   N(4) = 4 * c1 * c2;
   N(5) = 4 * c2 * c0;
 }
 /* -------------------------------------------------------------------------- */
 template <>
 template <class vector_type, class matrix_type>
 inline void InterpolationElement<_itp_lagrange_triangle_6>::computeDNDS(
     const vector_type & natural_coords, matrix_type & dnds) {
 
   /**
    * @f[
    * dnds =  \left(
    *   \begin{array}{cccccc}
    *       \frac{\partial N1}{\partial \xi}
    *     & \frac{\partial N2}{\partial \xi}
    *     & \frac{\partial N3}{\partial \xi}
    *     & \frac{\partial N4}{\partial \xi}
    *     & \frac{\partial N5}{\partial \xi}
    *     & \frac{\partial N6}{\partial \xi} \\
    *
    *       \frac{\partial N1}{\partial \eta}
    *     & \frac{\partial N2}{\partial \eta}
    *     & \frac{\partial N3}{\partial \eta}
    *     & \frac{\partial N4}{\partial \eta}
    *     & \frac{\partial N5}{\partial \eta}
    *     & \frac{\partial N6}{\partial \eta}
    *   \end{array}
    * \right)
    * @f]
    */
 
   /// Natural coordinates
   Real c0 =
       1 - natural_coords(0) - natural_coords(1); /// @f$ c0 = 1 - \xi - \eta @f$
   Real c1 = natural_coords(0);                   /// @f$ c1 = \xi @f$
   Real c2 = natural_coords(1);                   /// @f$ c2 = \eta @f$
 
   dnds(0, 0) = 1 - 4 * c0;
   dnds(0, 1) = 4 * c1 - 1.;
   dnds(0, 2) = 0.;
   dnds(0, 3) = 4 * (c0 - c1);
   dnds(0, 4) = 4 * c2;
   dnds(0, 5) = -4 * c2;
 
   dnds(1, 0) = 1 - 4 * c0;
   dnds(1, 1) = 0.;
   dnds(1, 2) = 4 * c2 - 1.;
   dnds(1, 3) = -4 * c1;
   dnds(1, 4) = 4 * c1;
   dnds(1, 5) = 4 * (c0 - c2);
 }
 
 /* -------------------------------------------------------------------------- */
 template <>
 inline void
 InterpolationElement<_itp_lagrange_triangle_6>::computeSpecialJacobian(
     const Matrix<Real> & J, Real & jac) {
   Vector<Real> vprod(J.cols());
   Matrix<Real> Jt(J.transpose(), true);
   vprod.crossProduct(Jt(0), Jt(1));
   jac = vprod.norm();
 }
 
 /* -------------------------------------------------------------------------- */
 template <>
 inline Real
 GeometricalElement<_gt_triangle_6>::getInradius(const Matrix<Real> & coord) {
   UInt triangles[4][3] = {{0, 3, 5}, {3, 1, 4}, {3, 4, 5}, {5, 4, 2}};
 
   Real inradius = std::numeric_limits<Real>::max();
   for (UInt t = 0; t < 4; t++) {
     Real ir = Math::triangle_inradius(coord(triangles[t][0]).storage(),
                                       coord(triangles[t][1]).storage(),
                                       coord(triangles[t][2]).storage());
     inradius = std::min(ir, inradius);
   }
 
   return inradius;
 }
 
 /* -------------------------------------------------------------------------- */
 // template<> inline bool ElementClass<_triangle_6>::contains(const Vector<Real>
 // & natural_coords) {
 //   return ElementClass<_triangle_3>::contains(natural_coords);
 // }
diff --git a/src/fe_engine/element_type_conversion.hh b/src/fe_engine/element_type_conversion.hh
index bf9ac699e..124ad9c77 100644
--- a/src/fe_engine/element_type_conversion.hh
+++ b/src/fe_engine/element_type_conversion.hh
@@ -1,55 +1,57 @@
 /**
  * @file   element_type_conversion.hh
  *
- * @author Nicolas Richart
+ * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
- * @date creation  Thu Jul 27 2017
+ * @date creation: Fri Jun 18 2010
+ * @date last modification: Fri Aug 11 2017
  *
- * @brief conversion between different types
+ * @brief  conversion between different types
  *
  * @section LICENSE
  *
- * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * 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
+ * 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
+ * A PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
+
 /* -------------------------------------------------------------------------- */
 #include "element_class.hh"
 /* -------------------------------------------------------------------------- */
 
 #ifndef __AKANTU_ELEMENT_TYPE_CONVERSION_HH__
 #define __AKANTU_ELEMENT_TYPE_CONVERSION_HH__
 
 namespace akantu {
 
 template <class InType, class OutType> OutType convertType(const InType &) {
   return OutType();
 }
 
 template <>
 inline InterpolationType
 convertType<ElementType, InterpolationType>(const ElementType & type) {
   InterpolationType itp_type = _itp_not_defined;
 #define GET_ITP(type) itp_type = ElementClassProperty<type>::interpolation_type;
 
   AKANTU_BOOST_ALL_ELEMENT_SWITCH(GET_ITP);
 #undef GET_ITP
   return itp_type;
 }
 
 } // namespace akantu
 
 #endif /* __AKANTU_ELEMENT_TYPE_CONVERSION_HH__ */
diff --git a/src/fe_engine/fe_engine.cc b/src/fe_engine/fe_engine.cc
index 95a2d29a2..23bc02714 100644
--- a/src/fe_engine/fe_engine.cc
+++ b/src/fe_engine/fe_engine.cc
@@ -1,95 +1,94 @@
 /**
  * @file   fe_engine.cc
  *
  * @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Tue Jul 20 2010
- * @date last modification: Fri Dec 11 2015
+ * @date last modification: Thu Feb 01 2018
  *
  * @brief  Implementation of the FEEngine class
  *
  * @section LICENSE
  *
- * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
- * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
- * Solides)
+ * 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
+ * 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
+ * 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 "fe_engine.hh"
 #include "aka_memory.hh"
 #include "mesh.hh"
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 FEEngine::FEEngine(Mesh & mesh, UInt element_dimension, const ID & id,
                    MemoryID memory_id)
     : Memory(id, memory_id), mesh(mesh),
       normals_on_integration_points("normals_on_quad_points", id, memory_id) {
   AKANTU_DEBUG_IN();
   this->element_dimension = (element_dimension != _all_dimensions)
                                 ? element_dimension
                                 : mesh.getSpatialDimension();
 
   this->mesh.registerEventHandler(*this, _ehp_fe_engine);
 
   init();
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void FEEngine::init() {}
 
 /* -------------------------------------------------------------------------- */
 FEEngine::~FEEngine() {
   AKANTU_DEBUG_IN();
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 typename FEEngine::ElementTypesIteratorHelper
 FEEngine::elementTypes(UInt dim, GhostType ghost_type, ElementKind kind) const {
   return this->getIntegratorInterface().getJacobians().elementTypes(
       dim, ghost_type, kind);
 }
 
 /* -------------------------------------------------------------------------- */
 void FEEngine::printself(std::ostream & stream, int indent) const {
   std::string space;
   for (Int i = 0; i < indent; i++, space += AKANTU_INDENT)
     ;
 
   stream << space << "FEEngine [" << std::endl;
   stream << space << " + id                : " << id << std::endl;
   stream << space << " + element dimension : " << element_dimension
          << std::endl;
 
   stream << space << " + mesh [" << std::endl;
   mesh.printself(stream, indent + 2);
   stream << space << AKANTU_INDENT << "]" << std::endl;
 
   stream << space << "]" << std::endl;
 }
 
 /* -------------------------------------------------------------------------- */
 
 } // namespace akantu
diff --git a/src/fe_engine/fe_engine.hh b/src/fe_engine/fe_engine.hh
index 4decb1828..1c0516a8f 100644
--- a/src/fe_engine/fe_engine.hh
+++ b/src/fe_engine/fe_engine.hh
@@ -1,393 +1,393 @@
 /**
  * @file   fe_engine.hh
  *
  * @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Fri Jun 18 2010
- * @date last modification: Thu Oct 22 2015
+ * @date last modification: Tue Feb 20 2018
  *
  * @brief  FEM class
  *
  * @section LICENSE
  *
- * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
- * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
- * Solides)
+ * 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
+ * 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
+ * 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_memory.hh"
 #include "element_type_map.hh"
 #include "mesh_events.hh"
 /* -------------------------------------------------------------------------- */
 
 #ifndef __AKANTU_FE_ENGINE_HH__
 #define __AKANTU_FE_ENGINE_HH__
 
 namespace akantu {
 class Mesh;
 class Integrator;
 class ShapeFunctions;
 class DOFManager;
 class Element;
 } // namespace akantu
 
 /* -------------------------------------------------------------------------- */
 namespace akantu {
 /* -------------------------------------------------------------------------- */
 
 /**
  * The  generic  FEEngine class  derived  in  a  FEEngineTemplate class
  * containing  the
  * shape functions and the integration method
  */
 class FEEngine : protected Memory, public MeshEventHandler {
   /* ------------------------------------------------------------------------ */
   /* Constructors/Destructors                                                 */
   /* ------------------------------------------------------------------------ */
 public:
   FEEngine(Mesh & mesh, UInt spatial_dimension = _all_dimensions,
            const ID & id = "fem", MemoryID memory_id = 0);
 
   ~FEEngine() override;
 
   /* ------------------------------------------------------------------------ */
   /* Methods                                                                  */
   /* ------------------------------------------------------------------------ */
 public:
   /// pre-compute all the shape functions, their derivatives and the jacobians
   virtual void
   initShapeFunctions(const GhostType & ghost_type = _not_ghost) = 0;
 
   /// extract the nodal values and store them per element
   template <typename T>
   static void extractNodalToElementField(
       const Mesh & mesh, const Array<T> & nodal_f, Array<T> & elemental_f,
       const ElementType & type, const GhostType & ghost_type = _not_ghost,
       const Array<UInt> & filter_elements = empty_filter);
 
   /// filter a field
   template <typename T>
   static void
   filterElementalData(const Mesh & mesh, const Array<T> & quad_f,
                       Array<T> & filtered_f, const ElementType & type,
                       const GhostType & ghost_type = _not_ghost,
                       const Array<UInt> & filter_elements = empty_filter);
 
   /* ------------------------------------------------------------------------ */
   /* Integration method bridges                                               */
   /* ------------------------------------------------------------------------ */
   /// integrate f for all elements of type "type"
   virtual void
   integrate(const Array<Real> & f, Array<Real> & intf,
             UInt nb_degree_of_freedom, const ElementType & type,
             const GhostType & ghost_type = _not_ghost,
             const Array<UInt> & filter_elements = empty_filter) const = 0;
 
   /// integrate a scalar value f on all elements of type "type"
   virtual Real
   integrate(const Array<Real> & f, const ElementType & type,
             const GhostType & ghost_type = _not_ghost,
             const Array<UInt> & filter_elements = empty_filter) const = 0;
 
   /// integrate f for all integration points of type "type" but don't sum over
   /// all integration points
   virtual void integrateOnIntegrationPoints(
       const Array<Real> & f, Array<Real> & intf, UInt nb_degree_of_freedom,
       const ElementType & type, const GhostType & ghost_type = _not_ghost,
       const Array<UInt> & filter_elements = empty_filter) const = 0;
 
   /// integrate one element scalar value on all elements of type "type"
   virtual Real integrate(const Vector<Real> & f, const ElementType & type,
                          UInt index,
                          const GhostType & ghost_type = _not_ghost) const = 0;
 
 /* ------------------------------------------------------------------------ */
 /* compatibility with old FEEngine fashion */
 /* ------------------------------------------------------------------------ */
 #ifndef SWIG
   /// get the number of integration points
   virtual UInt
   getNbIntegrationPoints(const ElementType & type,
                          const GhostType & ghost_type = _not_ghost) const = 0;
   /// get the precomputed shapes
   const virtual Array<Real> &
   getShapes(const ElementType & type, const GhostType & ghost_type = _not_ghost,
             UInt id = 0) const = 0;
 
   /// get the derivatives of shapes
   const virtual Array<Real> &
   getShapesDerivatives(const ElementType & type,
                        const GhostType & ghost_type = _not_ghost,
                        UInt id = 0) const = 0;
 
   /// get integration points
   const virtual Matrix<Real> &
   getIntegrationPoints(const ElementType & type,
                        const GhostType & ghost_type = _not_ghost) const = 0;
 #endif
   /* ------------------------------------------------------------------------ */
   /* Shape method bridges                                                     */
   /* ------------------------------------------------------------------------ */
   /// Compute the gradient nablauq on the integration points of an element type
   /// from nodal values u
   virtual void gradientOnIntegrationPoints(
       const Array<Real> & u, Array<Real> & nablauq,
       const UInt nb_degree_of_freedom, const ElementType & type,
       const GhostType & ghost_type = _not_ghost,
       const Array<UInt> & filter_elements = empty_filter) const = 0;
 
   /// Interpolate a nodal field u at the integration points of an element type
   /// -> uq
   virtual void interpolateOnIntegrationPoints(
       const Array<Real> & u, Array<Real> & uq, UInt nb_degree_of_freedom,
       const ElementType & type, const GhostType & ghost_type = _not_ghost,
       const Array<UInt> & filter_elements = empty_filter) const = 0;
 
   /// Interpolate a nodal field u at the integration points of many element
   /// types -> uq
   virtual void interpolateOnIntegrationPoints(
       const Array<Real> & u, ElementTypeMapArray<Real> & uq,
       const ElementTypeMapArray<UInt> * filter_elements = nullptr) const = 0;
 
   /// pre multiplies a tensor by the shapes derivaties
   virtual void
   computeBtD(const Array<Real> & Ds, Array<Real> & BtDs,
              const ElementType & type, const GhostType & ghost_type,
              const Array<UInt> & filter_elements = empty_filter) const = 0;
 
   /// left and right  multiplies a tensor by the shapes derivaties
   virtual void
   computeBtDB(const Array<Real> & Ds, Array<Real> & BtDBs, UInt order_d,
               const ElementType & type, const GhostType & ghost_type,
               const Array<UInt> & filter_elements = empty_filter) const = 0;
 
   /// Compute the interpolation point position in the global coordinates for
   /// many element types
   virtual void computeIntegrationPointsCoordinates(
       ElementTypeMapArray<Real> & integration_points_coordinates,
       const ElementTypeMapArray<UInt> * filter_elements = nullptr) const = 0;
 
   /// Compute the interpolation point position in the global coordinates for an
   /// element type
   virtual void computeIntegrationPointsCoordinates(
       Array<Real> & integration_points_coordinates, const ElementType & type,
       const GhostType & ghost_type = _not_ghost,
       const Array<UInt> & filter_elements = empty_filter) const = 0;
 
   /// Build pre-computed matrices for interpolation of field form integration
   /// points at other given positions (interpolation_points)
   virtual void initElementalFieldInterpolationFromIntegrationPoints(
       const ElementTypeMapArray<Real> & interpolation_points_coordinates,
       ElementTypeMapArray<Real> & interpolation_points_coordinates_matrices,
       ElementTypeMapArray<Real> & integration_points_coordinates_inv_matrices,
       const ElementTypeMapArray<UInt> * element_filter) const = 0;
 
   /// interpolate field at given position (interpolation_points) from given
   /// values of this field at integration points (field)
   virtual void interpolateElementalFieldFromIntegrationPoints(
       const ElementTypeMapArray<Real> & field,
       const ElementTypeMapArray<Real> & interpolation_points_coordinates,
       ElementTypeMapArray<Real> & result, const GhostType ghost_type,
       const ElementTypeMapArray<UInt> * element_filter) const = 0;
 
   /// Interpolate field at given position from given values of this field at
   /// integration points (field)
   /// using matrices precomputed with
   /// initElementalFieldInterplationFromIntegrationPoints
   virtual void interpolateElementalFieldFromIntegrationPoints(
       const ElementTypeMapArray<Real> & field,
       const ElementTypeMapArray<Real> &
           interpolation_points_coordinates_matrices,
       const ElementTypeMapArray<Real> &
           integration_points_coordinates_inv_matrices,
       ElementTypeMapArray<Real> & result, const GhostType ghost_type,
       const ElementTypeMapArray<UInt> * element_filter) const = 0;
 
   /// interpolate on a phyiscal point inside an element
   virtual void interpolate(const Vector<Real> & real_coords,
                            const Matrix<Real> & nodal_values,
                            Vector<Real> & interpolated,
                            const Element & element) const = 0;
 
   /// compute the shape on a provided point
   virtual void
   computeShapes(const Vector<Real> & real_coords, UInt elem,
                 const ElementType & type, Vector<Real> & shapes,
                 const GhostType & ghost_type = _not_ghost) const = 0;
 
   /// compute the shape derivatives on a provided point
   virtual void
   computeShapeDerivatives(const Vector<Real> & real__coords, UInt element,
                           const ElementType & type,
                           Matrix<Real> & shape_derivatives,
                           const GhostType & ghost_type = _not_ghost) const = 0;
 
   /* ------------------------------------------------------------------------ */
   /* Other methods                                                            */
   /* ------------------------------------------------------------------------ */
 
   /// pre-compute normals on integration points
   virtual void computeNormalsOnIntegrationPoints(
       const GhostType & ghost_type = _not_ghost) = 0;
 
   /// pre-compute normals on integration points
   virtual void computeNormalsOnIntegrationPoints(
       __attribute__((unused)) const Array<Real> & field,
       __attribute__((unused)) const GhostType & ghost_type = _not_ghost) {
     AKANTU_TO_IMPLEMENT();
   }
 
   /// pre-compute normals on integration points
   virtual void computeNormalsOnIntegrationPoints(
       __attribute__((unused)) const Array<Real> & field,
       __attribute__((unused)) Array<Real> & normal,
       __attribute__((unused)) const ElementType & type,
       __attribute__((unused)) const GhostType & ghost_type = _not_ghost) const {
     AKANTU_TO_IMPLEMENT();
   }
 
 #ifdef AKANTU_STRUCTURAL_MECHANICS
 
   /// assemble a field as a matrix for structural elements (ex. rho to mass
   /// matrix)
   virtual void assembleFieldMatrix(
       __attribute__((unused)) const Array<Real> & field_1,
       __attribute__((unused)) UInt nb_degree_of_freedom,
       __attribute__((unused)) SparseMatrix & M,
       __attribute__((unused)) Array<Real> * n,
       __attribute__((unused)) ElementTypeMapArray<Real> & rotation_mat,
       __attribute__((unused)) ElementType type,
       __attribute__((unused)) const GhostType & ghost_type) const {
 
     AKANTU_TO_IMPLEMENT();
   }
   /// compute shapes function in a matrix for structural elements
   virtual void computeShapesMatrix(
       __attribute__((unused)) const ElementType & type,
       __attribute__((unused)) UInt nb_degree_of_freedom,
       __attribute__((unused)) UInt nb_nodes_per_element,
       __attribute__((unused)) Array<Real> * n, __attribute__((unused)) UInt id,
       __attribute__((unused)) UInt degree_to_interpolate,
       __attribute__((unused)) UInt degree_interpolated,
       __attribute__((unused)) const bool sign,
       __attribute__((unused)) const GhostType & ghost_type) const {
 
     AKANTU_TO_IMPLEMENT();
   }
 
 #endif
 
   /// function to print the containt of the class
   virtual void printself(std::ostream & stream, int indent = 0) const;
 
 private:
   /// initialise the class
   void init();
 
   /* ------------------------------------------------------------------------ */
   /* Mesh Event Handler interface                                             */
   /* ------------------------------------------------------------------------ */
 public:
   void onNodesAdded(const Array<UInt> &, const NewNodesEvent &) final {}
   void onNodesRemoved(const Array<UInt> &, const Array<UInt> &,
                       const RemovedNodesEvent &) final {}
   void onElementsAdded(const Array<Element> &,
                        const NewElementsEvent &) override{};
   void onElementsRemoved(const Array<Element> &,
                          const ElementTypeMapArray<UInt> &,
                          const RemovedElementsEvent &) override {}
   void onElementsChanged(const Array<Element> &, const Array<Element> &,
                          const ElementTypeMapArray<UInt> &,
                          const ChangedElementsEvent &) override {}
   /* ------------------------------------------------------------------------ */
   /* Accessors                                                                */
   /* ------------------------------------------------------------------------ */
 public:
   using ElementTypesIteratorHelper =
       ElementTypeMapArray<Real, ElementType>::ElementTypesIteratorHelper;
 
   ElementTypesIteratorHelper elementTypes(UInt dim = _all_dimensions,
                                           GhostType ghost_type = _not_ghost,
                                           ElementKind kind = _ek_regular) const;
 
   /// get the dimension of the element handeled by this fe_engine object
   AKANTU_GET_MACRO(ElementDimension, element_dimension, UInt);
 
   /// get the mesh contained in the fem object
   AKANTU_GET_MACRO(Mesh, mesh, const Mesh &);
   /// get the mesh contained in the fem object
   AKANTU_GET_MACRO_NOT_CONST(Mesh, mesh, Mesh &);
 
   /// get the in-radius of an element
   static inline Real getElementInradius(const Matrix<Real> & coord,
                                         const ElementType & type);
 
   /// get the normals on integration points
   AKANTU_GET_MACRO_BY_ELEMENT_TYPE_CONST(NormalsOnIntegrationPoints,
                                          normals_on_integration_points, Real);
 
   /// get cohesive element type for a given facet type
   static inline ElementType
   getCohesiveElementType(const ElementType & type_facet);
 
   /// get igfem element type for a given regular type
   static inline Vector<ElementType>
   getIGFEMElementTypes(const ElementType & type);
 
   /// get the interpolation element associated to an element type
   static inline InterpolationType
   getInterpolationType(const ElementType & el_type);
 
   /// get the shape function class (probably useless: see getShapeFunction in
   /// fe_engine_template.hh)
   virtual const ShapeFunctions & getShapeFunctionsInterface() const = 0;
   /// get the integrator class (probably useless: see getIntegrator in
   /// fe_engine_template.hh)
   virtual const Integrator & getIntegratorInterface() const = 0;
 
   /* ------------------------------------------------------------------------ */
   /* Class Members                                                            */
   /* ------------------------------------------------------------------------ */
 protected:
   /// spatial dimension of the problem
   UInt element_dimension;
 
   /// the mesh on which all computation are made
   Mesh & mesh;
 
   /// normals at integration points
   ElementTypeMapArray<Real> normals_on_integration_points;
 };
 
 /* -------------------------------------------------------------------------- */
 /* inline functions                                                           */
 /* -------------------------------------------------------------------------- */
 
 /// standard output stream operator
 inline std::ostream & operator<<(std::ostream & stream,
                                  const FEEngine & _this) {
   _this.printself(stream);
   return stream;
 }
 
 } // namespace akantu
 
 #include "fe_engine_inline_impl.cc"
 #include "fe_engine_template.hh"
 
 #endif /* __AKANTU_FE_ENGINE_HH__ */
diff --git a/src/fe_engine/fe_engine_inline_impl.cc b/src/fe_engine/fe_engine_inline_impl.cc
index 48940bdb0..a04ec296e 100644
--- a/src/fe_engine/fe_engine_inline_impl.cc
+++ b/src/fe_engine/fe_engine_inline_impl.cc
@@ -1,199 +1,199 @@
 /**
  * @file   fe_engine_inline_impl.cc
  *
  * @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Tue Jul 20 2010
- * @date last modification: Sat Sep 05 2015
+ * @date last modification: Sun Aug 13 2017
  *
  * @brief  Implementation of the inline functions of the FEEngine Class
  *
  * @section LICENSE
  *
- * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
- * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
- * Solides)
+ * 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
+ * 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
+ * A PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
+
 /* -------------------------------------------------------------------------- */
 #include "element_class.hh"
 #include "fe_engine.hh"
 #include "mesh.hh"
 /* -------------------------------------------------------------------------- */
 #include "element_type_conversion.hh"
 /* -------------------------------------------------------------------------- */
 
 #ifndef __AKANTU_FE_ENGINE_INLINE_IMPL_CC__
 #define __AKANTU_FE_ENGINE_INLINE_IMPL_CC__
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 inline Real FEEngine::getElementInradius(const Matrix<Real> & coord,
                                          const ElementType & type) {
   AKANTU_DEBUG_IN();
 
   Real inradius = 0;
 
 #define GET_INRADIUS(type) inradius = ElementClass<type>::getInradius(coord);
 
   AKANTU_BOOST_ALL_ELEMENT_SWITCH(GET_INRADIUS);
 #undef GET_INRADIUS
 
   AKANTU_DEBUG_OUT();
   return inradius;
 }
 
 /* -------------------------------------------------------------------------- */
 inline InterpolationType
 FEEngine::getInterpolationType(const ElementType & type) {
   return convertType<ElementType, InterpolationType>(type);
 }
 
 /* -------------------------------------------------------------------------- */
 /// @todo rewrite this function in order to get the cohesive element
 /// type directly from the facet
 #if defined(AKANTU_COHESIVE_ELEMENT)
 inline ElementType FEEngine::getCohesiveElementType(const ElementType & type) {
   AKANTU_DEBUG_IN();
 
   ElementType ctype;
 #define GET_COHESIVE_TYPE(type)                                                \
   ctype = CohesiveFacetProperty<type>::cohesive_type;
 
   AKANTU_BOOST_ALL_ELEMENT_SWITCH(GET_COHESIVE_TYPE);
 #undef GET_COHESIVE_TYPE
 
   AKANTU_DEBUG_OUT();
   return ctype;
 }
 #else
 inline ElementType
 FEEngine::getCohesiveElementType(__attribute__((unused))
                                  const ElementType & type_facet) {
   return _not_defined;
 }
 #endif
 
 /* -------------------------------------------------------------------------- */
 #if defined(AKANTU_IGFEM)
 } // akantu
 #include "igfem_helper.hh"
 namespace akantu {
 
 inline Vector<ElementType>
 FEEngine::getIGFEMElementTypes(const ElementType & type) {
 
 #define GET_IGFEM_ELEMENT_TYPES(type)                                          \
   return IGFEMHelper::getIGFEMElementTypes<type>();
 
   AKANTU_BOOST_REGULAR_ELEMENT_SWITCH(GET_IGFEM_ELEMENT_TYPES);
 
 #undef GET_IGFEM_ELEMENT_TYPES
 }
 #endif
 
 /* -------------------------------------------------------------------------- */
 template <typename T>
 void FEEngine::extractNodalToElementField(const Mesh & mesh,
                                           const Array<T> & nodal_f,
                                           Array<T> & elemental_f,
                                           const ElementType & type,
                                           const GhostType & ghost_type,
                                           const Array<UInt> & filter_elements) {
   AKANTU_DEBUG_IN();
 
   UInt nb_nodes_per_element = Mesh::getNbNodesPerElement(type);
   UInt nb_degree_of_freedom = nodal_f.getNbComponent();
   UInt nb_element = mesh.getNbElement(type, ghost_type);
   UInt * conn_val = mesh.getConnectivity(type, ghost_type).storage();
 
   if (filter_elements != empty_filter) {
     nb_element = filter_elements.size();
   }
 
   elemental_f.resize(nb_element);
 
   T * nodal_f_val = nodal_f.storage();
   T * f_val = elemental_f.storage();
 
   UInt * el_conn;
   for (UInt el = 0; el < nb_element; ++el) {
     if (filter_elements != empty_filter)
       el_conn = conn_val + filter_elements(el) * nb_nodes_per_element;
     else
       el_conn = conn_val + el * nb_nodes_per_element;
 
     for (UInt n = 0; n < nb_nodes_per_element; ++n) {
       UInt node = *(el_conn + n);
       std::copy(nodal_f_val + node * nb_degree_of_freedom,
                 nodal_f_val + (node + 1) * nb_degree_of_freedom, f_val);
       f_val += nb_degree_of_freedom;
     }
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <typename T>
 void FEEngine::filterElementalData(const Mesh & mesh, const Array<T> & elem_f,
                                    Array<T> & filtered_f,
                                    const ElementType & type,
                                    const GhostType & ghost_type,
                                    const Array<UInt> & filter_elements) {
   AKANTU_DEBUG_IN();
 
   UInt nb_element = mesh.getNbElement(type, ghost_type);
   if (nb_element == 0) {
     filtered_f.resize(0);
     return;
   }
 
   UInt nb_degree_of_freedom = elem_f.getNbComponent();
   UInt nb_data_per_element = elem_f.size() / nb_element;
 
   if (filter_elements != empty_filter) {
     nb_element = filter_elements.size();
   }
 
   filtered_f.resize(nb_element * nb_data_per_element);
 
   T * elem_f_val = elem_f.storage();
   T * f_val = filtered_f.storage();
 
   UInt el_offset;
   for (UInt el = 0; el < nb_element; ++el) {
     if (filter_elements != empty_filter)
       el_offset = filter_elements(el);
     else
       el_offset = el;
 
     std::copy(elem_f_val +
                   el_offset * nb_data_per_element * nb_degree_of_freedom,
               elem_f_val +
                   (el_offset + 1) * nb_data_per_element * nb_degree_of_freedom,
               f_val);
     f_val += nb_degree_of_freedom * nb_data_per_element;
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 } // akantu
 
 #endif /* __AKANTU_FE_ENGINE_INLINE_IMPL_CC__ */
diff --git a/src/fe_engine/fe_engine_template.hh b/src/fe_engine/fe_engine_template.hh
index 14e5793b6..4325dbce6 100644
--- a/src/fe_engine/fe_engine_template.hh
+++ b/src/fe_engine/fe_engine_template.hh
@@ -1,407 +1,407 @@
 /**
  * @file   fe_engine_template.hh
  *
  * @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Fri Jun 18 2010
- * @date last modification: Tue Dec 08 2015
+ * @date last modification: Mon Jan 29 2018
  *
  * @brief  templated class that calls integration and shape objects
  *
  * @section LICENSE
  *
- * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
- * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
- * Solides)
+ * 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
+ * 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
+ * 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_FE_ENGINE_TEMPLATE_HH__
 #define __AKANTU_FE_ENGINE_TEMPLATE_HH__
 
 /* -------------------------------------------------------------------------- */
 #include "fe_engine.hh"
 #include "integrator.hh"
 #include "shape_functions.hh"
 /* -------------------------------------------------------------------------- */
 #include <type_traits>
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 class DOFManager;
 namespace fe_engine {
   namespace details {
     template <ElementKind> struct AssembleLumpedTemplateHelper;
     template <ElementKind> struct AssembleFieldMatrixHelper;
   } // namespace details
 } // namespace fe_engine
 
 template <ElementKind, typename> struct AssembleFieldMatrixStructHelper;
 
 struct DefaultIntegrationOrderFunctor {
   template <ElementType type> static inline constexpr int getOrder() {
     return ElementClassProperty<type>::polynomial_degree;
   }
 };
 
 /* -------------------------------------------------------------------------- */
 template <template <ElementKind, class> class I, template <ElementKind> class S,
           ElementKind kind = _ek_regular,
           class IntegrationOrderFunctor = DefaultIntegrationOrderFunctor>
 class FEEngineTemplate : public FEEngine {
   /* ------------------------------------------------------------------------ */
   /* Constructors/Destructors                                                 */
   /* ------------------------------------------------------------------------ */
 public:
   using Integ = I<kind, IntegrationOrderFunctor>;
   using Shape = S<kind>;
 
   FEEngineTemplate(Mesh & mesh, UInt spatial_dimension = _all_dimensions,
                    ID id = "fem", MemoryID memory_id = 0);
 
   ~FEEngineTemplate() override;
 
   /* ------------------------------------------------------------------------ */
   /* Methods                                                                  */
   /* ------------------------------------------------------------------------ */
 public:
   /// pre-compute all the shape functions, their derivatives and the jacobians
   void initShapeFunctions(const GhostType & ghost_type = _not_ghost) override;
   void initShapeFunctions(const Array<Real> & nodes,
                           const GhostType & ghost_type = _not_ghost);
 
   /* ------------------------------------------------------------------------ */
   /* Integration method bridges                                               */
   /* ------------------------------------------------------------------------ */
   /// integrate f for all elements of type "type"
   void
   integrate(const Array<Real> & f, Array<Real> & intf,
             UInt nb_degree_of_freedom, const ElementType & type,
             const GhostType & ghost_type = _not_ghost,
             const Array<UInt> & filter_elements = empty_filter) const override;
 
   /// integrate a scalar value on all elements of type "type"
   Real
   integrate(const Array<Real> & f, const ElementType & type,
             const GhostType & ghost_type = _not_ghost,
             const Array<UInt> & filter_elements = empty_filter) const override;
 
   /// integrate one element scalar value on all elements of type "type"
   Real integrate(const Vector<Real> & f, const ElementType & type, UInt index,
                  const GhostType & ghost_type = _not_ghost) const override;
 
   /// integrate partially around an integration point (@f$ intf_q = f_q * J_q *
   /// w_q @f$)
   void integrateOnIntegrationPoints(
       const Array<Real> & f, Array<Real> & intf, UInt nb_degree_of_freedom,
       const ElementType & type, const GhostType & ghost_type = _not_ghost,
       const Array<UInt> & filter_elements = empty_filter) const override;
 
   /// interpolate on a phyiscal point inside an element
   void interpolate(const Vector<Real> & real_coords,
                    const Matrix<Real> & nodal_values,
                    Vector<Real> & interpolated,
                    const Element & element) const override;
 
   /// get the number of integration points
   UInt getNbIntegrationPoints(
       const ElementType & type,
       const GhostType & ghost_type = _not_ghost) const override;
 
   /// get shapes precomputed
   const Array<Real> & getShapes(const ElementType & type,
                                 const GhostType & ghost_type = _not_ghost,
                                 UInt id = 0) const override;
 
   /// get the derivatives of shapes
   const Array<Real> &
   getShapesDerivatives(const ElementType & type,
                        const GhostType & ghost_type = _not_ghost,
                        UInt id = 0) const override;
 
   /// get integration points
   const inline Matrix<Real> & getIntegrationPoints(
       const ElementType & type,
       const GhostType & ghost_type = _not_ghost) const override;
 
   /* ------------------------------------------------------------------------ */
   /* Shape method bridges                                                     */
   /* ------------------------------------------------------------------------ */
 
   /// compute the gradient of a nodal field on the integration points
   void gradientOnIntegrationPoints(
       const Array<Real> & u, Array<Real> & nablauq,
       const UInt nb_degree_of_freedom, const ElementType & type,
       const GhostType & ghost_type = _not_ghost,
       const Array<UInt> & filter_elements = empty_filter) const override;
 
   /// interpolate a nodal field on the integration points
   void interpolateOnIntegrationPoints(
       const Array<Real> & u, Array<Real> & uq, UInt nb_degree_of_freedom,
       const ElementType & type, const GhostType & ghost_type = _not_ghost,
       const Array<UInt> & filter_elements = empty_filter) const override;
 
   /// interpolate a nodal field on the integration points given a
   /// by_element_type
   void interpolateOnIntegrationPoints(
       const Array<Real> & u, ElementTypeMapArray<Real> & uq,
       const ElementTypeMapArray<UInt> * filter_elements =
           nullptr) const override;
 
   /// pre multiplies a tensor by the shapes derivaties
   void
   computeBtD(const Array<Real> & Ds, Array<Real> & BtDs,
              const ElementType & type, const GhostType & ghost_type,
              const Array<UInt> & filter_elements = empty_filter) const override;
 
   /// left and right  multiplies a tensor by the shapes derivaties
   void computeBtDB(
       const Array<Real> & Ds, Array<Real> & BtDBs, UInt order_d,
       const ElementType & type, const GhostType & ghost_type,
       const Array<UInt> & filter_elements = empty_filter) const override;
 
   /// compute the position of integration points given by an element_type_map
   /// from nodes position
   inline void computeIntegrationPointsCoordinates(
       ElementTypeMapArray<Real> & quadrature_points_coordinates,
       const ElementTypeMapArray<UInt> * filter_elements =
           nullptr) const override;
 
   /// compute the position of integration points from nodes position
   inline void computeIntegrationPointsCoordinates(
       Array<Real> & quadrature_points_coordinates, const ElementType & type,
       const GhostType & ghost_type = _not_ghost,
       const Array<UInt> & filter_elements = empty_filter) const override;
 
   /// interpolate field at given position (interpolation_points) from given
   /// values of this field at integration points (field)
   inline void interpolateElementalFieldFromIntegrationPoints(
       const ElementTypeMapArray<Real> & field,
       const ElementTypeMapArray<Real> & interpolation_points_coordinates,
       ElementTypeMapArray<Real> & result, const GhostType ghost_type,
       const ElementTypeMapArray<UInt> * element_filter) const override;
 
   /// Interpolate field at given position from given values of this field at
   /// integration points (field)
   /// using matrices precomputed with
   /// initElementalFieldInterplationFromIntegrationPoints
   inline void interpolateElementalFieldFromIntegrationPoints(
       const ElementTypeMapArray<Real> & field,
       const ElementTypeMapArray<Real> &
           interpolation_points_coordinates_matrices,
       const ElementTypeMapArray<Real> & quad_points_coordinates_inv_matrices,
       ElementTypeMapArray<Real> & result, const GhostType ghost_type,
       const ElementTypeMapArray<UInt> * element_filter) const override;
 
   /// Build pre-computed matrices for interpolation of field form integration
   /// points at other given positions (interpolation_points)
   inline void initElementalFieldInterpolationFromIntegrationPoints(
       const ElementTypeMapArray<Real> & interpolation_points_coordinates,
       ElementTypeMapArray<Real> & interpolation_points_coordinates_matrices,
       ElementTypeMapArray<Real> & quad_points_coordinates_inv_matrices,
       const ElementTypeMapArray<UInt> * element_filter =
           nullptr) const override;
 
   /// find natural coords from real coords provided an element
   void inverseMap(const Vector<Real> & real_coords, UInt element,
                   const ElementType & type, Vector<Real> & natural_coords,
                   const GhostType & ghost_type = _not_ghost) const;
 
   /// return true if the coordinates provided are inside the element, false
   /// otherwise
   inline bool contains(const Vector<Real> & real_coords, UInt element,
                        const ElementType & type,
                        const GhostType & ghost_type = _not_ghost) const;
 
   /// compute the shape on a provided point
   inline void
   computeShapes(const Vector<Real> & real_coords, UInt element,
                 const ElementType & type, Vector<Real> & shapes,
                 const GhostType & ghost_type = _not_ghost) const override;
 
   /// compute the shape derivatives on a provided point
   inline void computeShapeDerivatives(
       const Vector<Real> & real__coords, UInt element, const ElementType & type,
       Matrix<Real> & shape_derivatives,
       const GhostType & ghost_type = _not_ghost) const override;
 
   /* ------------------------------------------------------------------------ */
   /* Other methods                                                            */
   /* ------------------------------------------------------------------------ */
   /// pre-compute normals on integration points
   void computeNormalsOnIntegrationPoints(
       const GhostType & ghost_type = _not_ghost) override;
   void computeNormalsOnIntegrationPoints(
       const Array<Real> & field,
       const GhostType & ghost_type = _not_ghost) override;
   void computeNormalsOnIntegrationPoints(
       const Array<Real> & field, Array<Real> & normal, const ElementType & type,
       const GhostType & ghost_type = _not_ghost) const override;
   template <ElementType type>
   void computeNormalsOnIntegrationPoints(const Array<Real> & field,
                                          Array<Real> & normal,
                                          const GhostType & ghost_type) const;
 
 private:
   // To avoid a weird full specialization of a method in a non specalized class
   void
   computeNormalsOnIntegrationPointsPoint1(const Array<Real> &,
                                           Array<Real> & normal,
                                           const GhostType & ghost_type) const;
 
 public:
   /// function to print the contain of the class
   void printself(std::ostream & stream, int indent = 0) const override;
 
   /// assemble a field as a lumped matrix (ex. rho in lumped mass)
   template <class Functor>
   void assembleFieldLumped(const Functor & field_funct, const ID & matrix_id,
                            const ID & dof_id, DOFManager & dof_manager,
                            ElementType type,
                            const GhostType & ghost_type) const;
 
   /// assemble a field as a matrix (ex. rho to mass matrix)
   template <class Functor>
   void assembleFieldMatrix(const Functor & field_funct, const ID & matrix_id,
                            const ID & dof_id, DOFManager & dof_manager,
                            ElementType type,
                            const GhostType & ghost_type) const;
 
 #ifdef AKANTU_STRUCTURAL_MECHANICS
   /// assemble a field as a matrix (ex. rho to mass matrix)
   void assembleFieldMatrix(const Array<Real> & field_1,
                            UInt nb_degree_of_freedom, SparseMatrix & M,
                            Array<Real> * n,
                            ElementTypeMapArray<Real> & rotation_mat,
                            const ElementType & type,
                            const GhostType & ghost_type = _not_ghost) const;
 
   /// compute shapes function in a matrix for structural elements
   void
   computeShapesMatrix(const ElementType & type, UInt nb_degree_of_freedom,
                       UInt nb_nodes_per_element, Array<Real> * n, UInt id,
                       UInt degree_to_interpolate, UInt degree_interpolated,
                       const bool sign,
                       const GhostType & ghost_type = _not_ghost) const override;
 #endif
 
 private:
   friend struct fe_engine::details::AssembleLumpedTemplateHelper<kind>;
   friend struct fe_engine::details::AssembleFieldMatrixHelper<kind>;
   friend struct AssembleFieldMatrixStructHelper<kind, void>;
 
   /// templated function to compute the scaling to assemble a lumped matrix
   template <class Functor, ElementType type>
   void assembleFieldLumped(const Functor & field_funct, const ID & matrix_id,
                            const ID & dof_id, DOFManager & dof_manager,
                            const GhostType & ghost_type) const;
 
   /// @f$ \tilde{M}_{i} = \sum_j M_{ij} = \sum_j \int \rho \varphi_i \varphi_j
   /// dV = \int \rho \varphi_i dV @f$
   template <ElementType type>
   void assembleLumpedRowSum(const Array<Real> & field, const ID & matrix_id,
                             const ID & dof_id, DOFManager & dof_manager,
                             const GhostType & ghost_type) const;
 
   /// @f$ \tilde{M}_{i} = c * M_{ii} = \int_{V_e} \rho dV @f$
   template <ElementType type>
   void assembleLumpedDiagonalScaling(const Array<Real> & field,
                                      const ID & matrix_id, const ID & dof_id,
                                      DOFManager & dof_manager,
                                      const GhostType & ghost_type) const;
 
   /// assemble a field as a matrix (ex. rho to mass matrix)
   template <class Functor, ElementType type>
   void assembleFieldMatrix(const Functor & field_funct, const ID & matrix_id,
                            const ID & dof_id, DOFManager & dof_manager,
                            const GhostType & ghost_type) const;
 
 #ifdef AKANTU_STRUCTURAL_MECHANICS
 
   /// assemble a field as a matrix for structural elements (ex. rho to mass
   /// matrix)
   template <ElementType type>
   void assembleFieldMatrix(const Array<Real> & field_1,
                            UInt nb_degree_of_freedom, SparseMatrix & M,
                            Array<Real> * n,
                            ElementTypeMapArray<Real> & rotation_mat,
                            __attribute__((unused))
                            const GhostType & ghost_type) const;
 
 #endif
 
   /* ------------------------------------------------------------------------ */
   /* Mesh Event Handler interface                                             */
   /* ------------------------------------------------------------------------ */
 public:
   void onElementsAdded(const Array<Element> &,
                        const NewElementsEvent &) override;
   void onElementsRemoved(const Array<Element> &,
                          const ElementTypeMapArray<UInt> &,
                          const RemovedElementsEvent &) override;
   void onElementsChanged(const Array<Element> &, const Array<Element> &,
                          const ElementTypeMapArray<UInt> &,
                          const ChangedElementsEvent &) override;
 
   /* ------------------------------------------------------------------------ */
   /* Accessors                                                                */
   /* ------------------------------------------------------------------------ */
 public:
   /// get the shape class (probably useless: see getShapeFunction)
   const ShapeFunctions & getShapeFunctionsInterface() const override {
     return shape_functions;
   };
   /// get the shape class
   const Shape & getShapeFunctions() const { return shape_functions; };
 
   /// get the integrator class (probably useless: see getIntegrator)
   const Integrator & getIntegratorInterface() const override {
     return integrator;
   };
   /// get the integrator class
   const Integ & getIntegrator() const { return integrator; };
 
   /* ------------------------------------------------------------------------ */
   /* Class Members                                                            */
   /* ------------------------------------------------------------------------ */
 private:
   Integ integrator;
   Shape shape_functions;
 };
 
 } // namespace akantu
 
 /* -------------------------------------------------------------------------- */
 /* inline functions                                                           */
 /* -------------------------------------------------------------------------- */
 #include "fe_engine_template_tmpl.hh"
 #include "fe_engine_template_tmpl_field.hh"
 /* -------------------------------------------------------------------------- */
 /* Shape Linked specialization                                                */
 /* -------------------------------------------------------------------------- */
 #if defined(AKANTU_STRUCTURAL_MECHANICS)
 #include "fe_engine_template_tmpl_struct.hh"
 #endif
 /* -------------------------------------------------------------------------- */
 /* Shape IGFEM specialization                                                 */
 /* -------------------------------------------------------------------------- */
 #if defined(AKANTU_IGFEM)
 #include "fe_engine_template_tmpl_igfem.hh"
 #endif
 
 #endif /* __AKANTU_FE_ENGINE_TEMPLATE_HH__ */
diff --git a/src/fe_engine/fe_engine_template_cohesive.cc b/src/fe_engine/fe_engine_template_cohesive.cc
index d93f779f0..447463fc4 100644
--- a/src/fe_engine/fe_engine_template_cohesive.cc
+++ b/src/fe_engine/fe_engine_template_cohesive.cc
@@ -1,133 +1,132 @@
 /**
  * @file   fe_engine_template_cohesive.cc
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  * @author Marco Vocialta <marco.vocialta@epfl.ch>
  *
  * @date creation: Wed Oct 31 2012
- * @date last modification: Thu Oct 15 2015
+ * @date last modification: Tue Feb 20 2018
  *
  * @brief  Specialization of the FEEngineTemplate for cohesive element
  *
  * @section LICENSE
  *
- * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
- * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
- * Solides)
+ * 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
+ * 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
+ * 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 "fe_engine_template.hh"
 #include "integrator_gauss.hh"
 #include "shape_cohesive.hh"
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 /* compatibility functions */
 /* -------------------------------------------------------------------------- */
 template <>
 Real FEEngineTemplate<IntegratorGauss, ShapeLagrange, _ek_cohesive,
                       DefaultIntegrationOrderFunctor>::
     integrate(const Array<Real> & f, const ElementType & type,
               const GhostType & ghost_type,
               const Array<UInt> & filter_elements) const {
   AKANTU_DEBUG_IN();
 
 #ifndef AKANTU_NDEBUG
   UInt nb_element = mesh.getNbElement(type, ghost_type);
   if (filter_elements != empty_filter)
     nb_element = filter_elements.size();
 
   UInt nb_quadrature_points = getNbIntegrationPoints(type);
 
   AKANTU_DEBUG_ASSERT(f.size() == nb_element * nb_quadrature_points,
                       "The vector f(" << f.getID()
                                       << ") has not the good size.");
   AKANTU_DEBUG_ASSERT(f.getNbComponent() == 1,
                       "The vector f("
                           << f.getID()
                           << ") has not the good number of component.");
 #endif
 
   Real integral = 0.;
 
 #define INTEGRATE(type)                                                        \
   integral = integrator.integrate<type>(f, ghost_type, filter_elements);
 
   AKANTU_BOOST_COHESIVE_ELEMENT_SWITCH(INTEGRATE);
 #undef INTEGRATE
 
   AKANTU_DEBUG_OUT();
   return integral;
 }
 
 /* -------------------------------------------------------------------------- */
 template <>
 void FEEngineTemplate<IntegratorGauss, ShapeLagrange, _ek_cohesive,
                       DefaultIntegrationOrderFunctor>::
     integrate(const Array<Real> & f, Array<Real> & intf,
               UInt nb_degree_of_freedom, const ElementType & type,
               const GhostType & ghost_type,
               const Array<UInt> & filter_elements) const {
 
 #ifndef AKANTU_NDEBUG
   UInt nb_element = mesh.getNbElement(type, ghost_type);
   if (filter_elements == filter_elements)
     nb_element = filter_elements.size();
 
   UInt nb_quadrature_points = getNbIntegrationPoints(type);
 
   AKANTU_DEBUG_ASSERT(f.size() == nb_element * nb_quadrature_points,
                       "The vector f(" << f.getID() << " size " << f.size()
                                       << ") has not the good size ("
                                       << nb_element << ").");
   AKANTU_DEBUG_ASSERT(f.getNbComponent() == nb_degree_of_freedom,
                       "The vector f("
                           << f.getID()
                           << ") has not the good number of component.");
   AKANTU_DEBUG_ASSERT(intf.getNbComponent() == nb_degree_of_freedom,
                       "The vector intf("
                           << intf.getID()
                           << ") has not the good number of component.");
   AKANTU_DEBUG_ASSERT(intf.size() == nb_element,
                       "The vector intf(" << intf.getID()
                                          << ") has not the good size.");
 #endif
 
 #define INTEGRATE(type)                                                        \
   integrator.integrate<type>(f, intf, nb_degree_of_freedom, ghost_type,        \
                              filter_elements);
 
   AKANTU_BOOST_COHESIVE_ELEMENT_SWITCH(INTEGRATE);
 #undef INTEGRATE
 }
 
 /* -------------------------------------------------------------------------- */
 template <>
 void FEEngineTemplate<IntegratorGauss, ShapeLagrange, _ek_cohesive,
                       DefaultIntegrationOrderFunctor>::
     gradientOnIntegrationPoints(const Array<Real> &, Array<Real> &, const UInt,
                                 const ElementType &, const GhostType &,
                                 const Array<UInt> &) const {
   AKANTU_TO_IMPLEMENT();
 }
 
 /* -------------------------------------------------------------------------- */
 
 } // akantu
diff --git a/src/fe_engine/fe_engine_template_tmpl.hh b/src/fe_engine/fe_engine_template_tmpl.hh
index 1d5c54b00..bace4d338 100644
--- a/src/fe_engine/fe_engine_template_tmpl.hh
+++ b/src/fe_engine/fe_engine_template_tmpl.hh
@@ -1,1374 +1,1373 @@
 /**
  * @file   fe_engine_template_tmpl.hh
  *
  * @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
  * @author Mauro Corrado <mauro.corrado@epfl.ch>
  * @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  * @author Marco Vocialta <marco.vocialta@epfl.ch>
  *
  * @date creation: Tue Feb 15 2011
- * @date last modification: Thu Nov 19 2015
+ * @date last modification: Tue Feb 20 2018
  *
  * @brief  Template implementation of FEEngineTemplate
  *
  * @section LICENSE
  *
- * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
- * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
- * Solides)
+ * 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
+ * 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
+ * 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 "dof_manager.hh"
 #include "fe_engine_template.hh"
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 template <template <ElementKind, class> class I, template <ElementKind> class S,
           ElementKind kind, class IntegrationOrderFunctor>
 FEEngineTemplate<I, S, kind, IntegrationOrderFunctor>::FEEngineTemplate(
     Mesh & mesh, UInt spatial_dimension, ID id, MemoryID memory_id)
     : FEEngine(mesh, spatial_dimension, id, memory_id),
       integrator(mesh, id, memory_id), shape_functions(mesh, id, memory_id) {}
 
 /* -------------------------------------------------------------------------- */
 template <template <ElementKind, class> class I, template <ElementKind> class S,
           ElementKind kind, class IntegrationOrderFunctor>
 FEEngineTemplate<I, S, kind, IntegrationOrderFunctor>::~FEEngineTemplate() =
     default;
 
 /* -------------------------------------------------------------------------- */
 /**
  * Helper class to be able to write a partial specialization on the element kind
  */
 namespace fe_engine {
   namespace details {
     template <ElementKind kind> struct GradientOnIntegrationPointsHelper {
       template <class S>
       static void call(const S &, Mesh &, const Array<Real> &, Array<Real> &,
                        const UInt, const ElementType &, const GhostType &,
                        const Array<UInt> &) {
         AKANTU_TO_IMPLEMENT();
       }
     };
 
 #define COMPUTE_GRADIENT(type)                                                 \
   if (element_dimension == ElementClass<type>::getSpatialDimension())          \
     shape_functions.template gradientOnIntegrationPoints<type>(                \
         u, nablauq, nb_degree_of_freedom, ghost_type, filter_elements);
 
 #define AKANTU_SPECIALIZE_GRADIENT_ON_INTEGRATION_POINTS_HELPER(kind)          \
   template <> struct GradientOnIntegrationPointsHelper<kind> {                 \
     template <class S>                                                         \
     static void call(const S & shape_functions, Mesh & mesh,                   \
                      const Array<Real> & u, Array<Real> & nablauq,             \
                      const UInt nb_degree_of_freedom,                          \
                      const ElementType & type, const GhostType & ghost_type,   \
                      const Array<UInt> & filter_elements) {                    \
       UInt element_dimension = mesh.getSpatialDimension(type);                 \
       AKANTU_BOOST_KIND_ELEMENT_SWITCH(COMPUTE_GRADIENT, kind);                \
     }                                                                          \
   };
 
     AKANTU_BOOST_ALL_KIND_LIST(
         AKANTU_SPECIALIZE_GRADIENT_ON_INTEGRATION_POINTS_HELPER,
         AKANTU_FE_ENGINE_LIST_GRADIENT_ON_INTEGRATION_POINTS)
 
 #undef AKANTU_SPECIALIZE_GRADIENT_ON_INTEGRATION_POINTS_HELPER
 #undef COMPUTE_GRADIENT
   } // namespace details
 } // namespace fe_engine
 
 template <template <ElementKind, class> class I, template <ElementKind> class S,
           ElementKind kind, class IntegrationOrderFunctor>
 void FEEngineTemplate<I, S, kind, IntegrationOrderFunctor>::
     gradientOnIntegrationPoints(const Array<Real> & u, Array<Real> & nablauq,
                                 const UInt nb_degree_of_freedom,
                                 const ElementType & type,
                                 const GhostType & ghost_type,
                                 const Array<UInt> & filter_elements) const {
   AKANTU_DEBUG_IN();
 
   UInt nb_element = mesh.getNbElement(type, ghost_type);
   if (filter_elements != empty_filter)
     nb_element = filter_elements.size();
   UInt nb_points =
       shape_functions.getIntegrationPoints(type, ghost_type).cols();
 
 #ifndef AKANTU_NDEBUG
 
   UInt element_dimension = mesh.getSpatialDimension(type);
 
   AKANTU_DEBUG_ASSERT(u.size() == mesh.getNbNodes(),
                       "The vector u(" << u.getID()
                                       << ") has not the good size.");
   AKANTU_DEBUG_ASSERT(u.getNbComponent() == nb_degree_of_freedom,
                       "The vector u("
                           << u.getID()
                           << ") has not the good number of component.");
 
   AKANTU_DEBUG_ASSERT(
       nablauq.getNbComponent() == nb_degree_of_freedom * element_dimension,
       "The vector nablauq(" << nablauq.getID()
                             << ") has not the good number of component.");
 
 // AKANTU_DEBUG_ASSERT(nablauq.size() == nb_element * nb_points,
 //                  "The vector nablauq(" << nablauq.getID()
 //                  << ") has not the good size.");
 #endif
 
   nablauq.resize(nb_element * nb_points);
 
   fe_engine::details::GradientOnIntegrationPointsHelper<kind>::call(
       shape_functions, mesh, u, nablauq, nb_degree_of_freedom, type, ghost_type,
       filter_elements);
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <template <ElementKind, class> class I, template <ElementKind> class S,
           ElementKind kind, class IntegrationOrderFunctor>
 void FEEngineTemplate<I, S, kind, IntegrationOrderFunctor>::initShapeFunctions(
     const GhostType & ghost_type) {
   initShapeFunctions(mesh.getNodes(), ghost_type);
 }
 
 /* -------------------------------------------------------------------------- */
 template <template <ElementKind, class> class I, template <ElementKind> class S,
           ElementKind kind, class IntegrationOrderFunctor>
 void FEEngineTemplate<I, S, kind, IntegrationOrderFunctor>::initShapeFunctions(
     const Array<Real> & nodes, const GhostType & ghost_type) {
   AKANTU_DEBUG_IN();
 
   for (auto & type : mesh.elementTypes(element_dimension, ghost_type, kind)) {
     integrator.initIntegrator(nodes, type, ghost_type);
     const auto & control_points = getIntegrationPoints(type, ghost_type);
     shape_functions.initShapeFunctions(nodes, control_points, type, ghost_type);
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 /**
  * Helper class to be able to write a partial specialization on the element kind
  */
 namespace fe_engine {
   namespace details {
     template <ElementKind kind> struct IntegrateHelper {};
 
 #define INTEGRATE(type)                                                        \
   integrator.template integrate<type>(f, intf, nb_degree_of_freedom,           \
                                       ghost_type, filter_elements);
 
 #define AKANTU_SPECIALIZE_INTEGRATE_HELPER(kind)                               \
   template <> struct IntegrateHelper<kind> {                                   \
     template <class I>                                                         \
     static void call(const I & integrator, const Array<Real> & f,              \
                      Array<Real> & intf, UInt nb_degree_of_freedom,            \
                      const ElementType & type, const GhostType & ghost_type,   \
                      const Array<UInt> & filter_elements) {                    \
       AKANTU_BOOST_KIND_ELEMENT_SWITCH(INTEGRATE, kind);                       \
     }                                                                          \
   };
 
     AKANTU_BOOST_ALL_KIND(AKANTU_SPECIALIZE_INTEGRATE_HELPER)
 
 #undef AKANTU_SPECIALIZE_INTEGRATE_HELPER
 #undef INTEGRATE
   } // namespace details
 } // namespace fe_engine
 
 template <template <ElementKind, class> class I, template <ElementKind> class S,
           ElementKind kind, class IntegrationOrderFunctor>
 void FEEngineTemplate<I, S, kind, IntegrationOrderFunctor>::integrate(
     const Array<Real> & f, Array<Real> & intf, UInt nb_degree_of_freedom,
     const ElementType & type, const GhostType & ghost_type,
     const Array<UInt> & filter_elements) const {
 
   UInt nb_element = mesh.getNbElement(type, ghost_type);
   if (filter_elements != empty_filter)
     nb_element = filter_elements.size();
 #ifndef AKANTU_NDEBUG
 
   UInt nb_quadrature_points = getNbIntegrationPoints(type);
 
   AKANTU_DEBUG_ASSERT(f.size() == nb_element * nb_quadrature_points,
                       "The vector f(" << f.getID() << " size " << f.size()
                                       << ") has not the good size ("
                                       << nb_element << ").");
   AKANTU_DEBUG_ASSERT(f.getNbComponent() == nb_degree_of_freedom,
                       "The vector f("
                           << f.getID()
                           << ") has not the good number of component.");
   AKANTU_DEBUG_ASSERT(intf.getNbComponent() == nb_degree_of_freedom,
                       "The vector intf("
                           << intf.getID()
                           << ") has not the good number of component.");
 #endif
 
   intf.resize(nb_element);
 
   fe_engine::details::IntegrateHelper<kind>::call(integrator, f, intf,
                                                   nb_degree_of_freedom, type,
                                                   ghost_type, filter_elements);
 }
 
 /* -------------------------------------------------------------------------- */
 /**
  * Helper class to be able to write a partial specialization on the element kind
  */
 namespace fe_engine {
   namespace details {
     template <ElementKind kind> struct IntegrateScalarHelper {};
 
 #define INTEGRATE(type)                                                        \
   integral =                                                                   \
       integrator.template integrate<type>(f, ghost_type, filter_elements);
 
 #define AKANTU_SPECIALIZE_INTEGRATE_SCALAR_HELPER(kind)                        \
   template <> struct IntegrateScalarHelper<kind> {                             \
     template <class I>                                                         \
     static Real call(const I & integrator, const Array<Real> & f,              \
                      const ElementType & type, const GhostType & ghost_type,   \
                      const Array<UInt> & filter_elements) {                    \
       Real integral = 0.;                                                      \
       AKANTU_BOOST_KIND_ELEMENT_SWITCH(INTEGRATE, kind);                       \
       return integral;                                                         \
     }                                                                          \
   };
 
     AKANTU_BOOST_ALL_KIND(AKANTU_SPECIALIZE_INTEGRATE_SCALAR_HELPER)
 
 #undef AKANTU_SPECIALIZE_INTEGRATE_SCALAR_HELPER
 #undef INTEGRATE
   } // namespace details
 } // namespace fe_engine
 
 template <template <ElementKind, class> class I, template <ElementKind> class S,
           ElementKind kind, class IntegrationOrderFunctor>
 Real FEEngineTemplate<I, S, kind, IntegrationOrderFunctor>::integrate(
     const Array<Real> & f, const ElementType & type,
     const GhostType & ghost_type, const Array<UInt> & filter_elements) const {
   AKANTU_DEBUG_IN();
 
 #ifndef AKANTU_NDEBUG
   //   std::stringstream sstr; sstr << ghost_type;
   //   AKANTU_DEBUG_ASSERT(sstr.str() == nablauq.getTag(),
   //                  "The vector " << nablauq.getID() << " is not taged " <<
   //                  ghost_type);
   UInt nb_element = mesh.getNbElement(type, ghost_type);
   if (filter_elements != empty_filter)
     nb_element = filter_elements.size();
 
   UInt nb_quadrature_points = getNbIntegrationPoints(type, ghost_type);
 
   AKANTU_DEBUG_ASSERT(
       f.size() == nb_element * nb_quadrature_points,
       "The vector f(" << f.getID() << ") has not the good size. (" << f.size()
                       << "!=" << nb_quadrature_points * nb_element << ")");
   AKANTU_DEBUG_ASSERT(f.getNbComponent() == 1,
                       "The vector f("
                           << f.getID()
                           << ") has not the good number of component.");
 #endif
 
   Real integral = fe_engine::details::IntegrateScalarHelper<kind>::call(
       integrator, f, type, ghost_type, filter_elements);
   AKANTU_DEBUG_OUT();
   return integral;
 }
 
 /* -------------------------------------------------------------------------- */
 /**
  * Helper class to be able to write a partial specialization on the element kind
  */
 namespace fe_engine {
   namespace details {
     template <ElementKind kind> struct IntegrateScalarOnOneElementHelper {};
 
 #define INTEGRATE(type)                                                        \
   res = integrator.template integrate<type>(f, index, ghost_type);
 
 #define AKANTU_SPECIALIZE_INTEGRATE_SCALAR_ON_ONE_ELEMENT_HELPER(kind)         \
   template <> struct IntegrateScalarOnOneElementHelper<kind> {                 \
     template <class I>                                                         \
     static Real call(const I & integrator, const Vector<Real> & f,             \
                      const ElementType & type, UInt index,                     \
                      const GhostType & ghost_type) {                           \
       Real res = 0.;                                                           \
       AKANTU_BOOST_KIND_ELEMENT_SWITCH(INTEGRATE, kind);                       \
       return res;                                                              \
     }                                                                          \
   };
 
     AKANTU_BOOST_ALL_KIND(
         AKANTU_SPECIALIZE_INTEGRATE_SCALAR_ON_ONE_ELEMENT_HELPER)
 
 #undef AKANTU_SPECIALIZE_INTEGRATE_SCALAR_ON_ONE_ELEMENT_HELPER
 #undef INTEGRATE
   } // namespace details
 } // namespace fe_engine
 
 template <template <ElementKind, class> class I, template <ElementKind> class S,
           ElementKind kind, class IntegrationOrderFunctor>
 Real FEEngineTemplate<I, S, kind, IntegrationOrderFunctor>::integrate(
     const Vector<Real> & f, const ElementType & type, UInt index,
     const GhostType & ghost_type) const {
 
   Real res = fe_engine::details::IntegrateScalarOnOneElementHelper<kind>::call(
       integrator, f, type, index, ghost_type);
   return res;
 }
 
 /* -------------------------------------------------------------------------- */
 /**
  * Helper class to be able to write a partial specialization on the element kind
  */
 namespace fe_engine {
   namespace details {
     template <ElementKind kind> struct IntegrateOnIntegrationPointsHelper {};
 
 #define INTEGRATE(type)                                                        \
   integrator.template integrateOnIntegrationPoints<type>(                      \
       f, intf, nb_degree_of_freedom, ghost_type, filter_elements);
 
 #define AKANTU_SPECIALIZE_INTEGRATE_ON_INTEGRATION_POINTS_HELPER(kind)         \
   template <> struct IntegrateOnIntegrationPointsHelper<kind> {                \
     template <class I>                                                         \
     static void call(const I & integrator, const Array<Real> & f,              \
                      Array<Real> & intf, UInt nb_degree_of_freedom,            \
                      const ElementType & type, const GhostType & ghost_type,   \
                      const Array<UInt> & filter_elements) {                    \
       AKANTU_BOOST_KIND_ELEMENT_SWITCH(INTEGRATE, kind);                       \
     }                                                                          \
   };
 
     AKANTU_BOOST_ALL_KIND(
         AKANTU_SPECIALIZE_INTEGRATE_ON_INTEGRATION_POINTS_HELPER)
 
 #undef AKANTU_SPECIALIZE_INTEGRATE_ON_INTEGRATION_POINTS_HELPER
 #undef INTEGRATE
   } // namespace details
 } // namespace fe_engine
 
 template <template <ElementKind, class> class I, template <ElementKind> class S,
           ElementKind kind, class IntegrationOrderFunctor>
 void FEEngineTemplate<I, S, kind, IntegrationOrderFunctor>::
     integrateOnIntegrationPoints(const Array<Real> & f, Array<Real> & intf,
                                  UInt nb_degree_of_freedom,
                                  const ElementType & type,
                                  const GhostType & ghost_type,
                                  const Array<UInt> & filter_elements) const {
 
   UInt nb_element = mesh.getNbElement(type, ghost_type);
   if (filter_elements != empty_filter)
     nb_element = filter_elements.size();
   UInt nb_quadrature_points = getNbIntegrationPoints(type);
 #ifndef AKANTU_NDEBUG
   //   std::stringstream sstr; sstr << ghost_type;
   //   AKANTU_DEBUG_ASSERT(sstr.str() == nablauq.getTag(),
   //                  "The vector " << nablauq.getID() << " is not taged " <<
   //                  ghost_type);
 
   AKANTU_DEBUG_ASSERT(f.size() == nb_element * nb_quadrature_points,
                       "The vector f(" << f.getID() << " size " << f.size()
                                       << ") has not the good size ("
                                       << nb_element << ").");
   AKANTU_DEBUG_ASSERT(f.getNbComponent() == nb_degree_of_freedom,
                       "The vector f("
                           << f.getID()
                           << ") has not the good number of component.");
   AKANTU_DEBUG_ASSERT(intf.getNbComponent() == nb_degree_of_freedom,
                       "The vector intf("
                           << intf.getID()
                           << ") has not the good number of component.");
 #endif
 
   intf.resize(nb_element * nb_quadrature_points);
   fe_engine::details::IntegrateOnIntegrationPointsHelper<kind>::call(
       integrator, f, intf, nb_degree_of_freedom, type, ghost_type,
       filter_elements);
 }
 
 /* -------------------------------------------------------------------------- */
 /**
  * Helper class to be able to write a partial specialization on the element kind
  */
 namespace fe_engine {
   namespace details {
     template <ElementKind kind> struct InterpolateOnIntegrationPointsHelper {
       template <class S>
       static void call(const S &, const Array<Real> &, Array<Real> &,
                        const UInt, const ElementType &, const GhostType &,
                        const Array<UInt> &) {
         AKANTU_TO_IMPLEMENT();
       }
     };
 
 #define INTERPOLATE(type)                                                      \
   shape_functions.template interpolateOnIntegrationPoints<type>(               \
       u, uq, nb_degree_of_freedom, ghost_type, filter_elements);
 
 #define AKANTU_SPECIALIZE_INTERPOLATE_ON_INTEGRATION_POINTS_HELPER(kind)       \
   template <> struct InterpolateOnIntegrationPointsHelper<kind> {              \
     template <class S>                                                         \
     static void call(const S & shape_functions, const Array<Real> & u,         \
                      Array<Real> & uq, const UInt nb_degree_of_freedom,        \
                      const ElementType & type, const GhostType & ghost_type,   \
                      const Array<UInt> & filter_elements) {                    \
       AKANTU_BOOST_KIND_ELEMENT_SWITCH(INTERPOLATE, kind);                     \
     }                                                                          \
   };
     AKANTU_BOOST_ALL_KIND_LIST(
         AKANTU_SPECIALIZE_INTERPOLATE_ON_INTEGRATION_POINTS_HELPER,
         AKANTU_FE_ENGINE_LIST_INTERPOLATE_ON_INTEGRATION_POINTS)
 
 #undef AKANTU_SPECIALIZE_INTERPOLATE_ON_INTEGRATION_POINTS_HELPER
 #undef INTERPOLATE
   } // namespace details
 } // namespace fe_engine
 
 template <template <ElementKind, class> class I, template <ElementKind> class S,
           ElementKind kind, class IntegrationOrderFunctor>
 void FEEngineTemplate<I, S, kind, IntegrationOrderFunctor>::
     interpolateOnIntegrationPoints(const Array<Real> & u, Array<Real> & uq,
                                    const UInt nb_degree_of_freedom,
                                    const ElementType & type,
                                    const GhostType & ghost_type,
                                    const Array<UInt> & filter_elements) const {
   AKANTU_DEBUG_IN();
 
   UInt nb_points =
       shape_functions.getIntegrationPoints(type, ghost_type).cols();
   UInt nb_element = mesh.getNbElement(type, ghost_type);
   if (filter_elements != empty_filter)
     nb_element = filter_elements.size();
 #ifndef AKANTU_NDEBUG
 
   AKANTU_DEBUG_ASSERT(u.size() == mesh.getNbNodes(),
                       "The vector u(" << u.getID()
                                       << ") has not the good size.");
   AKANTU_DEBUG_ASSERT(u.getNbComponent() == nb_degree_of_freedom,
                       "The vector u("
                           << u.getID()
                           << ") has not the good number of component.");
   AKANTU_DEBUG_ASSERT(uq.getNbComponent() == nb_degree_of_freedom,
                       "The vector uq("
                           << uq.getID()
                           << ") has not the good number of component.");
 #endif
 
   uq.resize(nb_element * nb_points);
 
   fe_engine::details::InterpolateOnIntegrationPointsHelper<kind>::call(
       shape_functions, u, uq, nb_degree_of_freedom, type, ghost_type,
       filter_elements);
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <template <ElementKind, class> class I, template <ElementKind> class S,
           ElementKind kind, class IntegrationOrderFunctor>
 void FEEngineTemplate<I, S, kind, IntegrationOrderFunctor>::
     interpolateOnIntegrationPoints(
         const Array<Real> & u, ElementTypeMapArray<Real> & uq,
         const ElementTypeMapArray<UInt> * filter_elements) const {
   AKANTU_DEBUG_IN();
 
   const Array<UInt> * filter = nullptr;
 
   for (auto ghost_type : ghost_types) {
     for (auto & type : uq.elementTypes(_all_dimensions, ghost_type, kind)) {
       UInt nb_quad_per_element = getNbIntegrationPoints(type, ghost_type);
 
       UInt nb_element = 0;
 
       if (filter_elements) {
         filter = &((*filter_elements)(type, ghost_type));
         nb_element = filter->size();
       } else {
         filter = &empty_filter;
         nb_element = mesh.getNbElement(type, ghost_type);
       }
 
       UInt nb_tot_quad = nb_quad_per_element * nb_element;
 
       Array<Real> & quad = uq(type, ghost_type);
       quad.resize(nb_tot_quad);
 
       interpolateOnIntegrationPoints(u, quad, quad.getNbComponent(), type,
                                      ghost_type, *filter);
     }
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 namespace fe_engine {
   namespace details {
     template <ElementKind kind> struct ComputeBtDHelper {};
 
 #define COMPUTE_BTD(type)                                                      \
   shape_functions.template computeBtD<type>(Ds, BtDs, ghost_type,              \
                                             filter_elements);
 
 #define AKANTU_SPECIALIZE_COMPUTE_BtD_HELPER(kind)                             \
   template <> struct ComputeBtDHelper<kind> {                                  \
     template <class S>                                                         \
     static void call(const S & shape_functions, const Array<Real> & Ds,        \
                      Array<Real> & BtDs, const ElementType & type,             \
                      const GhostType & ghost_type,                             \
                      const Array<UInt> & filter_elements) {                    \
       AKANTU_BOOST_KIND_ELEMENT_SWITCH(COMPUTE_BTD, kind);                     \
     }                                                                          \
   };
 
     AKANTU_BOOST_ALL_KIND(AKANTU_SPECIALIZE_COMPUTE_BtD_HELPER)
 
 #undef AKANTU_SPECIALIZE_COMPUTE_BtD_HELPER
 #undef COMPUTE_BTD
   } // namespace details
 } // namespace fe_engine
 
 template <template <ElementKind, class> class I, template <ElementKind> class S,
           ElementKind kind, class IntegrationOrderFunctor>
 inline void FEEngineTemplate<I, S, kind, IntegrationOrderFunctor>::computeBtD(
     const Array<Real> & Ds, Array<Real> & BtDs, const ElementType & type,
     const GhostType & ghost_type, const Array<UInt> & filter_elements) const {
   fe_engine::details::ComputeBtDHelper<kind>::call(
       shape_functions, Ds, BtDs, type, ghost_type, filter_elements);
 }
 
 /* -------------------------------------------------------------------------- */
 namespace fe_engine {
   namespace details {
     template <ElementKind kind> struct ComputeBtDBHelper {};
 
 #define COMPUTE_BTDB(type)                                                     \
   shape_functions.template computeBtDB<type>(Ds, BtDBs, order_d, ghost_type,   \
                                              filter_elements);
 
 #define AKANTU_SPECIALIZE_COMPUTE_BtDB_HELPER(kind)                            \
   template <> struct ComputeBtDBHelper<kind> {                                 \
     template <class S>                                                         \
     static void call(const S & shape_functions, const Array<Real> & Ds,        \
                      Array<Real> & BtDBs, UInt order_d,                        \
                      const ElementType & type, const GhostType & ghost_type,   \
                      const Array<UInt> & filter_elements) {                    \
       AKANTU_BOOST_KIND_ELEMENT_SWITCH(COMPUTE_BTDB, kind);                    \
     }                                                                          \
   };
 
     AKANTU_BOOST_ALL_KIND(AKANTU_SPECIALIZE_COMPUTE_BtDB_HELPER)
 
 #undef AKANTU_SPECIALIZE_COMPUTE_BtDB_HELPER
 #undef COMPUTE_BTDB
   } // namespace details
 } // namespace fe_engine
 
 template <template <ElementKind, class> class I, template <ElementKind> class S,
           ElementKind kind, class IntegrationOrderFunctor>
 inline void FEEngineTemplate<I, S, kind, IntegrationOrderFunctor>::computeBtDB(
     const Array<Real> & Ds, Array<Real> & BtDBs, UInt order_d,
     const ElementType & type, const GhostType & ghost_type,
     const Array<UInt> & filter_elements) const {
   fe_engine::details::ComputeBtDBHelper<kind>::call(
       shape_functions, Ds, BtDBs, order_d, type, ghost_type, filter_elements);
 }
 
 /* -------------------------------------------------------------------------- */
 template <template <ElementKind, class> class I, template <ElementKind> class S,
           ElementKind kind, class IntegrationOrderFunctor>
 inline void FEEngineTemplate<I, S, kind, IntegrationOrderFunctor>::
     computeIntegrationPointsCoordinates(
         ElementTypeMapArray<Real> & quadrature_points_coordinates,
         const ElementTypeMapArray<UInt> * filter_elements) const {
 
   const Array<Real> & nodes_coordinates = mesh.getNodes();
 
   interpolateOnIntegrationPoints(
       nodes_coordinates, quadrature_points_coordinates, filter_elements);
 }
 
 /* -------------------------------------------------------------------------- */
 template <template <ElementKind, class> class I, template <ElementKind> class S,
           ElementKind kind, class IntegrationOrderFunctor>
 inline void FEEngineTemplate<I, S, kind, IntegrationOrderFunctor>::
     computeIntegrationPointsCoordinates(
         Array<Real> & quadrature_points_coordinates, const ElementType & type,
         const GhostType & ghost_type,
         const Array<UInt> & filter_elements) const {
 
   const Array<Real> & nodes_coordinates = mesh.getNodes();
 
   UInt spatial_dimension = mesh.getSpatialDimension();
 
   interpolateOnIntegrationPoints(
       nodes_coordinates, quadrature_points_coordinates, spatial_dimension, type,
       ghost_type, filter_elements);
 }
 
 /* -------------------------------------------------------------------------- */
 template <template <ElementKind, class> class I, template <ElementKind> class S,
           ElementKind kind, class IntegrationOrderFunctor>
 inline void FEEngineTemplate<I, S, kind, IntegrationOrderFunctor>::
     initElementalFieldInterpolationFromIntegrationPoints(
         const ElementTypeMapArray<Real> & interpolation_points_coordinates,
         ElementTypeMapArray<Real> & interpolation_points_coordinates_matrices,
         ElementTypeMapArray<Real> & quad_points_coordinates_inv_matrices,
         const ElementTypeMapArray<UInt> * element_filter) const {
 
   AKANTU_DEBUG_IN();
 
   UInt spatial_dimension = this->mesh.getSpatialDimension();
 
   ElementTypeMapArray<Real> quadrature_points_coordinates(
       "quadrature_points_coordinates_for_interpolation", getID(),
       getMemoryID());
 
   quadrature_points_coordinates.initialize(*this,
                                            _nb_component = spatial_dimension);
 
   computeIntegrationPointsCoordinates(quadrature_points_coordinates,
                                       element_filter);
   shape_functions.initElementalFieldInterpolationFromIntegrationPoints(
       interpolation_points_coordinates,
       interpolation_points_coordinates_matrices,
       quad_points_coordinates_inv_matrices, quadrature_points_coordinates,
       element_filter);
 }
 
 /* -------------------------------------------------------------------------- */
 template <template <ElementKind, class> class I, template <ElementKind> class S,
           ElementKind kind, class IntegrationOrderFunctor>
 inline void FEEngineTemplate<I, S, kind, IntegrationOrderFunctor>::
     interpolateElementalFieldFromIntegrationPoints(
         const ElementTypeMapArray<Real> & field,
         const ElementTypeMapArray<Real> & interpolation_points_coordinates,
         ElementTypeMapArray<Real> & result, const GhostType ghost_type,
         const ElementTypeMapArray<UInt> * element_filter) const {
 
   ElementTypeMapArray<Real> interpolation_points_coordinates_matrices(
       "interpolation_points_coordinates_matrices", id, memory_id);
   ElementTypeMapArray<Real> quad_points_coordinates_inv_matrices(
       "quad_points_coordinates_inv_matrices", id, memory_id);
 
   initElementalFieldInterpolationFromIntegrationPoints(
       interpolation_points_coordinates,
       interpolation_points_coordinates_matrices,
       quad_points_coordinates_inv_matrices, element_filter);
 
   interpolateElementalFieldFromIntegrationPoints(
       field, interpolation_points_coordinates_matrices,
       quad_points_coordinates_inv_matrices, result, ghost_type, element_filter);
 }
 
 /* -------------------------------------------------------------------------- */
 template <template <ElementKind, class> class I, template <ElementKind> class S,
           ElementKind kind, class IntegrationOrderFunctor>
 inline void FEEngineTemplate<I, S, kind, IntegrationOrderFunctor>::
     interpolateElementalFieldFromIntegrationPoints(
         const ElementTypeMapArray<Real> & field,
         const ElementTypeMapArray<Real> &
             interpolation_points_coordinates_matrices,
         const ElementTypeMapArray<Real> & quad_points_coordinates_inv_matrices,
         ElementTypeMapArray<Real> & result, const GhostType ghost_type,
         const ElementTypeMapArray<UInt> * element_filter) const {
 
   shape_functions.interpolateElementalFieldFromIntegrationPoints(
       field, interpolation_points_coordinates_matrices,
       quad_points_coordinates_inv_matrices, result, ghost_type, element_filter);
 }
 
 /* -------------------------------------------------------------------------- */
 /**
  * Helper class to be able to write a partial specialization on the element kind
  */
 namespace fe_engine {
   namespace details {
     template <ElementKind kind> struct InterpolateHelper {
       template <class S>
       static void call(const S &, const Vector<Real> &, UInt,
                        const Matrix<Real> &, Vector<Real> &,
                        const ElementType &, const GhostType &) {
         AKANTU_TO_IMPLEMENT();
       }
     };
 
 #define INTERPOLATE(type)                                                      \
   shape_functions.template interpolate<type>(                                  \
       real_coords, element, nodal_values, interpolated, ghost_type);
 
 #define AKANTU_SPECIALIZE_INTERPOLATE_HELPER(kind)                             \
   template <> struct InterpolateHelper<kind> {                                 \
     template <class S>                                                         \
     static void call(const S & shape_functions,                                \
                      const Vector<Real> & real_coords, UInt element,           \
                      const Matrix<Real> & nodal_values,                        \
                      Vector<Real> & interpolated, const ElementType & type,    \
                      const GhostType & ghost_type) {                           \
       AKANTU_BOOST_KIND_ELEMENT_SWITCH(INTERPOLATE, kind);                     \
     }                                                                          \
   };
 
     AKANTU_BOOST_ALL_KIND_LIST(AKANTU_SPECIALIZE_INTERPOLATE_HELPER,
                                AKANTU_FE_ENGINE_LIST_INTERPOLATE)
 
 #undef AKANTU_SPECIALIZE_INTERPOLATE_HELPER
 #undef INTERPOLATE
   } // namespace details
 } // namespace fe_engine
 
 template <template <ElementKind, class> class I, template <ElementKind> class S,
           ElementKind kind, class IntegrationOrderFunctor>
 inline void FEEngineTemplate<I, S, kind, IntegrationOrderFunctor>::interpolate(
     const Vector<Real> & real_coords, const Matrix<Real> & nodal_values,
     Vector<Real> & interpolated, const Element & element) const {
 
   AKANTU_DEBUG_IN();
 
   fe_engine::details::InterpolateHelper<kind>::call(
       shape_functions, real_coords, element.element, nodal_values, interpolated,
       element.type, element.ghost_type);
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <template <ElementKind, class> class I, template <ElementKind> class S,
           ElementKind kind, class IntegrationOrderFunctor>
 void FEEngineTemplate<I, S, kind, IntegrationOrderFunctor>::
     computeNormalsOnIntegrationPoints(const GhostType & ghost_type) {
   AKANTU_DEBUG_IN();
 
   computeNormalsOnIntegrationPoints(mesh.getNodes(), ghost_type);
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <template <ElementKind, class> class I, template <ElementKind> class S,
           ElementKind kind, class IntegrationOrderFunctor>
 void FEEngineTemplate<I, S, kind, IntegrationOrderFunctor>::
     computeNormalsOnIntegrationPoints(const Array<Real> & field,
                                       const GhostType & ghost_type) {
   AKANTU_DEBUG_IN();
 
   //  Real * coord = mesh.getNodes().storage();
   UInt spatial_dimension = mesh.getSpatialDimension();
 
   // allocate the normal arrays
   for (auto & type : mesh.elementTypes(element_dimension, ghost_type, kind)) {
     UInt size = mesh.getNbElement(type, ghost_type);
     if (normals_on_integration_points.exists(type, ghost_type)) {
       normals_on_integration_points(type, ghost_type).resize(size);
     } else {
       normals_on_integration_points.alloc(size, spatial_dimension, type,
                                           ghost_type);
     }
   }
 
   // loop over the type to build the normals
   for (auto & type : mesh.elementTypes(element_dimension, ghost_type, kind)) {
     Array<Real> & normals_on_quad =
         normals_on_integration_points(type, ghost_type);
     computeNormalsOnIntegrationPoints(field, normals_on_quad, type, ghost_type);
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 /**
  * Helper class to be able to write a partial specialization on the element kind
  */
 namespace fe_engine {
   namespace details {
     template <ElementKind kind> struct ComputeNormalsOnIntegrationPoints {
       template <template <ElementKind, class> class I,
                 template <ElementKind> class S, ElementKind k, class IOF>
       static void call(const FEEngineTemplate<I, S, k, IOF> &,
                        const Array<Real> &, Array<Real> &, const ElementType &,
                        const GhostType &) {
         AKANTU_TO_IMPLEMENT();
       }
     };
 
 #define COMPUTE_NORMALS_ON_INTEGRATION_POINTS(type)                            \
   fem.template computeNormalsOnIntegrationPoints<type>(field, normal,          \
                                                        ghost_type);
 
 #define AKANTU_SPECIALIZE_COMPUTE_NORMALS_ON_INTEGRATION_POINTS(kind)          \
   template <> struct ComputeNormalsOnIntegrationPoints<kind> {                 \
     template <template <ElementKind, class> class I,                           \
               template <ElementKind> class S, ElementKind k, class IOF>        \
     static void call(const FEEngineTemplate<I, S, k, IOF> & fem,               \
                      const Array<Real> & field, Array<Real> & normal,          \
                      const ElementType & type, const GhostType & ghost_type) { \
       AKANTU_BOOST_KIND_ELEMENT_SWITCH(COMPUTE_NORMALS_ON_INTEGRATION_POINTS,  \
                                        kind);                                  \
     }                                                                          \
   };
 
     AKANTU_BOOST_ALL_KIND_LIST(
         AKANTU_SPECIALIZE_COMPUTE_NORMALS_ON_INTEGRATION_POINTS,
         AKANTU_FE_ENGINE_LIST_COMPUTE_NORMALS_ON_INTEGRATION_POINTS)
 
 #undef AKANTU_SPECIALIZE_COMPUTE_NORMALS_ON_INTEGRATION_POINTS
 #undef COMPUTE_NORMALS_ON_INTEGRATION_POINTS
   } // namespace details
 } // namespace fe_engine
 
 template <template <ElementKind, class> class I, template <ElementKind> class S,
           ElementKind kind, class IntegrationOrderFunctor>
 void FEEngineTemplate<I, S, kind, IntegrationOrderFunctor>::
     computeNormalsOnIntegrationPoints(const Array<Real> & field,
                                       Array<Real> & normal,
                                       const ElementType & type,
                                       const GhostType & ghost_type) const {
   fe_engine::details::ComputeNormalsOnIntegrationPoints<kind>::call(
       *this, field, normal, type, ghost_type);
 }
 
 /* -------------------------------------------------------------------------- */
 template <template <ElementKind, class> class I, template <ElementKind> class S,
           ElementKind kind, class IntegrationOrderFunctor>
 template <ElementType type>
 void FEEngineTemplate<I, S, kind, IntegrationOrderFunctor>::
     computeNormalsOnIntegrationPoints(const Array<Real> & field,
                                       Array<Real> & normal,
                                       const GhostType & ghost_type) const {
   AKANTU_DEBUG_IN();
 
   if (type == _point_1) {
     computeNormalsOnIntegrationPointsPoint1(field, normal, ghost_type);
     return;
   }
 
   UInt spatial_dimension = mesh.getSpatialDimension();
   UInt nb_nodes_per_element = Mesh::getNbNodesPerElement(type);
   UInt nb_points = getNbIntegrationPoints(type, ghost_type);
 
   UInt nb_element = mesh.getConnectivity(type, ghost_type).size();
   normal.resize(nb_element * nb_points);
   Array<Real>::matrix_iterator normals_on_quad =
       normal.begin_reinterpret(spatial_dimension, nb_points, nb_element);
   Array<Real> f_el(0, spatial_dimension * nb_nodes_per_element);
   FEEngine::extractNodalToElementField(mesh, field, f_el, type, ghost_type);
 
   const Matrix<Real> & quads =
       integrator.template getIntegrationPoints<type>(ghost_type);
 
   Array<Real>::matrix_iterator f_it =
       f_el.begin(spatial_dimension, nb_nodes_per_element);
 
   for (UInt elem = 0; elem < nb_element; ++elem) {
     ElementClass<type>::computeNormalsOnNaturalCoordinates(quads, *f_it,
                                                            *normals_on_quad);
     ++normals_on_quad;
     ++f_it;
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 /**
  * Helper class to be able to write a partial specialization on the element kind
  */
 template <ElementKind kind> struct InverseMapHelper {
   template <class S>
   static void
   call(const S & /*shape_functions*/, const Vector<Real> & /*real_coords*/,
        UInt /*element*/, const ElementType & /*type*/,
        Vector<Real> & /*natural_coords*/, const GhostType & /*ghost_type*/) {
     AKANTU_TO_IMPLEMENT();
   }
 };
 
 #define INVERSE_MAP(type)                                                      \
   shape_functions.template inverseMap<type>(real_coords, element,              \
                                             natural_coords, ghost_type);
 
 #define AKANTU_SPECIALIZE_INVERSE_MAP_HELPER(kind)                             \
   template <> struct InverseMapHelper<kind> {                                  \
     template <class S>                                                         \
     static void call(const S & shape_functions,                                \
                      const Vector<Real> & real_coords, UInt element,           \
                      const ElementType & type, Vector<Real> & natural_coords,  \
                      const GhostType & ghost_type) {                           \
       AKANTU_BOOST_KIND_ELEMENT_SWITCH(INVERSE_MAP, kind);                     \
     }                                                                          \
   };
 
 AKANTU_BOOST_ALL_KIND_LIST(AKANTU_SPECIALIZE_INVERSE_MAP_HELPER,
                            AKANTU_FE_ENGINE_LIST_INVERSE_MAP)
 
 #undef AKANTU_SPECIALIZE_INVERSE_MAP_HELPER
 #undef INVERSE_MAP
 
 template <template <ElementKind, class> class I, template <ElementKind> class S,
           ElementKind kind, class IntegrationOrderFunctor>
 inline void FEEngineTemplate<I, S, kind, IntegrationOrderFunctor>::inverseMap(
     const Vector<Real> & real_coords, UInt element, const ElementType & type,
     Vector<Real> & natural_coords, const GhostType & ghost_type) const {
 
   AKANTU_DEBUG_IN();
 
   InverseMapHelper<kind>::call(shape_functions, real_coords, element, type,
                                natural_coords, ghost_type);
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 /**
  * Helper class to be able to write a partial specialization on the element kind
  */
 namespace fe_engine {
   namespace details {
     template <ElementKind kind> struct ContainsHelper {
       template <class S>
       static void call(const S &, const Vector<Real> &, UInt,
                        const ElementType &, const GhostType &) {
         AKANTU_TO_IMPLEMENT();
       }
     };
 
 #define CONTAINS(type)                                                         \
   contain = shape_functions.template contains<type>(real_coords, element,      \
                                                     ghost_type);
 
 #define AKANTU_SPECIALIZE_CONTAINS_HELPER(kind)                                \
   template <> struct ContainsHelper<kind> {                                    \
     template <template <ElementKind> class S, ElementKind k>                   \
     static bool call(const S<k> & shape_functions,                             \
                      const Vector<Real> & real_coords, UInt element,           \
                      const ElementType & type, const GhostType & ghost_type) { \
       bool contain = false;                                                    \
       AKANTU_BOOST_KIND_ELEMENT_SWITCH(CONTAINS, kind);                        \
       return contain;                                                          \
     }                                                                          \
   };
 
     AKANTU_BOOST_ALL_KIND_LIST(AKANTU_SPECIALIZE_CONTAINS_HELPER,
                                AKANTU_FE_ENGINE_LIST_CONTAINS)
 
 #undef AKANTU_SPECIALIZE_CONTAINS_HELPER
 #undef CONTAINS
   } // namespace details
 } // namespace fe_engine
 
 template <template <ElementKind, class> class I, template <ElementKind> class S,
           ElementKind kind, class IntegrationOrderFunctor>
 inline bool FEEngineTemplate<I, S, kind, IntegrationOrderFunctor>::contains(
     const Vector<Real> & real_coords, UInt element, const ElementType & type,
     const GhostType & ghost_type) const {
   return fe_engine::details::ContainsHelper<kind>::call(
       shape_functions, real_coords, element, type, ghost_type);
 }
 
 /* -------------------------------------------------------------------------- */
 /**
  * Helper class to be able to write a partial specialization on the element kind
  */
 namespace fe_engine {
   namespace details {
     template <ElementKind kind> struct ComputeShapesHelper {
       template <class S>
       static void call(const S &, const Vector<Real> &, UInt, const ElementType,
                        Vector<Real> &, const GhostType &) {
         AKANTU_TO_IMPLEMENT();
       }
     };
 
 #define COMPUTE_SHAPES(type)                                                   \
   shape_functions.template computeShapes<type>(real_coords, element, shapes,   \
                                                ghost_type);
 
 #define AKANTU_SPECIALIZE_COMPUTE_SHAPES_HELPER(kind)                          \
   template <> struct ComputeShapesHelper<kind> {                               \
     template <class S>                                                         \
     static void call(const S & shape_functions,                                \
                      const Vector<Real> & real_coords, UInt element,           \
                      const ElementType type, Vector<Real> & shapes,            \
                      const GhostType & ghost_type) {                           \
       AKANTU_BOOST_KIND_ELEMENT_SWITCH(COMPUTE_SHAPES, kind);                  \
     }                                                                          \
   };
 
     AKANTU_BOOST_ALL_KIND_LIST(AKANTU_SPECIALIZE_COMPUTE_SHAPES_HELPER,
                                AKANTU_FE_ENGINE_LIST_COMPUTE_SHAPES)
 
 #undef AKANTU_SPECIALIZE_COMPUTE_SHAPES_HELPER
 #undef COMPUTE_SHAPES
   } // namespace details
 } // namespace fe_engine
 template <template <ElementKind, class> class I, template <ElementKind> class S,
           ElementKind kind, class IntegrationOrderFunctor>
 inline void
 FEEngineTemplate<I, S, kind, IntegrationOrderFunctor>::computeShapes(
     const Vector<Real> & real_coords, UInt element, const ElementType & type,
     Vector<Real> & shapes, const GhostType & ghost_type) const {
 
   AKANTU_DEBUG_IN();
 
   fe_engine::details::ComputeShapesHelper<kind>::call(
       shape_functions, real_coords, element, type, shapes, ghost_type);
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 /**
  * Helper class to be able to write a partial specialization on the element kind
  */
 namespace fe_engine {
   namespace details {
     template <ElementKind kind> struct ComputeShapeDerivativesHelper {
       template <class S>
       static void call(__attribute__((unused)) const S & shape_functions,
                        __attribute__((unused)) const Vector<Real> & real_coords,
                        __attribute__((unused)) UInt element,
                        __attribute__((unused)) const ElementType type,
                        __attribute__((unused)) Matrix<Real> & shape_derivatives,
                        __attribute__((unused)) const GhostType & ghost_type) {
         AKANTU_TO_IMPLEMENT();
       }
     };
 
 #define COMPUTE_SHAPE_DERIVATIVES(type)                                        \
   Matrix<Real> coords_mat(real_coords.storage(), shape_derivatives.rows(), 1); \
   Tensor3<Real> shapesd_tensor(shape_derivatives.storage(),                    \
                                shape_derivatives.rows(),                       \
                                shape_derivatives.cols(), 1);                   \
   shape_functions.template computeShapeDerivatives<type>(                      \
       coords_mat, element, shapesd_tensor, ghost_type);
 
 #define AKANTU_SPECIALIZE_COMPUTE_SHAPE_DERIVATIVES_HELPER(kind)               \
   template <> struct ComputeShapeDerivativesHelper<kind> {                     \
     template <class S>                                                         \
     static void call(const S & shape_functions,                                \
                      const Vector<Real> & real_coords, UInt element,           \
                      const ElementType type, Matrix<Real> & shape_derivatives, \
                      const GhostType & ghost_type) {                           \
       AKANTU_BOOST_KIND_ELEMENT_SWITCH(COMPUTE_SHAPE_DERIVATIVES, kind);       \
     }                                                                          \
   };
 
     AKANTU_BOOST_ALL_KIND_LIST(
         AKANTU_SPECIALIZE_COMPUTE_SHAPE_DERIVATIVES_HELPER,
         AKANTU_FE_ENGINE_LIST_COMPUTE_SHAPES_DERIVATIVES)
 
 #undef AKANTU_SPECIALIZE_COMPUTE_SHAPE_DERIVATIVES_HELPER
 #undef COMPUTE_SHAPE_DERIVATIVES
   } // namespace details
 } // namespace fe_engine
 
 template <template <ElementKind, class> class I, template <ElementKind> class S,
           ElementKind kind, class IntegrationOrderFunctor>
 inline void
 FEEngineTemplate<I, S, kind, IntegrationOrderFunctor>::computeShapeDerivatives(
     const Vector<Real> & real_coords, UInt element, const ElementType & type,
     Matrix<Real> & shape_derivatives, const GhostType & ghost_type) const {
   AKANTU_DEBUG_IN();
 
   fe_engine::details::ComputeShapeDerivativesHelper<kind>::call(
       shape_functions, real_coords, element, type, shape_derivatives,
       ghost_type);
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 /**
  * Helper class to be able to write a partial specialization on the element kind
  */
 namespace fe_engine {
   namespace details {
     template <ElementKind kind> struct GetNbIntegrationPointsHelper {};
 
 #define GET_NB_INTEGRATION_POINTS(type)                                        \
   nb_quad_points = integrator.template getNbIntegrationPoints<type>(ghost_type);
 
 #define AKANTU_SPECIALIZE_GET_NB_INTEGRATION_POINTS_HELPER(kind)               \
   template <> struct GetNbIntegrationPointsHelper<kind> {                      \
     template <template <ElementKind, class> class I, ElementKind k, class IOF> \
     static UInt call(const I<k, IOF> & integrator, const ElementType type,     \
                      const GhostType & ghost_type) {                           \
       UInt nb_quad_points = 0;                                                 \
       AKANTU_BOOST_KIND_ELEMENT_SWITCH(GET_NB_INTEGRATION_POINTS, kind);       \
       return nb_quad_points;                                                   \
     }                                                                          \
   };
 
     AKANTU_BOOST_ALL_KIND(AKANTU_SPECIALIZE_GET_NB_INTEGRATION_POINTS_HELPER)
 
 #undef AKANTU_SPECIALIZE_GET_NB_INTEGRATION_POINTS_HELPER
 #undef GET_NB_INTEGRATION
   } // namespace details
 } // namespace fe_engine
 
 template <template <ElementKind, class> class I, template <ElementKind> class S,
           ElementKind kind, class IntegrationOrderFunctor>
 inline UInt
 FEEngineTemplate<I, S, kind, IntegrationOrderFunctor>::getNbIntegrationPoints(
     const ElementType & type, const GhostType & ghost_type) const {
   return fe_engine::details::GetNbIntegrationPointsHelper<kind>::call(
       integrator, type, ghost_type);
 }
 
 /* -------------------------------------------------------------------------- */
 /**
  * Helper class to be able to write a partial specialization on the element kind
  */
 namespace fe_engine {
   namespace details {
     template <ElementKind kind> struct GetShapesHelper {};
 
 #define GET_SHAPES(type) ret = &(shape_functions.getShapes(type, ghost_type));
 
 #define AKANTU_SPECIALIZE_GET_SHAPES_HELPER(kind)                              \
   template <> struct GetShapesHelper<kind> {                                   \
     template <class S>                                                         \
     static const Array<Real> & call(const S & shape_functions,                 \
                                     const ElementType type,                    \
                                     const GhostType & ghost_type) {            \
       const Array<Real> * ret = NULL;                                          \
       AKANTU_BOOST_KIND_ELEMENT_SWITCH(GET_SHAPES, kind);                      \
       return *ret;                                                             \
     }                                                                          \
   };
 
     AKANTU_BOOST_ALL_KIND(AKANTU_SPECIALIZE_GET_SHAPES_HELPER)
 
 #undef AKANTU_SPECIALIZE_GET_SHAPES_HELPER
 #undef GET_SHAPES
   } // namespace details
 } // namespace fe_engine
 
 template <template <ElementKind, class> class I, template <ElementKind> class S,
           ElementKind kind, class IntegrationOrderFunctor>
 inline const Array<Real> &
 FEEngineTemplate<I, S, kind, IntegrationOrderFunctor>::getShapes(
     const ElementType & type, const GhostType & ghost_type,
     __attribute__((unused)) UInt id) const {
   return fe_engine::details::GetShapesHelper<kind>::call(shape_functions, type,
                                                          ghost_type);
 }
 
 /* -------------------------------------------------------------------------- */
 /**
  * Helper class to be able to write a partial specialization on the element kind
  */
 namespace fe_engine {
   namespace details {
     template <ElementKind kind> struct GetShapesDerivativesHelper {
       template <template <ElementKind> class S, ElementKind k>
       static const Array<Real> & call(const S<k> &, const ElementType &,
                                       const GhostType &, UInt) {
         AKANTU_TO_IMPLEMENT();
       }
     };
 
 #define GET_SHAPES_DERIVATIVES(type)                                           \
   ret = &(shape_functions.getShapesDerivatives(type, ghost_type));
 
 #define AKANTU_SPECIALIZE_GET_SHAPES_DERIVATIVES_HELPER(kind)                  \
   template <> struct GetShapesDerivativesHelper<kind> {                        \
     template <template <ElementKind> class S, ElementKind k>                   \
     static const Array<Real> &                                                 \
     call(const S<k> & shape_functions, const ElementType type,                 \
          const GhostType & ghost_type, __attribute__((unused)) UInt id) {      \
       const Array<Real> * ret = NULL;                                          \
       AKANTU_BOOST_KIND_ELEMENT_SWITCH(GET_SHAPES_DERIVATIVES, kind);          \
       return *ret;                                                             \
     }                                                                          \
   };
 
     AKANTU_BOOST_ALL_KIND_LIST(AKANTU_SPECIALIZE_GET_SHAPES_DERIVATIVES_HELPER,
                                AKANTU_FE_ENGINE_LIST_GET_SHAPES_DERIVATIVES)
 
 #undef AKANTU_SPECIALIZE_GET_SHAPE_DERIVATIVES_HELPER
 #undef GET_SHAPES_DERIVATIVES
   } // namespace details
 } // namespace fe_engine
 
 template <template <ElementKind, class> class I, template <ElementKind> class S,
           ElementKind kind, class IntegrationOrderFunctor>
 inline const Array<Real> &
 FEEngineTemplate<I, S, kind, IntegrationOrderFunctor>::getShapesDerivatives(
     const ElementType & type, const GhostType & ghost_type,
     __attribute__((unused)) UInt id) const {
   return fe_engine::details::GetShapesDerivativesHelper<kind>::call(
       shape_functions, type, ghost_type, id);
 }
 
 /* -------------------------------------------------------------------------- */
 /**
  * Helper class to be able to write a partial specialization on the element kind
  */
 namespace fe_engine {
   namespace details {
     template <ElementKind kind> struct GetIntegrationPointsHelper {};
 
 #define GET_INTEGRATION_POINTS(type)                                           \
   ret = &(integrator.template getIntegrationPoints<type>(ghost_type));
 
 #define AKANTU_SPECIALIZE_GET_INTEGRATION_POINTS_HELPER(kind)                  \
   template <> struct GetIntegrationPointsHelper<kind> {                        \
     template <template <ElementKind, class> class I, ElementKind k, class IOF> \
     static const Matrix<Real> & call(const I<k, IOF> & integrator,             \
                                      const ElementType type,                   \
                                      const GhostType & ghost_type) {           \
       const Matrix<Real> * ret = NULL;                                         \
       AKANTU_BOOST_KIND_ELEMENT_SWITCH(GET_INTEGRATION_POINTS, kind);          \
       return *ret;                                                             \
     }                                                                          \
   };
 
     AKANTU_BOOST_ALL_KIND(AKANTU_SPECIALIZE_GET_INTEGRATION_POINTS_HELPER)
 
 #undef AKANTU_SPECIALIZE_GET_INTEGRATION_POINTS_HELPER
 #undef GET_INTEGRATION_POINTS
   } // namespace details
 } // namespace fe_engine
 
 template <template <ElementKind, class> class I, template <ElementKind> class S,
           ElementKind kind, class IntegrationOrderFunctor>
 inline const Matrix<Real> &
 FEEngineTemplate<I, S, kind, IntegrationOrderFunctor>::getIntegrationPoints(
     const ElementType & type, const GhostType & ghost_type) const {
   return fe_engine::details::GetIntegrationPointsHelper<kind>::call(
       integrator, type, ghost_type);
 }
 
 /* -------------------------------------------------------------------------- */
 template <template <ElementKind, class> class I, template <ElementKind> class S,
           ElementKind kind, class IntegrationOrderFunctor>
 void FEEngineTemplate<I, S, kind, IntegrationOrderFunctor>::printself(
     std::ostream & stream, int indent) const {
   std::string space;
   for (Int i = 0; i < indent; i++, space += AKANTU_INDENT)
     ;
 
   stream << space << "FEEngineTemplate [" << std::endl;
   stream << space << " + parent [" << std::endl;
   FEEngine::printself(stream, indent + 3);
   stream << space << "   ]" << std::endl;
   stream << space << " + shape functions [" << std::endl;
   shape_functions.printself(stream, indent + 3);
   stream << space << "   ]" << std::endl;
   stream << space << " + integrator [" << std::endl;
   integrator.printself(stream, indent + 3);
   stream << space << "   ]" << std::endl;
   stream << space << "]" << std::endl;
 }
 
 /* -------------------------------------------------------------------------- */
 template <template <ElementKind, class> class I, template <ElementKind> class S,
           ElementKind kind, class IntegrationOrderFunctor>
 void FEEngineTemplate<I, S, kind, IntegrationOrderFunctor>::onElementsAdded(
     const Array<Element> & new_elements, const NewElementsEvent &) {
   integrator.onElementsAdded(new_elements);
   shape_functions.onElementsAdded(new_elements);
 }
 
 /* -------------------------------------------------------------------------- */
 template <template <ElementKind, class> class I, template <ElementKind> class S,
           ElementKind kind, class IntegrationOrderFunctor>
 void FEEngineTemplate<I, S, kind, IntegrationOrderFunctor>::onElementsRemoved(
     const Array<Element> &, const ElementTypeMapArray<UInt> &,
     const RemovedElementsEvent &) {}
 
 /* -------------------------------------------------------------------------- */
 template <template <ElementKind, class> class I, template <ElementKind> class S,
           ElementKind kind, class IntegrationOrderFunctor>
 void FEEngineTemplate<I, S, kind, IntegrationOrderFunctor>::onElementsChanged(
     const Array<Element> &, const Array<Element> &,
     const ElementTypeMapArray<UInt> &, const ChangedElementsEvent &) {}
 
 /* -------------------------------------------------------------------------- */
 template <template <ElementKind, class> class I, template <ElementKind> class S,
           ElementKind kind, class IntegrationOrderFunctor>
 inline void FEEngineTemplate<I, S, kind, IntegrationOrderFunctor>::
     computeNormalsOnIntegrationPointsPoint1(
         const Array<Real> &, Array<Real> & normal,
         const GhostType & ghost_type) const {
   AKANTU_DEBUG_IN();
 
   AKANTU_DEBUG_ASSERT(mesh.getSpatialDimension() == 1,
                       "Mesh dimension must be 1 to compute normals on points!");
   const ElementType type = _point_1;
   UInt spatial_dimension = mesh.getSpatialDimension();
   // UInt nb_nodes_per_element  = Mesh::getNbNodesPerElement(type);
   UInt nb_points = getNbIntegrationPoints(type, ghost_type);
 
   UInt nb_element = mesh.getConnectivity(type, ghost_type).size();
   normal.resize(nb_element * nb_points);
   Array<Real>::matrix_iterator normals_on_quad =
       normal.begin_reinterpret(spatial_dimension, nb_points, nb_element);
   const Array<std::vector<Element>> & segments =
       mesh.getElementToSubelement(type, ghost_type);
   const Array<Real> & coords = mesh.getNodes();
 
   const Mesh * mesh_segment;
   if (mesh.isMeshFacets())
     mesh_segment = &(mesh.getMeshParent());
   else
     mesh_segment = &mesh;
 
   for (UInt elem = 0; elem < nb_element; ++elem) {
     UInt nb_segment = segments(elem).size();
 
     AKANTU_DEBUG_ASSERT(
         nb_segment > 0,
         "Impossible to compute a normal on a point connected to 0 segments");
 
     Real normal_value = 1;
     if (nb_segment == 1) {
       const Element & segment = segments(elem)[0];
       const Array<UInt> & segment_connectivity =
           mesh_segment->getConnectivity(segment.type, segment.ghost_type);
       // const Vector<UInt> & segment_points =
       // segment_connectivity.begin(Mesh::getNbNodesPerElement(segment.type))[segment.element];
       Real difference;
       if (segment_connectivity(0) == elem) {
         difference = coords(elem) - coords(segment_connectivity(1));
       } else {
         difference = coords(elem) - coords(segment_connectivity(0));
       }
       normal_value = difference / std::abs(difference);
     }
 
     for (UInt n(0); n < nb_points; ++n) {
       (*normals_on_quad)(0, n) = normal_value;
     }
     ++normals_on_quad;
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 } // namespace akantu
diff --git a/src/fe_engine/fe_engine_template_tmpl_field.hh b/src/fe_engine/fe_engine_template_tmpl_field.hh
index 205071102..1cc83c4ae 100644
--- a/src/fe_engine/fe_engine_template_tmpl_field.hh
+++ b/src/fe_engine/fe_engine_template_tmpl_field.hh
@@ -1,426 +1,428 @@
 /**
  * @file   fe_engine_template_tmpl_field.hh
  *
- * @author Nicolas Richart
+ * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
- * @date creation  Tue Jul 25 2017
+ * @date creation: Wed Aug 09 2017
+ * @date last modification: Thu Dec 07 2017
  *
- * @brief implementation of the assemble field s functions
+ * @brief  implementation of the assemble field s functions
  *
  * @section LICENSE
  *
- * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * 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
+ * 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
+ * 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 "fe_engine_template.hh"
 /* -------------------------------------------------------------------------- */
 
 #ifndef __AKANTU_FE_ENGINE_TEMPLATE_TMPL_FIELD_HH__
 #define __AKANTU_FE_ENGINE_TEMPLATE_TMPL_FIELD_HH__
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 /* Matrix lumping functions                                                   */
 /* -------------------------------------------------------------------------- */
 namespace fe_engine {
   namespace details {
     namespace {
       template <class Functor>
       void fillField(const Functor & field_funct, Array<Real> & field,
                      UInt nb_element, UInt nb_integration_points,
                      const ElementType & type, const GhostType & ghost_type) {
         UInt nb_degree_of_freedom = field.getNbComponent();
         field.resize(nb_integration_points * nb_element);
 
         auto field_it = field.begin_reinterpret(
             nb_degree_of_freedom, nb_integration_points, nb_element);
 
         Element el{type, 0, ghost_type};
         for (; el.element < nb_element; ++el.element, ++field_it) {
           field_funct(*field_it, el);
         }
       }
     } // namespace
   }   // namespace details
 } // namespace fe_engine
 
 /**
  * Helper class to be able to write a partial specialization on the element kind
  */
 namespace fe_engine {
   namespace details {
     template <ElementKind kind> struct AssembleLumpedTemplateHelper {};
 
 #define ASSEMBLE_LUMPED(type)                                                  \
   fem.template assembleFieldLumped<Functor, type>(field_funct, lumped, dof_id, \
                                                   dof_manager, ghost_type)
 
 #define AKANTU_SPECIALIZE_ASSEMBLE_HELPER(kind)                                \
   template <> struct AssembleLumpedTemplateHelper<kind> {                      \
     template <template <ElementKind, class> class I,                           \
               template <ElementKind> class S, ElementKind k, class IOF,        \
               class Functor>                                                   \
     static void call(const FEEngineTemplate<I, S, k, IOF> & fem,               \
                      const Functor & field_funct, const ID & lumped,           \
                      const ID & dof_id, DOFManager & dof_manager,              \
                      ElementType type, const GhostType & ghost_type) {         \
       AKANTU_BOOST_KIND_ELEMENT_SWITCH(ASSEMBLE_LUMPED, kind);                 \
     }                                                                          \
   };
 
     AKANTU_BOOST_ALL_KIND(AKANTU_SPECIALIZE_ASSEMBLE_HELPER)
 
 #undef AKANTU_SPECIALIZE_ASSEMBLE_HELPER
 #undef ASSEMBLE_LUMPED
   } // namespace details
 } // namespace fe_engine
 
 /* -------------------------------------------------------------------------- */
 template <template <ElementKind, class> class I, template <ElementKind> class S,
           ElementKind kind, class IOF>
 template <class Functor>
 void FEEngineTemplate<I, S, kind, IOF>::assembleFieldLumped(
     const Functor & field_funct, const ID & matrix_id, const ID & dof_id,
     DOFManager & dof_manager, ElementType type,
     const GhostType & ghost_type) const {
   AKANTU_DEBUG_IN();
 
   fe_engine::details::AssembleLumpedTemplateHelper<kind>::call(
       *this, field_funct, matrix_id, dof_id, dof_manager, type, ghost_type);
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 
 /* -------------------------------------------------------------------------- */
 template <template <ElementKind, class> class I, template <ElementKind> class S,
           ElementKind kind, class IntegrationOrderFunctor>
 template <class Functor, ElementType type>
 void FEEngineTemplate<I, S, kind, IntegrationOrderFunctor>::assembleFieldLumped(
     const Functor & field_funct, const ID & matrix_id, const ID & dof_id,
     DOFManager & dof_manager, const GhostType & ghost_type) const {
   AKANTU_DEBUG_IN();
 
   UInt nb_degree_of_freedom = dof_manager.getDOFs(dof_id).getNbComponent();
   UInt nb_element = mesh.getNbElement(type, ghost_type);
   UInt nb_integration_points = this->getNbIntegrationPoints(type);
 
   Array<Real> field(0, nb_degree_of_freedom);
   fe_engine::details::fillField(field_funct, field, nb_element,
                                 nb_integration_points, type, ghost_type);
 
   switch (type) {
   case _triangle_6:
   case _quadrangle_8:
   case _tetrahedron_10:
   case _hexahedron_20:
   case _pentahedron_15:
     this->template assembleLumpedDiagonalScaling<type>(field, matrix_id, dof_id,
                                                        dof_manager, ghost_type);
     break;
   default:
     this->template assembleLumpedRowSum<type>(field, matrix_id, dof_id,
                                               dof_manager, ghost_type);
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 /**
  * @f$ \tilde{M}_{i} = \sum_j M_{ij} = \sum_j \int \rho \varphi_i \varphi_j dV =
  * \int \rho \varphi_i dV @f$
  */
 template <template <ElementKind, class> class I, template <ElementKind> class S,
           ElementKind kind, class IntegrationOrderFunctor>
 template <ElementType type>
 void FEEngineTemplate<I, S, kind, IntegrationOrderFunctor>::
     assembleLumpedRowSum(const Array<Real> & field, const ID & matrix_id,
                          const ID & dof_id, DOFManager & dof_manager,
                          const GhostType & ghost_type) const {
   AKANTU_DEBUG_IN();
 
   UInt shapes_size = ElementClass<type>::getShapeSize();
   UInt nb_degree_of_freedom = field.getNbComponent();
 
   Array<Real> * field_times_shapes =
       new Array<Real>(0, shapes_size * nb_degree_of_freedom);
 
   shape_functions.template fieldTimesShapes<type>(field, *field_times_shapes,
                                                   ghost_type);
 
   UInt nb_element = mesh.getNbElement(type, ghost_type);
   Array<Real> * int_field_times_shapes = new Array<Real>(
       nb_element, shapes_size * nb_degree_of_freedom, "inte_rho_x_shapes");
 
   integrator.template integrate<type>(
       *field_times_shapes, *int_field_times_shapes,
       nb_degree_of_freedom * shapes_size, ghost_type, empty_filter);
 
   delete field_times_shapes;
 
   dof_manager.assembleElementalArrayToLumpedMatrix(
       dof_id, *int_field_times_shapes, matrix_id, type, ghost_type);
 
   delete int_field_times_shapes;
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 /**
  * @f$ \tilde{M}_{i} = c * M_{ii} = \int_{V_e} \rho dV @f$
  */
 template <template <ElementKind, class> class I, template <ElementKind> class S,
           ElementKind kind, class IntegrationOrderFunctor>
 template <ElementType type>
 void FEEngineTemplate<I, S, kind, IntegrationOrderFunctor>::
     assembleLumpedDiagonalScaling(const Array<Real> & field,
                                   const ID & matrix_id, const ID & dof_id,
                                   DOFManager & dof_manager,
                                   const GhostType & ghost_type) const {
   AKANTU_DEBUG_IN();
 
   const ElementType & type_p1 = ElementClass<type>::getP1ElementType();
   UInt nb_nodes_per_element_p1 = Mesh::getNbNodesPerElement(type_p1);
   UInt nb_nodes_per_element = Mesh::getNbNodesPerElement(type);
   UInt nb_degree_of_freedom = field.getNbComponent();
   UInt nb_element = mesh.getNbElement(type, ghost_type);
 
   Vector<Real> nodal_factor(nb_nodes_per_element);
 
 #define ASSIGN_WEIGHT_TO_NODES(corner, mid)                                    \
   {                                                                            \
     for (UInt n = 0; n < nb_nodes_per_element_p1; n++)                         \
       nodal_factor(n) = corner;                                                \
     for (UInt n = nb_nodes_per_element_p1; n < nb_nodes_per_element; n++)      \
       nodal_factor(n) = mid;                                                   \
   }
 
   if (type == _triangle_6)
     ASSIGN_WEIGHT_TO_NODES(1. / 12., 1. / 4.);
   if (type == _tetrahedron_10)
     ASSIGN_WEIGHT_TO_NODES(1. / 32., 7. / 48.);
   if (type == _quadrangle_8)
     ASSIGN_WEIGHT_TO_NODES(
         3. / 76.,
         16. / 76.); /** coeff. derived by scaling
                      * the diagonal terms of the corresponding
                      * consistent mass computed with 3x3 gauss points;
                      * coeff. are (1./36., 8./36.) for 2x2 gauss points */
   if (type == _hexahedron_20)
     ASSIGN_WEIGHT_TO_NODES(
         7. / 248.,
         16. / 248.); /** coeff. derived by scaling
                       * the diagonal terms of the corresponding
                       * consistent mass computed with 3x3x3 gauss points;
                       * coeff. are (1./40.,
                       * 1./15.) for 2x2x2 gauss points */
   if (type == _pentahedron_15) {
     // coefficients derived by scaling the diagonal terms of the corresponding
     // consistent mass computed with 8 gauss points;
     for (UInt n = 0; n < nb_nodes_per_element_p1; n++)
       nodal_factor(n) = 51. / 2358.;
 
     Real mid_triangle = 192. / 2358.;
     Real mid_quadrangle = 300. / 2358.;
 
     nodal_factor(6) = mid_triangle;
     nodal_factor(7) = mid_triangle;
     nodal_factor(8) = mid_triangle;
     nodal_factor(9) = mid_quadrangle;
     nodal_factor(10) = mid_quadrangle;
     nodal_factor(11) = mid_quadrangle;
     nodal_factor(12) = mid_triangle;
     nodal_factor(13) = mid_triangle;
     nodal_factor(14) = mid_triangle;
   }
 
   if (nb_element == 0) {
     AKANTU_DEBUG_OUT();
     return;
   }
 
 #undef ASSIGN_WEIGHT_TO_NODES
   /// compute @f$ \int \rho dV = \rho V @f$ for each element
   auto int_field = std::make_unique<Array<Real>>(
       field.size(), nb_degree_of_freedom, "inte_rho_x");
   integrator.template integrate<type>(field, *int_field, nb_degree_of_freedom,
                                       ghost_type, empty_filter);
 
   /// distribute the mass of the element to the nodes
   auto lumped_per_node = std::make_unique<Array<Real>>(
       nb_element, nb_degree_of_freedom * nb_nodes_per_element, "mass_per_node");
   auto int_field_it = int_field->begin(nb_degree_of_freedom);
   auto lumped_per_node_it =
       lumped_per_node->begin(nb_degree_of_freedom, nb_nodes_per_element);
 
   for (UInt e = 0; e < nb_element; ++e) {
     for (UInt n = 0; n < nb_nodes_per_element; ++n) {
       Vector<Real> l = (*lumped_per_node_it)(n);
       l = *int_field_it;
       l *= nodal_factor(n);
     }
     ++int_field_it;
     ++lumped_per_node_it;
   }
 
   dof_manager.assembleElementalArrayToLumpedMatrix(dof_id, *lumped_per_node,
                                                    matrix_id, type, ghost_type);
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 /**
  * Helper class to be able to write a partial specialization on the element kind
  */
 namespace fe_engine {
   namespace details {
     template <ElementKind kind> struct AssembleFieldMatrixHelper {};
 
 #define ASSEMBLE_MATRIX(type)                                                  \
   fem.template assembleFieldMatrix<Functor, type>(                             \
       field_funct, matrix_id, dof_id, dof_manager, ghost_type)
 
 #define AKANTU_SPECIALIZE_ASSEMBLE_FIELD_MATRIX_HELPER(kind)                   \
   template <> struct AssembleFieldMatrixHelper<kind> {                         \
     template <template <ElementKind, class> class I,                           \
               template <ElementKind> class S, ElementKind k, class IOF,        \
               class Functor>                                                   \
     static void call(const FEEngineTemplate<I, S, k, IOF> & fem,               \
                      const Functor & field_funct, const ID & matrix_id,        \
                      const ID & dof_id, DOFManager & dof_manager,              \
                      ElementType type, const GhostType & ghost_type) {         \
       AKANTU_BOOST_KIND_ELEMENT_SWITCH(ASSEMBLE_MATRIX, kind);                 \
     }                                                                          \
   };
 
     AKANTU_BOOST_ALL_KIND(AKANTU_SPECIALIZE_ASSEMBLE_FIELD_MATRIX_HELPER)
 
 #undef AKANTU_SPECIALIZE_ASSEMBLE_FIELD_MATRIX_HELPER
 #undef ASSEMBLE_MATRIX
   } // namespace details
 } // namespace fe_engine
 
 /* -------------------------------------------------------------------------- */
 template <template <ElementKind, class> class I, template <ElementKind> class S,
           ElementKind kind, class IOF>
 template <class Functor>
 void FEEngineTemplate<I, S, kind, IOF>::assembleFieldMatrix(
     const Functor & field_funct, const ID & matrix_id, const ID & dof_id,
     DOFManager & dof_manager, ElementType type,
     const GhostType & ghost_type) const {
   AKANTU_DEBUG_IN();
   fe_engine::details::AssembleFieldMatrixHelper<kind>::template call(
       *this, field_funct, matrix_id, dof_id, dof_manager, type, ghost_type);
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 /**
  * @f$ \tilde{M}_{i} = \sum_j M_{ij} = \sum_j \int \rho \varphi_i \varphi_j dV =
  * \int \rho \varphi_i dV @f$
  */
 template <template <ElementKind, class> class I, template <ElementKind> class S,
           ElementKind kind, class IntegrationOrderFunctor>
 template <class Functor, ElementType type>
 void FEEngineTemplate<I, S, kind, IntegrationOrderFunctor>::assembleFieldMatrix(
     const Functor & field_funct, const ID & matrix_id, const ID & dof_id,
     DOFManager & dof_manager, const GhostType & ghost_type) const {
   AKANTU_DEBUG_IN();
 
   UInt shapes_size = ElementClass<type>::getShapeSize();
   UInt nb_degree_of_freedom = dof_manager.getDOFs(dof_id).getNbComponent();
   UInt lmat_size = nb_degree_of_freedom * shapes_size;
   UInt nb_element = mesh.getNbElement(type, ghost_type);
 
   // \int N * N  so degree 2 * degree of N
   const UInt polynomial_degree =
       2 * ElementClassProperty<type>::polynomial_degree;
 
   // getting the integration points
   Matrix<Real> integration_points =
       integrator.template getIntegrationPoints<type, polynomial_degree>();
 
   UInt nb_integration_points = integration_points.cols();
   UInt vect_size = nb_integration_points * nb_element;
 
   // getting the shapes on the integration points
   Array<Real> shapes(0, shapes_size);
   shape_functions.template computeShapesOnIntegrationPoints<type>(
       mesh.getNodes(), integration_points, shapes, ghost_type);
 
   // Extending the shape functions
   /// \TODO move this in the shape functions as Voigt format shapes to have the
   /// code in common with the structural elements
   Array<Real> modified_shapes(vect_size, lmat_size * nb_degree_of_freedom, 0.);
   Array<Real> local_mat(vect_size, lmat_size * lmat_size);
   auto mshapes_it = modified_shapes.begin(nb_degree_of_freedom, lmat_size);
   auto shapes_it = shapes.begin(shapes_size);
 
   for (UInt q = 0; q < vect_size; ++q, ++mshapes_it, ++shapes_it) {
     for (UInt d = 0; d < nb_degree_of_freedom; ++d) {
       for (UInt s = 0; s < shapes_size; ++s) {
         (*mshapes_it)(d, s * nb_degree_of_freedom + d) = (*shapes_it)(s);
       }
     }
   }
 
   // getting the value to assemble on the integration points
   Array<Real> field(vect_size, nb_degree_of_freedom);
   fe_engine::details::fillField(field_funct, field, nb_element,
                                 nb_integration_points, type, ghost_type);
 
   // computing \rho * N
   mshapes_it = modified_shapes.begin(nb_degree_of_freedom, lmat_size);
   auto lmat = local_mat.begin(lmat_size, lmat_size);
   auto field_it = field.begin_reinterpret(nb_degree_of_freedom, field.size());
 
   for (UInt q = 0; q < vect_size; ++q, ++lmat, ++mshapes_it, ++field_it) {
     const auto & rho = *field_it;
     const auto & N = *mshapes_it;
     auto & mat = *lmat;
 
     Matrix<Real> Nt = N.transpose();
     for (UInt d = 0; d < Nt.cols(); ++d) {
       Nt(d) *= rho(d);
     }
 
     mat.template mul<false, false>(Nt, N);
   }
 
   // integrate the elemental values
   Array<Real> int_field_times_shapes(nb_element, lmat_size * lmat_size,
                                      "inte_rho_x_shapes");
   this->integrator.template integrate<type, polynomial_degree>(
       local_mat, int_field_times_shapes, lmat_size * lmat_size, ghost_type);
 
   // assemble the elemental values to the matrix
   dof_manager.assembleElementalMatricesToMatrix(
       matrix_id, dof_id, int_field_times_shapes, type, ghost_type);
 
   AKANTU_DEBUG_OUT();
 }
 
 } // namespace akantu
 
 #endif /* __AKANTU_FE_ENGINE_TEMPLATE_TMPL_FIELD_HH__ */
diff --git a/src/fe_engine/fe_engine_template_tmpl_struct.hh b/src/fe_engine/fe_engine_template_tmpl_struct.hh
index 410af8f66..e6318d1e5 100644
--- a/src/fe_engine/fe_engine_template_tmpl_struct.hh
+++ b/src/fe_engine/fe_engine_template_tmpl_struct.hh
@@ -1,99 +1,99 @@
 /**
  * @file   fe_engine_template_tmpl_struct.hh
  *
  * @author Fabian Barras <fabian.barras@epfl.ch>
  * @author Sébastien Hartmann <sebastien.hartmann@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Mon Jul 07 2014
- * @date last modification: Thu Oct 15 2015
+ * @date last modification: Tue Feb 20 2018
  *
  * @brief  Template implementation of FEEngineTemplate for Structural Element
  * Kinds
  *
  * @section LICENSE
  *
- * Copyright  (©)  2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de Lausanne)
+ * 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
+ * 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
+ * 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 "shape_structural.hh"
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 template <ElementKind kind, typename = void>
 struct AssembleFieldMatrixStructHelper {};
 
 template <ElementKind kind>
 struct AssembleFieldMatrixStructHelper<
     kind, typename std::enable_if<kind == _ek_structural>::type> {
   template <template <ElementKind, class> class I,
             template <ElementKind> class S, ElementKind k, class IOF>
   static void call(const FEEngineTemplate<I, S, k, IOF> & fem,
                    const Array<Real> & field_1, UInt nb_degree_of_freedom,
                    SparseMatrix & M, Array<Real> * n,
                    ElementTypeMapArray<Real> & rotation_mat,
                    const ElementType & type, const GhostType & ghost_type) {
 #define ASSEMBLE_MATRIX(type)                                                  \
   fem.template assembleFieldMatrix<type>(field_1, nb_degree_of_freedom, M, n,  \
                                          rotation_mat, ghost_type)
 
     AKANTU_BOOST_KIND_ELEMENT_SWITCH(ASSEMBLE_MATRIX, _ek_structural);
 #undef ASSEMBLE_MATRIX
   }
 };
 
 template <template <ElementKind, class> class I, template <ElementKind> class S,
           ElementKind kind, class IntegrationOrderFunctor>
 inline void
 FEEngineTemplate<I, S, kind, IntegrationOrderFunctor>::assembleFieldMatrix(
     const Array<Real> & field_1, UInt nb_degree_of_freedom, SparseMatrix & M,
     Array<Real> * n, ElementTypeMapArray<Real> & rotation_mat,
     const ElementType & type, const GhostType & ghost_type) const {
   AKANTU_DEBUG_IN();
 
   AssembleFieldMatrixStructHelper<kind>::template call(
       *this, field_1, nb_degree_of_freedom, M, n, rotation_mat, type,
       ghost_type);
 
   AKANTU_DEBUG_OUT();
 }
 /* -------------------------------------------------------------------------- */
 template <template <ElementKind, class> class I, template <ElementKind> class S,
           ElementKind kind, class IntegrationOrderFunctor>
 inline void
 FEEngineTemplate<I, S, kind, IntegrationOrderFunctor>::computeShapesMatrix(
     const ElementType &, UInt, UInt, Array<Real> *, UInt, UInt, UInt,
     const bool, const GhostType &) const {
 
   AKANTU_TO_IMPLEMENT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <template <ElementKind, class> class I, template <ElementKind> class S,
           ElementKind kind, class IntegrationOrderFunctor>
 template <ElementType type>
 inline void
 FEEngineTemplate<I, S, kind, IntegrationOrderFunctor>::assembleFieldMatrix(
     const Array<Real> &, UInt, SparseMatrix &, Array<Real> *,
     ElementTypeMapArray<Real> &, const GhostType &) const {
   AKANTU_TO_IMPLEMENT();
 }
 
 } // akantu
diff --git a/src/fe_engine/gauss_integration.cc b/src/fe_engine/gauss_integration.cc
index d4f4d8caf..ec718269d 100644
--- a/src/fe_engine/gauss_integration.cc
+++ b/src/fe_engine/gauss_integration.cc
@@ -1,238 +1,238 @@
 /**
- * @file   integration_element.cc
+ * @file   gauss_integration.cc
  *
  * @author Mauro Corrado <mauro.corrado@epfl.ch>
  * @author Sébastien Hartmann <sebastien.hartmann@epfl.ch>
  * @author Thomas Menouillard <tmenouillard@stucky.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Thu Feb 21 2013
- * @date last modification: Thu Nov 05 2015
+ * @date last modification: Mon Jun 19 2017
  *
- * @brief Definition of the integration constants, some of the value are taken
+ * @brief  Definition of the integration constants, some of the value are taken
  * from r3.01.01 doc from Code Aster
  *
  * @section LICENSE
  *
- * Copyright  (©)  2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de Lausanne)
+ * 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
+ * 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
+ * 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 "element_class.hh"
 
 using std::sqrt;
 
 namespace akantu {
 
 /* clang-format off */
 /* -------------------------------------------------------------------------- */
 /* Points                                                                     */
 /* -------------------------------------------------------------------------- */
 template<> Real GaussIntegrationTypeData<_git_point, 1>::quad_positions[]     = {0};
 template<> Real GaussIntegrationTypeData<_git_point, 1>::quad_weights[]       = {1.};
 
 /* -------------------------------------------------------------------------- */
 /* Segments                                                                   */
 /* -------------------------------------------------------------------------- */
 template<> Real GaussIntegrationTypeData<_git_segment, 1>::quad_positions[]     = {0.};
 template<> Real GaussIntegrationTypeData<_git_segment, 1>::quad_weights[]       = {2.};
 /* -------------------------------------------------------------------------- */
 template<> Real GaussIntegrationTypeData<_git_segment, 2>::quad_positions[]     = {-1./sqrt(3.), 1./sqrt(3.)};
 template<> Real GaussIntegrationTypeData<_git_segment, 2>::quad_weights[]       = {1., 1.};
 /* -------------------------------------------------------------------------- */
 template<> Real GaussIntegrationTypeData<_git_segment, 3>::quad_positions[]     = {-sqrt(3./5.), 0., sqrt(3./5.)};
 template<> Real GaussIntegrationTypeData<_git_segment, 3>::quad_weights[]       = {5./9., 8./9., 5./9.};
 /* -------------------------------------------------------------------------- */
 template<> Real GaussIntegrationTypeData<_git_segment, 4>::quad_positions[]     = {-sqrt((3. + 2.*sqrt(6./5.))/7.),
                                                                                    -sqrt((3. - 2.*sqrt(6./5.))/7.),
                                                                                    sqrt((3. - 2.*sqrt(6./5.))/7.),
                                                                                    sqrt((3. + 2.*sqrt(6./5.))/7.)};
 template<> Real GaussIntegrationTypeData<_git_segment, 4>::quad_weights[]       = {(18. - sqrt(30.))/36.,
                                                                                    (18. + sqrt(30.))/36.,
                                                                                    (18. + sqrt(30.))/36.,
                                                                                    (18. - sqrt(30.))/36.};
 /* -------------------------------------------------------------------------- */
 /* Triangles                                                                  */
 /* -------------------------------------------------------------------------- */
 template<> Real GaussIntegrationTypeData<_git_triangle, 1>::quad_positions[]     = {1./3., 1./3.};
 template<> Real GaussIntegrationTypeData<_git_triangle, 1>::quad_weights[]       = {1./2.};
 /* -------------------------------------------------------------------------- */
 template<> Real GaussIntegrationTypeData<_git_triangle, 3>::quad_positions[]     = {1./6., 1./6.,
                                                                                     2./3., 1./6.,
                                                                                     1./6., 2./3.};
 template<> Real GaussIntegrationTypeData<_git_triangle, 3>::quad_weights[]       = {1./6., 1./6., 1./6.};
 /* -------------------------------------------------------------------------- */
 template<> Real GaussIntegrationTypeData<_git_triangle, 4>::quad_positions[]     = {1./5., 1./5.,
                                                                                     3./5., 1./5.,
                                                                                     1./5., 3./5.,
                                                                                     1./3., 1./3.};
 template<> Real GaussIntegrationTypeData<_git_triangle, 4>::quad_weights[]       = {25./(24.*4.), 25./(24.*4.), 25./(24.*4.), -27/(24.*4.)};
 /* -------------------------------------------------------------------------- */
 /// Found those one in the TrigGaussRuleInfo from mathematica and matched them to the code aster values
 /// http://www.colorado.edu/engineering/CAS/courses.d/AFEM.d/AFEM.AppI.d/AFEM.AppI.pdf
 static const Real tri_6_a = (8. - std::sqrt(10.) + std::sqrt(38.-44.*std::sqrt(2./5.)))/18.;
 static const Real tri_6_b = (8. - std::sqrt(10.) - std::sqrt(38.-44.*std::sqrt(2./5.)))/18.;
 static const Real tri_6_w1 = (620. - std::sqrt(213125. - 53320.*std::sqrt(10.)))/7440.;
 static const Real tri_6_w2 = (620. + std::sqrt(213125. - 53320.*std::sqrt(10.)))/7440.;
 template<> Real GaussIntegrationTypeData<_git_triangle, 6>::quad_positions[]     = {tri_6_b, tri_6_b,
                                                                                     1. - 2. * tri_6_b, tri_6_b,
                                                                                     tri_6_b, 1. - 2. * tri_6_b,
                                                                                     tri_6_a, 1. - 2. * tri_6_a,
                                                                                     tri_6_a, tri_6_a,
                                                                                     1. - 2. * tri_6_a, tri_6_a};
 template<> Real GaussIntegrationTypeData<_git_triangle, 6>::quad_weights[]       = {tri_6_w1, tri_6_w1, tri_6_w1,
                                                                                     tri_6_w2, tri_6_w2, tri_6_w2};
 /* -------------------------------------------------------------------------- */
 static const Real tri_7_a  = (6. + std::sqrt(15.)) / 21.;
 static const Real tri_7_b  = (6. - std::sqrt(15.)) / 21.;
 static const Real tri_7_w1 = (155. + std::sqrt(15.))/2400.;
 static const Real tri_7_w2 = (155. - std::sqrt(15.))/2400.;
 template<> Real GaussIntegrationTypeData<_git_triangle, 7>::quad_positions[]     = {          1./3.,           1./3.,
                                                                                             tri_7_a,         tri_7_a,
                                                                                     1. - 2.*tri_7_a,         tri_7_a,
                                                                                             tri_7_a, 1. - 2.*tri_7_a,
                                                                                             tri_7_b,         tri_7_b,
                                                                                     1. - 2.*tri_7_b,         tri_7_b,
                                                                                             tri_7_b, 1. - 2.*tri_7_b};
 template<> Real GaussIntegrationTypeData<_git_triangle, 7>::quad_weights[]       = {9./80.,
                                                                                     tri_7_w1, tri_7_w1, tri_7_w1,
                                                                                     tri_7_w2, tri_7_w2, tri_7_w2};
 
 /* -------------------------------------------------------------------------- */
 
 
 /* -------------------------------------------------------------------------- */
 /* Tetrahedrons                                                               */
 /* -------------------------------------------------------------------------- */
 template<> Real GaussIntegrationTypeData<_git_tetrahedron, 1>::quad_positions[]     = {1./4., 1./4., 1./4.};
 template<> Real GaussIntegrationTypeData<_git_tetrahedron, 1>::quad_weights[]       = {1./6.};
 /* -------------------------------------------------------------------------- */
 static const Real tet_4_a = (5. -    std::sqrt(5.))/20.;
 static const Real tet_4_b = (5. + 3.*std::sqrt(5.))/20.;
 template<> Real GaussIntegrationTypeData<_git_tetrahedron, 4>::quad_positions[]     = {tet_4_a, tet_4_a, tet_4_a,
                                                                                        tet_4_b, tet_4_a, tet_4_a,
                                                                                        tet_4_a, tet_4_b, tet_4_a,
                                                                                        tet_4_a, tet_4_a, tet_4_b};
 template<> Real GaussIntegrationTypeData<_git_tetrahedron, 4>::quad_weights[]       = {1./24., 1./24., 1./24., 1./24.};
 /* -------------------------------------------------------------------------- */
 template<> Real GaussIntegrationTypeData<_git_tetrahedron, 5>::quad_positions[]     = {1./4., 1./4., 1./4.,
                                                                                        1./6., 1./6., 1./6.,
                                                                                        1./6., 1./6., 1./2.,
                                                                                        1./6., 1./2., 1./6.,
                                                                                        1./2., 1./6., 1./6.,};
 template<> Real GaussIntegrationTypeData<_git_tetrahedron, 5>::quad_weights[]       = {-2./15., 3./40.,
                                                                                        3./40., 3./40.,
                                                                                        3./40.};
 /* -------------------------------------------------------------------------- */
 static const Real tet_15_a = (7. + std::sqrt(15.))/34.;
 static const Real tet_15_b = (13. - 3. * std::sqrt(15.))/34.;
 static const Real tet_15_c = (7. - std::sqrt(15.))/34.;
 static const Real tet_15_d = (13. + 3. * std::sqrt(15.))/34.;
 static const Real tet_15_e = (5. - std::sqrt(15.))/20.;
 static const Real tet_15_f = (5. + std::sqrt(15.))/20.;
 static const Real tet_15_w1 = (2665. - 14. * std::sqrt(15.))/226800.;
 static const Real tet_15_w2 = (2665. + 14. * std::sqrt(15.))/226800.;
 static const Real tet_15_w3 = 5./567.;
 template<> Real GaussIntegrationTypeData<_git_tetrahedron, 15>::quad_positions[]    = {1./4., 1./4., 1./4.,
                                                                                        tet_15_a, tet_15_a, tet_15_a,
                                                                                        tet_15_a, tet_15_a, tet_15_b,
                                                                                        tet_15_a, tet_15_b, tet_15_a,
                                                                                        tet_15_b, tet_15_a, tet_15_a,
 
                                                                                        tet_15_c, tet_15_c, tet_15_c,
                                                                                        tet_15_c, tet_15_c, tet_15_d,
                                                                                        tet_15_c, tet_15_d, tet_15_c,
                                                                                        tet_15_d, tet_15_c, tet_15_c,
 
                                                                                        tet_15_e, tet_15_e, tet_15_f,
                                                                                        tet_15_e, tet_15_f, tet_15_e,
                                                                                        tet_15_f, tet_15_e, tet_15_e,
 
                                                                                        tet_15_e, tet_15_f, tet_15_f,
                                                                                        tet_15_f, tet_15_e, tet_15_f,
                                                                                        tet_15_f, tet_15_f, tet_15_e};
 template<> Real GaussIntegrationTypeData<_git_tetrahedron, 15>::quad_weights[]      = {8./405.,
                                                                                        tet_15_w1, tet_15_w1, tet_15_w1, tet_15_w1,
                                                                                        tet_15_w2, tet_15_w2, tet_15_w2, tet_15_w2,
                                                                                        tet_15_w3, tet_15_w3, tet_15_w3, tet_15_w3, tet_15_w3, tet_15_w3};
 
 /* -------------------------------------------------------------------------- */
 /* Pentahedrons                                                               */
 /* -------------------------------------------------------------------------- */
 template<> Real GaussIntegrationTypeData<_git_pentahedron, 6>::quad_positions[]     = {-1./sqrt(3.), 0.5, 0.5,
                                                                                        -1./sqrt(3.), 0. , 0.5,
                                                                                        -1./sqrt(3.), 0.5, 0.,
                                                                                         1./sqrt(3.), 0.5, 0.5,
                                                                                         1./sqrt(3.), 0. , 0.5,
                                                                                         1./sqrt(3.), 0.5 ,0.};
 template<> Real GaussIntegrationTypeData<_git_pentahedron, 6>::quad_weights[]       = {1./6., 1./6., 1./6.,
                                                                                        1./6., 1./6., 1./6.};
 /* -------------------------------------------------------------------------- */
 template<> Real GaussIntegrationTypeData<_git_pentahedron, 8>::quad_positions[]     = {-sqrt(3.)/3., 1./3., 1./3.,
                                                                                        -sqrt(3.)/3.,   0.6,   0.2,
                                                                                        -sqrt(3.)/3.,   0.2,   0.6,
                                                                                        -sqrt(3.)/3.,   0.2,   0.2,
                                                                                         sqrt(3.)/3., 1./3., 1./3.,
                                                                                         sqrt(3.)/3.,   0.6,   0.2,
                                                                                         sqrt(3.)/3.,   0.2,   0.6,
                                                                                         sqrt(3.)/3.,   0.2,   0.2};
 template<> Real GaussIntegrationTypeData<_git_pentahedron, 8>::quad_weights[]       = {-27./96., 25./96., 25./96., 25./96.,
                                                                                        -27./96., 25./96., 25./96., 25./96.};
 /* -------------------------------------------------------------------------- */
 static const Real pent_21_x = std::sqrt(3./5.);
 static const Real pent_21_a = (6. + std::sqrt(15.)) / 21.;
 static const Real pent_21_b = (6. - std::sqrt(15.)) / 21.;
 
 static const Real pent_21_w1_1 = 5./9.;
 static const Real pent_21_w2_1 = 8./9.;
 static const Real pent_21_w1_2 = (155. + std::sqrt(15.))/2400.;
 static const Real pent_21_w2_2 = (155. - std::sqrt(15.))/2400.;
 template<> Real GaussIntegrationTypeData<_git_pentahedron, 21>::quad_positions[]    = {- pent_21_x,             1./3.,             1./3.,
                                                                                        - pent_21_x,         pent_21_a,         pent_21_a,
                                                                                        - pent_21_x, 1. - 2.*pent_21_a,         pent_21_a,
                                                                                        - pent_21_x,         pent_21_a, 1. - 2.*pent_21_a,
                                                                                        - pent_21_x,         pent_21_b,         pent_21_b,
                                                                                        - pent_21_x, 1. - 2.*pent_21_b,         pent_21_b,
                                                                                        - pent_21_x,         pent_21_b, 1. - 2.*pent_21_b,
                                                                                                 0.,             1./3.,             1./3.,
                                                                                                 0.,         pent_21_a,         pent_21_a,
                                                                                                 0., 1. - 2.*pent_21_a,         pent_21_a,
                                                                                                 0.,         pent_21_a, 1. - 2.*pent_21_a,
                                                                                                 0.,         pent_21_b,         pent_21_b,
                                                                                                 0., 1. - 2.*pent_21_b,         pent_21_b,
                                                                                                 0.,         pent_21_b, 1. - 2.*pent_21_b,
                                                                                          pent_21_x,             1./3.,             1./3.,
                                                                                          pent_21_x,         pent_21_a,         pent_21_a,
                                                                                          pent_21_x, 1. - 2.*pent_21_a,         pent_21_a,
                                                                                          pent_21_x,         pent_21_a, 1. - 2.*pent_21_a,
                                                                                          pent_21_x,         pent_21_b,         pent_21_b,
                                                                                          pent_21_x, 1. - 2.*pent_21_b,         pent_21_b,
                                                                                          pent_21_x,         pent_21_b, 1. - 2.*pent_21_b};
 template<> Real GaussIntegrationTypeData<_git_pentahedron, 21>::quad_weights[]      = {pent_21_w1_1 * 9. / 80.,
                                                                                        pent_21_w1_1*pent_21_w1_2, pent_21_w1_1*pent_21_w1_2, pent_21_w1_1*pent_21_w1_2,
                                                                                        pent_21_w1_1*pent_21_w2_2, pent_21_w1_1*pent_21_w2_2, pent_21_w1_1*pent_21_w2_2,
                                                                                        pent_21_w2_1 * 9. / 80.,
                                                                                        pent_21_w1_2*pent_21_w1_2, pent_21_w1_2*pent_21_w1_2, pent_21_w1_2*pent_21_w1_2,
                                                                                        pent_21_w1_2*pent_21_w2_2, pent_21_w1_2*pent_21_w2_2, pent_21_w1_2*pent_21_w2_2,
                                                                                        pent_21_w1_1 * 9. / 80.,
                                                                                        pent_21_w1_1*pent_21_w1_2, pent_21_w1_1*pent_21_w1_2, pent_21_w1_1*pent_21_w1_2,
                                                                                        pent_21_w1_1*pent_21_w2_2, pent_21_w1_1*pent_21_w2_2, pent_21_w1_1*pent_21_w2_2};
 
 
 } // akantu
diff --git a/src/fe_engine/gauss_integration_tmpl.hh b/src/fe_engine/gauss_integration_tmpl.hh
index 6ddb1e673..7e9a17e10 100644
--- a/src/fe_engine/gauss_integration_tmpl.hh
+++ b/src/fe_engine/gauss_integration_tmpl.hh
@@ -1,272 +1,273 @@
 /**
  * @file   gauss_integration_tmpl.hh
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
- * @date   Tue May 10 10:48:21 2016
+ * @date creation: Tue May 10 2016
+ * @date last modification: Wed Nov 29 2017
  *
  * @brief  implementation of the gauss integration helpers
  *
  * @section LICENSE
  *
- * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * 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
+ * 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
+ * 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_GAUSS_INTEGRATION_TMPL_HH__
 #define __AKANTU_GAUSS_INTEGRATION_TMPL_HH__
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 /* GaussIntegrationElement                                                    */
 /* -------------------------------------------------------------------------- */
 namespace _aka_gauss_helpers {
   template <GaussIntegrationType type, UInt n>
   struct GaussIntegrationNbPoints {};
 
   template <UInt n> struct GaussIntegrationNbPoints<_git_not_defined, n> {
     static const UInt nb_points = 0;
   };
 
   template <UInt n> struct GaussIntegrationNbPoints<_git_point, n> {
     static const UInt nb_points = 1;
   };
 
   template <UInt n> struct GaussIntegrationNbPoints<_git_segment, n> {
     static const UInt nb_points = (n + 1) / 2 + ((n + 1) % 2 ? 1 : 0);
   };
 
 #define DECLARE_GAUSS_NB_POINTS(type, order, points)                           \
   template <> struct GaussIntegrationNbPoints<type, order> {                   \
     static const UInt nb_points = points;                                      \
   }
 
 #define DECLARE_GAUSS_NB_POINTS_PENT(type, order, xo, yo)                      \
   template <> struct GaussIntegrationNbPoints<type, order> {                   \
     static const UInt x_order = xo;                                            \
     static const UInt yz_order = yo;                                           \
     static const UInt nb_points = 1;                                           \
   }
 
   DECLARE_GAUSS_NB_POINTS(_git_triangle, 1, 1);
   DECLARE_GAUSS_NB_POINTS(_git_triangle, 2, 3);
   DECLARE_GAUSS_NB_POINTS(_git_triangle, 3, 4);
   DECLARE_GAUSS_NB_POINTS(_git_triangle, 4, 6);
   DECLARE_GAUSS_NB_POINTS(_git_triangle, 5, 7);
   DECLARE_GAUSS_NB_POINTS(_git_tetrahedron, 1, 1);
   DECLARE_GAUSS_NB_POINTS(_git_tetrahedron, 2, 4);
   DECLARE_GAUSS_NB_POINTS(_git_tetrahedron, 3, 5);
   DECLARE_GAUSS_NB_POINTS(_git_tetrahedron, 4, 15);
   DECLARE_GAUSS_NB_POINTS(_git_tetrahedron, 5, 15);
   DECLARE_GAUSS_NB_POINTS_PENT(_git_pentahedron, 1, 3,
                                2); // order 3 in x, order 2 in y and z
   DECLARE_GAUSS_NB_POINTS_PENT(_git_pentahedron, 2, 3,
                                2); // order 3 in x, order 2 in y and z
   DECLARE_GAUSS_NB_POINTS_PENT(_git_pentahedron, 3, 3,
                                3); // order 3 in x, order 3 in y and z
   DECLARE_GAUSS_NB_POINTS_PENT(_git_pentahedron, 4, 5,
                                5); // order 5 in x, order 5 in y and z
   DECLARE_GAUSS_NB_POINTS_PENT(_git_pentahedron, 5, 5,
                                5); // order 5 in x, order 5 in y and z
 
   template <GaussIntegrationType type, UInt n, UInt on = n,
             bool end_recurse = false>
   struct GaussIntegrationNbPointsHelper {
     static const UInt pnp = GaussIntegrationNbPoints<type, n>::nb_points;
     static const UInt order = n;
     static const UInt nb_points = pnp;
   };
 
   template <GaussIntegrationType type, UInt n, UInt on>
   struct GaussIntegrationNbPointsHelper<type, n, on, true> {
     static const UInt nb_points = 0;
   };
 
   /* ------------------------------------------------------------------------ */
   /* Generic helper                                                           */
   /* ------------------------------------------------------------------------ */
   template <GaussIntegrationType type, UInt dimension, UInt n>
   struct GaussIntegrationTypeDataHelper {
     using git_np = GaussIntegrationNbPoints<type, n>;
     using git_data = GaussIntegrationTypeData<type, git_np::nb_points>;
 
     static UInt getNbQuadraturePoints() { return git_np::nb_points; }
 
     static const Matrix<Real> getQuadraturePoints() {
       return Matrix<Real>(git_data::quad_positions, dimension,
                           git_np::nb_points);
     }
 
     static const Vector<Real> getWeights() {
       return Vector<Real>(git_data::quad_weights, git_np::nb_points);
     }
   };
 
   /* ------------------------------------------------------------------------ */
   /* helper for _segment _quadrangle _hexahedron                              */
   /* ------------------------------------------------------------------------ */
   template <UInt dimension, UInt dp>
   struct GaussIntegrationTypeDataHelper<_git_segment, dimension, dp> {
     using git_np = GaussIntegrationNbPoints<_git_segment, dp>;
     using git_data = GaussIntegrationTypeData<_git_segment, git_np::nb_points>;
 
     static UInt getNbQuadraturePoints() {
       return Math::pow<dimension>(git_np::nb_points);
     }
 
     static const Matrix<Real> getQuadraturePoints() {
       UInt tot_nquad = getNbQuadraturePoints();
       UInt nquad = git_np::nb_points;
 
       Matrix<Real> quads(dimension, tot_nquad);
       Vector<Real> pos(git_data::quad_positions, nquad);
 
       UInt offset = 1;
       for (UInt d = 0; d < dimension; ++d) {
         for (UInt n = 0, q = 0; n < tot_nquad; ++n, q += offset) {
           UInt rq = q % tot_nquad + q / tot_nquad;
           quads(d, rq) = pos(n % nquad);
         }
         offset *= nquad;
       }
       return quads;
     }
 
     static const Vector<Real> getWeights() {
       UInt tot_nquad = getNbQuadraturePoints();
       UInt nquad = git_np::nb_points;
 
       Vector<Real> quads_weights(tot_nquad, 1.);
       Vector<Real> weights(git_data::quad_weights, nquad);
 
       UInt offset = 1;
       for (UInt d = 0; d < dimension; ++d) {
         for (UInt n = 0, q = 0; n < tot_nquad; ++n, q += offset) {
           UInt rq = q % tot_nquad + q / tot_nquad;
           quads_weights(rq) *= weights(n % nquad);
         }
         offset *= nquad;
       }
       return quads_weights;
     }
   };
 
   /* ------------------------------------------------------------------------ */
   /* helper for _pentahedron                                                  */
   /* ------------------------------------------------------------------------ */
   template <UInt dimension, UInt dp>
   struct GaussIntegrationTypeDataHelper<_git_pentahedron, dimension, dp> {
     using git_info = GaussIntegrationNbPoints<_git_pentahedron, dp>;
     using git_np_seg =
         GaussIntegrationNbPoints<_git_segment, git_info::x_order>;
     using git_np_tri =
         GaussIntegrationNbPoints<_git_triangle, git_info::yz_order>;
     using git_data_seg =
         GaussIntegrationTypeData<_git_segment, git_np_seg::nb_points>;
     using git_data_tri =
         GaussIntegrationTypeData<_git_triangle, git_np_tri::nb_points>;
 
     static UInt getNbQuadraturePoints() {
       return git_np_seg::nb_points * git_np_tri::nb_points;
     }
 
     static const Matrix<Real> getQuadraturePoints() {
       UInt tot_nquad = getNbQuadraturePoints();
       UInt nquad_seg = git_np_seg::nb_points;
       UInt nquad_tri = git_np_tri::nb_points;
 
       Matrix<Real> quads(dimension, tot_nquad);
       Matrix<Real> pos_seg_w(git_data_seg::quad_positions, 1, nquad_seg);
       Matrix<Real> pos_tri_w(git_data_tri::quad_positions, 2, nquad_tri);
 
       for (UInt ns = 0, q = 0; ns < nquad_seg; ++ns) {
         Vector<Real> pos_seg = pos_seg_w(ns);
         for (UInt nt = 0; nt < nquad_tri; ++nt, ++q) {
           Vector<Real> pos_tri = pos_tri_w(nt);
           Vector<Real> quad = quads(q);
           quad(_x) = pos_seg(_x);
           quad(_y) = pos_tri(_x);
           quad(_z) = pos_tri(_y);
         }
       }
       return quads;
     }
 
     static const Vector<Real> getWeights() {
       UInt tot_nquad = getNbQuadraturePoints();
       UInt nquad_seg = git_np_seg::nb_points;
       UInt nquad_tri = git_np_tri::nb_points;
 
       Vector<Real> quads_weights(tot_nquad);
 
       Vector<Real> weight_seg(git_data_seg::quad_weights, nquad_seg);
       Vector<Real> weight_tri(git_data_tri::quad_weights, nquad_tri);
 
       for (UInt ns = 0, q = 0; ns < nquad_seg; ++ns) {
         for (UInt nt = 0; nt < nquad_tri; ++nt, ++q) {
           quads_weights(q) = weight_seg(ns) * weight_tri(nt);
         }
       }
       return quads_weights;
     }
   };
 }
 
 template <ElementType element_type, UInt n>
 const Matrix<Real>
 GaussIntegrationElement<element_type, n>::getQuadraturePoints() {
   const InterpolationType itp_type =
       ElementClassProperty<element_type>::interpolation_type;
   using interpolation_property = InterpolationProperty<itp_type>;
   using data_helper = _aka_gauss_helpers::GaussIntegrationTypeDataHelper<
       ElementClassProperty<element_type>::gauss_integration_type,
       interpolation_property::natural_space_dimension, n>;
   Matrix<Real> tmp(data_helper::getQuadraturePoints());
   return tmp;
 }
 
 /* -------------------------------------------------------------------------- */
 template <ElementType element_type, UInt n>
 const Vector<Real> GaussIntegrationElement<element_type, n>::getWeights() {
   const InterpolationType itp_type =
       ElementClassProperty<element_type>::interpolation_type;
   using interpolation_property = InterpolationProperty<itp_type>;
   using data_helper = _aka_gauss_helpers::GaussIntegrationTypeDataHelper<
       ElementClassProperty<element_type>::gauss_integration_type,
       interpolation_property::natural_space_dimension, n>;
   Vector<Real> tmp(data_helper::getWeights());
   return tmp;
 }
 
 /* -------------------------------------------------------------------------- */
 template <ElementType element_type, UInt n>
 UInt GaussIntegrationElement<element_type, n>::getNbQuadraturePoints() {
   const InterpolationType itp_type =
       ElementClassProperty<element_type>::interpolation_type;
   using interpolation_property = InterpolationProperty<itp_type>;
   using data_helper = _aka_gauss_helpers::GaussIntegrationTypeDataHelper<
       ElementClassProperty<element_type>::gauss_integration_type,
       interpolation_property::natural_space_dimension, n>;
   return data_helper::getNbQuadraturePoints();
 }
 
 } // akantu
 
 #endif /* __AKANTU_GAUSS_INTEGRATION_TMPL_HH__ */
diff --git a/src/fe_engine/geometrical_element_property.cc b/src/fe_engine/geometrical_element_property.cc
index c7086bbed..60e7f11f8 100644
--- a/src/fe_engine/geometrical_element_property.cc
+++ b/src/fe_engine/geometrical_element_property.cc
@@ -1,60 +1,62 @@
 /**
  * @file   geometrical_element_property.cc
  *
- * @author Nicolas Richart
+ * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
- * @date creation  Wed Nov 29 2017
+ * @date creation: Wed Nov 29 2017
+ * @date last modification: Thu Nov 30 2017
  *
- * @brief A Documented file.
+ * @brief  A Documented file.
  *
  * @section LICENSE
  *
- * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * 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
+ * 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
+ * A PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
+
 /* -------------------------------------------------------------------------- */
 #include "element_class.hh"
 /* -------------------------------------------------------------------------- */
 #include <boost/preprocessor.hpp>
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 
 #define AKANTU_INSTANTIATE_TYPES(r, data, type)                                \
   constexpr std::array<UInt, ElementClass<type>::getNbFacetTypes()>            \
       GeometricalElementProperty<                                              \
           ElementClassProperty<type>::geometrical_type>::nb_facets;            \
   constexpr std::array<UInt, ElementClass<type>::getNbFacetTypes()>            \
       GeometricalElementProperty<                                              \
           ElementClassProperty<type>::geometrical_type>::nb_nodes_per_facet;   \
   constexpr std::array<                                                        \
       UInt, detail::sizeFacetConnectivity<GeometricalElementProperty<          \
                 ElementClassProperty<type>::geometrical_type>>()>              \
       GeometricalElementProperty<ElementClassProperty<                         \
           type>::geometrical_type>::facet_connectivity_vect;                   \
   constexpr std::array<ElementType, ElementClass<type>::getNbFacetTypes()>     \
       ElementClassExtraGeometryProperties<type>::facet_type;
 
 BOOST_PP_SEQ_FOR_EACH(AKANTU_INSTANTIATE_TYPES, _,
                       (_not_defined)AKANTU_ek_regular_ELEMENT_TYPE)
 
 #if defined(AKANTU_COHESIVE_ELEMENT)
 BOOST_PP_SEQ_FOR_EACH(AKANTU_INSTANTIATE_TYPES, _,
                       AKANTU_ek_cohesive_ELEMENT_TYPE)
 #endif
 
 } // akantu
diff --git a/src/fe_engine/geometrical_element_property.hh b/src/fe_engine/geometrical_element_property.hh
index e6f42d94e..d3a70224b 100644
--- a/src/fe_engine/geometrical_element_property.hh
+++ b/src/fe_engine/geometrical_element_property.hh
@@ -1,489 +1,488 @@
 /**
- * @file   geometrical_element.cc
+ * @file   geometrical_element_property.hh
  *
  * @author Mauro Corrado <mauro.corrado@epfl.ch>
  * @author Thomas Menouillard <tmenouillard@stucky.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
- * @date creation: Thu Feb 21 2013
- * @date last modification: Thu Jan 21 2016
+ * @date creation: Wed Nov 29 2017
  *
  * @brief  Specialization of the geometrical types
  *
  * @section LICENSE
  *
- * Copyright  (©)  2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de Lausanne)
+ * 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
+ * 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
+ * A PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 #include "element_class.hh"
 /* -------------------------------------------------------------------------- */
 #include <array>
 /* -------------------------------------------------------------------------- */
 
 #ifndef __AKANTU_GEOMETRICAL_ELEMENT_PROPERTY_HH__
 #define __AKANTU_GEOMETRICAL_ELEMENT_PROPERTY_HH__
 
 namespace akantu {
 
 namespace detail {
   template <typename properties> constexpr size_t sizeFacetConnectivity() {
     size_t s = 0;
     for (size_t n = 0; n < properties::nb_facet_types; ++n) {
       s += properties::nb_facets[n] * properties::nb_nodes_per_facet[n];
     }
     return s == 0 ? 1 : s;
   }
 }
 
 template <> struct GeometricalElementProperty<_gt_not_defined> {
   static constexpr UInt spatial_dimension{0};
   static constexpr UInt nb_nodes_per_element{0};
   static constexpr UInt nb_facet_types{1};
   static constexpr std::array<UInt, nb_facet_types> nb_facets{{0}};
   static constexpr std::array<UInt, nb_facet_types> nb_nodes_per_facet{{0}};
   static constexpr std::array<UInt, 1> facet_connectivity_vect{{0}};
 };
 
 template <> struct GeometricalElementProperty<_gt_point> {
   static constexpr UInt spatial_dimension{0};
   static constexpr UInt nb_nodes_per_element{1};
   static constexpr UInt nb_facet_types{1};
   static constexpr std::array<UInt, nb_facet_types> nb_facets{{1}};
   static constexpr std::array<UInt, nb_facet_types> nb_nodes_per_facet{{1}};
   static constexpr std::array<UInt, 1> facet_connectivity_vect{{0}};
 };
 
 template <> struct GeometricalElementProperty<_gt_segment_2> {
   static constexpr UInt spatial_dimension{1};
   static constexpr UInt nb_nodes_per_element{2};
   static constexpr UInt nb_facet_types{1};
   static constexpr std::array<UInt, nb_facet_types> nb_facets{{2}};
   static constexpr std::array<UInt, nb_facet_types> nb_nodes_per_facet{{1}};
   static constexpr std::array<UInt, 2> facet_connectivity_vect{{0, 1}};
 };
 
 template <> struct GeometricalElementProperty<_gt_segment_3> {
   static constexpr UInt spatial_dimension{1};
   static constexpr UInt nb_nodes_per_element{3};
   static constexpr UInt nb_facet_types{1};
   static constexpr std::array<UInt, nb_facet_types> nb_facets{{2}};
   static constexpr std::array<UInt, nb_facet_types> nb_nodes_per_facet{{1}};
   // clang-format off
   static constexpr std::array<UInt, 2> facet_connectivity_vect{{0, 1}};
   // clang-format on
 };
 
 template <> struct GeometricalElementProperty<_gt_triangle_3> {
   static constexpr UInt spatial_dimension{2};
   static constexpr UInt nb_nodes_per_element{3};
   static constexpr UInt nb_facet_types{1};
   static constexpr std::array<UInt, nb_facet_types> nb_facets{{3}};
   static constexpr std::array<UInt, nb_facet_types> nb_nodes_per_facet{{2}};
   // clang-format off
     static constexpr std::array<UInt, 6> facet_connectivity_vect{{
         0, 1, 2,
         1, 2, 0}};
   // clang-format on
 };
 
 template <> struct GeometricalElementProperty<_gt_triangle_6> {
   static constexpr UInt spatial_dimension{2};
   static constexpr UInt nb_nodes_per_element{6};
   static constexpr UInt nb_facet_types{1};
   static constexpr std::array<UInt, nb_facet_types> nb_facets{{3}};
   static constexpr std::array<UInt, nb_facet_types> nb_nodes_per_facet{{3}};
   // clang-format off
     static constexpr std::array<UInt, 9> facet_connectivity_vect{{
         0, 1, 2,
         1, 2, 0,
         3, 4, 5}};
   // clang-format on
 };
 
 template <> struct GeometricalElementProperty<_gt_tetrahedron_4> {
   static constexpr UInt spatial_dimension{3};
   static constexpr UInt nb_nodes_per_element{4};
   static constexpr UInt nb_facet_types{1};
   static constexpr std::array<UInt, nb_facet_types> nb_facets{{4}};
   static constexpr std::array<UInt, nb_facet_types> nb_nodes_per_facet{{3}};
   // clang-format off
     static constexpr std::array<UInt, 12> facet_connectivity_vect{{
         0, 1, 2, 0,
         2, 2, 0, 1,
         1, 3, 3, 3}};
   // clang-format on
 };
 
 template <> struct GeometricalElementProperty<_gt_tetrahedron_10> {
   static constexpr UInt spatial_dimension{3};
   static constexpr UInt nb_nodes_per_element{10};
   static constexpr UInt nb_facet_types{1};
   static constexpr std::array<UInt, nb_facet_types> nb_facets{{4}};
   static constexpr std::array<UInt, nb_facet_types> nb_nodes_per_facet{{6}};
   // clang-format off
   static constexpr std::array<UInt, 6*4> facet_connectivity_vect{{
       0, 1, 2, 0,
       2, 2, 0, 1,
       1, 3, 3, 3,
       6, 5, 6, 4,
       5, 9, 7, 8,
       4, 8, 9, 7}};
   // clang-format on
 };
 
 template <> struct GeometricalElementProperty<_gt_quadrangle_4> {
   static constexpr UInt spatial_dimension{2};
   static constexpr UInt nb_nodes_per_element{4};
   static constexpr UInt nb_facet_types{1};
   static constexpr std::array<UInt, nb_facet_types> nb_facets{{4}};
   static constexpr std::array<UInt, nb_facet_types> nb_nodes_per_facet{{2}};
   // clang-format off
   static constexpr std::array<UInt, 2*4> facet_connectivity_vect{{
       0, 1, 2, 3,
       1, 2, 3, 0}};
   // clang-format on
 };
 
 template <> struct GeometricalElementProperty<_gt_quadrangle_8> {
   static constexpr UInt spatial_dimension{2};
   static constexpr UInt nb_nodes_per_element{8};
   static constexpr UInt nb_facet_types{1};
   static constexpr std::array<UInt, nb_facet_types> nb_facets{{4}};
   static constexpr std::array<UInt, nb_facet_types> nb_nodes_per_facet{{3}};
   // clang-format off
   static constexpr std::array<UInt, 4*3> facet_connectivity_vect{{
       0, 1, 2, 3,
       1, 2, 3, 0,
       4, 5, 6, 7}};
   // clang-format on
 };
 
 template <> struct GeometricalElementProperty<_gt_hexahedron_8> {
   static constexpr UInt spatial_dimension{3};
   static constexpr UInt nb_nodes_per_element{8};
   static constexpr UInt nb_facet_types{1};
   static constexpr std::array<UInt, nb_facet_types> nb_facets{{6}};
   static constexpr std::array<UInt, nb_facet_types> nb_nodes_per_facet{{4}};
   // clang-format off
   static constexpr std::array<UInt, 4*6> facet_connectivity_vect{{
       0, 0, 1, 2, 3, 4,
       3, 1, 2, 3, 0, 5,
       2, 5, 6, 7, 4, 6,
       1, 4, 5, 6, 7, 7}};
   // clang-format on
 };
 
 template <> struct GeometricalElementProperty<_gt_hexahedron_20> {
   static constexpr UInt spatial_dimension{3};
   static constexpr UInt nb_nodes_per_element{20};
   static constexpr UInt nb_facet_types{1};
   static constexpr std::array<UInt, nb_facet_types> nb_facets{{6}};
   static constexpr std::array<UInt, nb_facet_types> nb_nodes_per_facet{{8}};
   // clang-format off
   static constexpr std::array<UInt, 8*6> facet_connectivity_vect{{
       0,  1,  2,  3,  0,  4,
       1,  2,  3,  0,  3,  5,
       5,  6,  7,  4,  2,  6,
       4,  5,  6,  7,  1,  7,
       8,  9, 10, 11, 11, 16,
       13, 14, 15, 12, 10, 17,
       16, 17, 18, 19,  9, 18,
       12, 13, 14, 15,  8, 19}};
   // clang-format on
 };
 
 template <> struct GeometricalElementProperty<_gt_pentahedron_6> {
   static constexpr UInt spatial_dimension{3};
   static constexpr UInt nb_nodes_per_element{6};
   static constexpr UInt nb_facet_types{2};
   static constexpr std::array<UInt, nb_facet_types> nb_facets{{2, 3}};
   static constexpr std::array<UInt, nb_facet_types> nb_nodes_per_facet{{3, 4}};
   // clang-format off
   static constexpr std::array<UInt, 3*2 + 4*3> facet_connectivity_vect{{
       // first type
       0, 3,
       2, 4,
       1, 5,
       // second type
       0, 0, 1,
       1, 3, 2,
       4, 5, 5,
       3, 2, 4}};
   // clang-format on
 };
 
 template <> struct GeometricalElementProperty<_gt_pentahedron_15> {
   static constexpr UInt spatial_dimension{3};
   static constexpr UInt nb_nodes_per_element{15};
   static constexpr UInt nb_facet_types{2};
   static constexpr std::array<UInt, nb_facet_types> nb_facets{{2, 3}};
   static constexpr std::array<UInt, nb_facet_types> nb_nodes_per_facet{{6, 8}};
   // clang-format off
   static constexpr std::array<UInt, 6*2 + 8*3> facet_connectivity_vect{{
       // first type
       0, 3,
       2, 4,
       1, 5,
       8, 12,
       7, 13,
       6, 14,
       // second type
        0, 0, 1,
        1, 3, 2,
        4, 5, 5,
        3, 2, 4,
        6, 9, 7,
       10, 14, 11,
       12, 11, 13,
        9, 8, 10}};
   // clang-format on
 };
 
 #if defined(AKANTU_COHESIVE_ELEMENT)
 /* --------------------------------------------------------------------------
  */
 template <> struct GeometricalElementProperty<_gt_cohesive_2d_4> {
   static constexpr UInt spatial_dimension{2};
   static constexpr UInt nb_nodes_per_element{4};
   static constexpr UInt nb_facet_types{1};
   static constexpr std::array<UInt, nb_facet_types> nb_facets{{2}};
   static constexpr std::array<UInt, nb_facet_types> nb_nodes_per_facet{{2}};
   // clang-format off
   static constexpr std::array<UInt, 2 * 2> facet_connectivity_vect{{
       0, 2,
       1, 3}};
   // clang-format on
 };
 
 /* --------------------------------------------------------------------------
  */
 template <> struct GeometricalElementProperty<_gt_cohesive_2d_6> {
   static constexpr UInt spatial_dimension{2};
   static constexpr UInt nb_nodes_per_element{6};
   static constexpr UInt nb_facet_types{1};
   static constexpr std::array<UInt, nb_facet_types> nb_facets{{2}};
   static constexpr std::array<UInt, nb_facet_types> nb_nodes_per_facet{{3}};
   // clang-format off
   static constexpr std::array<UInt, 3*2> facet_connectivity_vect{{
       0, 3,
       1, 4,
       2, 5}};
   // clang-format on
 };
 
 /* --------------------------------------------------------------------------
  */
 template <> struct GeometricalElementProperty<_gt_cohesive_1d_2> {
   static constexpr UInt spatial_dimension{1};
   static constexpr UInt nb_nodes_per_element{2};
   static constexpr UInt nb_facet_types{1};
   static constexpr std::array<UInt, nb_facet_types> nb_facets{{2}};
   static constexpr std::array<UInt, nb_facet_types> nb_nodes_per_facet{{1}};
   // clang-format off
   static constexpr std::array<UInt, 2> facet_connectivity_vect{{0, 1}};
   // clang-format on
 };
 
 /* --------------------------------------------------------------------------
  */
 template <> struct GeometricalElementProperty<_gt_cohesive_3d_6> {
   static constexpr UInt spatial_dimension{3};
   static constexpr UInt nb_nodes_per_element{6};
   static constexpr UInt nb_facet_types{1};
   static constexpr std::array<UInt, nb_facet_types> nb_facets{{2}};
   static constexpr std::array<UInt, nb_facet_types> nb_nodes_per_facet{{3}};
   // clang-format off
   static constexpr std::array<UInt, 3*2> facet_connectivity_vect{{
       0, 3,
       1, 4,
       2, 5}};
   // clang-format on
 };
 
 /* --------------------------------------------------------------------------
  */
 template <> struct GeometricalElementProperty<_gt_cohesive_3d_12> {
   static constexpr UInt spatial_dimension{3};
   static constexpr UInt nb_nodes_per_element{12};
   static constexpr UInt nb_facet_types{1};
   static constexpr std::array<UInt, nb_facet_types> nb_facets{{2}};
   static constexpr std::array<UInt, nb_facet_types> nb_nodes_per_facet{{6}};
   // clang-format off
   static constexpr std::array<UInt, 6*2> facet_connectivity_vect{{
       0, 6,
       1, 7,
       2, 8,
       3, 9,
       4, 10,
       5, 11}};
   // clang-format on
 };
 
 /* --------------------------------------------------------------------------
  */
 template <> struct GeometricalElementProperty<_gt_cohesive_3d_8> {
   static constexpr UInt spatial_dimension{3};
   static constexpr UInt nb_nodes_per_element{8};
   static constexpr UInt nb_facet_types{1};
   static constexpr std::array<UInt, nb_facet_types> nb_facets{{2}};
   static constexpr std::array<UInt, nb_facet_types> nb_nodes_per_facet{{4}};
   // clang-format off
   static constexpr std::array<UInt, 4*2> facet_connectivity_vect{{
       0, 4,
       1, 5,
       2, 6,
       3, 7}};
   // clang-format on
 };
 
 /* --------------------------------------------------------------------------
  */
 template <> struct GeometricalElementProperty<_gt_cohesive_3d_16> {
   static constexpr UInt spatial_dimension{3};
   static constexpr UInt nb_nodes_per_element{16};
   static constexpr UInt nb_facet_types{1};
   static constexpr std::array<UInt, nb_facet_types> nb_facets{{2}};
   static constexpr std::array<UInt, nb_facet_types> nb_nodes_per_facet{{8}};
   // clang-format off
   static constexpr std::array<UInt, 8*2> facet_connectivity_vect{{
       0, 8,
       1, 9,
       2, 10,
       3, 11,
       4, 12,
       5, 13,
       6, 14,
       7, 15}};
   // clang-format on
 };
 #endif // AKANTU_COHESIVE_ELEMENT
 
 /* ------------------------------------------------------------------------ */
 template <> struct ElementClassExtraGeometryProperties<_not_defined> {
   static constexpr ElementType p1_type{_not_defined};
   static constexpr std::array<ElementType, 1> facet_type{{_not_defined}};
 };
 
 template <> struct ElementClassExtraGeometryProperties<_point_1> {
   static constexpr ElementType p1_type{_point_1};
   static constexpr std::array<ElementType, 1> facet_type{{_point_1}};
 };
 
 template <> struct ElementClassExtraGeometryProperties<_segment_2> {
   static constexpr ElementType p1_type{_segment_2};
   static constexpr std::array<ElementType, 1> facet_type{{_point_1}};
 };
 
 template <> struct ElementClassExtraGeometryProperties<_segment_3> {
   static constexpr ElementType p1_type{_segment_2};
   static constexpr std::array<ElementType, 1> facet_type{{_point_1}};
 };
 
 template <> struct ElementClassExtraGeometryProperties<_triangle_3> {
   static constexpr ElementType p1_type{_triangle_3};
   static constexpr std::array<ElementType, 1> facet_type{{_segment_2}};
 };
 
 template <> struct ElementClassExtraGeometryProperties<_triangle_6> {
   static constexpr ElementType p1_type{_triangle_3};
   static constexpr std::array<ElementType, 1> facet_type{{_segment_3}};
 };
 
 template <> struct ElementClassExtraGeometryProperties<_tetrahedron_4> {
   static constexpr ElementType p1_type{_tetrahedron_4};
   static constexpr std::array<ElementType, 1> facet_type{{_triangle_3}};
 };
 
 template <> struct ElementClassExtraGeometryProperties<_tetrahedron_10> {
   static constexpr ElementType p1_type{_tetrahedron_4};
   static constexpr std::array<ElementType, 1> facet_type{{_triangle_6}};
 };
 
 template <> struct ElementClassExtraGeometryProperties<_quadrangle_4> {
   static constexpr ElementType p1_type{_quadrangle_4};
   static constexpr std::array<ElementType, 1> facet_type{{_segment_2}};
 };
 
 template <> struct ElementClassExtraGeometryProperties<_quadrangle_8> {
   static constexpr ElementType p1_type{_quadrangle_4};
   static constexpr std::array<ElementType, 1> facet_type{{_segment_3}};
 };
 
 template <> struct ElementClassExtraGeometryProperties<_hexahedron_8> {
   static constexpr ElementType p1_type{_hexahedron_8};
   static constexpr std::array<ElementType, 1> facet_type{{_quadrangle_4}};
 };
 
 template <> struct ElementClassExtraGeometryProperties<_hexahedron_20> {
   static constexpr ElementType p1_type{_hexahedron_8};
   static constexpr std::array<ElementType, 1> facet_type{{_quadrangle_8}};
 };
 
 template <> struct ElementClassExtraGeometryProperties<_pentahedron_6> {
   static constexpr ElementType p1_type{_pentahedron_6};
   static constexpr std::array<ElementType, 2> facet_type{
       {_triangle_3, _quadrangle_4}};
 };
 
 template <> struct ElementClassExtraGeometryProperties<_pentahedron_15> {
   static constexpr ElementType p1_type{_pentahedron_6};
   static constexpr std::array<ElementType, 2> facet_type{
       {_triangle_6, _quadrangle_8}};
 };
 
 #if defined(AKANTU_COHESIVE_ELEMENT)
 template <> struct ElementClassExtraGeometryProperties<_cohesive_2d_4> {
   static constexpr ElementType p1_type{_cohesive_2d_4};
   static constexpr std::array<ElementType, 1> facet_type{{_segment_2}};
 };
 
 template <> struct ElementClassExtraGeometryProperties<_cohesive_2d_6> {
   static constexpr ElementType p1_type{_cohesive_2d_4};
   static constexpr std::array<ElementType, 1> facet_type{{_segment_3}};
 };
 
 template <> struct ElementClassExtraGeometryProperties<_cohesive_1d_2> {
   static constexpr ElementType p1_type{_cohesive_1d_2};
   static constexpr std::array<ElementType, 1> facet_type{{_point_1}};
 };
 
 template <> struct ElementClassExtraGeometryProperties<_cohesive_3d_6> {
   static constexpr ElementType p1_type{_cohesive_3d_6};
   static constexpr std::array<ElementType, 1> facet_type{{_triangle_3}};
 };
 
 template <> struct ElementClassExtraGeometryProperties<_cohesive_3d_12> {
   static constexpr ElementType p1_type{_cohesive_3d_6};
   static constexpr std::array<ElementType, 1> facet_type{{_triangle_6}};
 };
 
 template <> struct ElementClassExtraGeometryProperties<_cohesive_3d_8> {
   static constexpr ElementType p1_type{_cohesive_3d_8};
   static constexpr std::array<ElementType, 1> facet_type{{_quadrangle_4}};
 };
 
 template <> struct ElementClassExtraGeometryProperties<_cohesive_3d_16> {
   static constexpr ElementType p1_type{_cohesive_3d_8};
   static constexpr std::array<ElementType, 1> facet_type{{_quadrangle_8}};
 };
 #endif // AKANTU_COHESIVE_ELEMENT
 
 } // namespace akantu
 
 #endif /* __AKANTU_GEOMETRICAL_ELEMENT_PROPERTY_HH__ */
diff --git a/src/fe_engine/integration_point.hh b/src/fe_engine/integration_point.hh
index 9c8eb8056..0e09a5b89 100644
--- a/src/fe_engine/integration_point.hh
+++ b/src/fe_engine/integration_point.hh
@@ -1,169 +1,170 @@
 /**
  * @file   integration_point.hh
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Wed Jun 17 2015
- * @date last modification: Sun Nov 15 2015
+ * @date last modification: Wed Nov 08 2017
  *
  * @brief  definition of the class IntegrationPoint
  *
  * @section LICENSE
  *
- * Copyright (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne) Laboratory
- * (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * Copyright (©) 2015-2018 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
- * terms  of the  GNU Lesser  General Public  License as  published by  the Free
+ * 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
+ * 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_types.hh"
 #include "element.hh"
 /* -------------------------------------------------------------------------- */
 
 #ifndef AKANTU_QUADRATURE_POINT_H
 #define AKANTU_QUADRATURE_POINT_H
 
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 class IntegrationPoint;
 extern const IntegrationPoint IntegrationPointNull;
 /* -------------------------------------------------------------------------- */
 
 class IntegrationPoint : public Element {
 
   /* ------------------------------------------------------------------------ */
   /* Typedefs                                                                 */
   /* ------------------------------------------------------------------------ */
 
 public:
   using position_type = Vector<Real>;
 
   /* ------------------------------------------------------------------------ */
   /* Constructors/Destructors                                                 */
   /* ------------------------------------------------------------------------ */
 
 public:
   IntegrationPoint(const Element & element, UInt num_point = 0,
                    UInt nb_quad_per_element = 0)
       : Element(element), num_point(num_point),
         global_num(element.element * nb_quad_per_element + num_point),
         position(nullptr, 0){};
 
   IntegrationPoint(ElementType type = _not_defined, UInt element = 0,
                    UInt num_point = 0, GhostType ghost_type = _not_ghost)
       : Element{type, element, ghost_type}, num_point(num_point),
         position(nullptr, 0){};
 
   IntegrationPoint(UInt element, UInt num_point, UInt global_num,
                    const position_type & position, ElementType type,
                    GhostType ghost_type = _not_ghost)
       : Element{type, element, ghost_type}, num_point(num_point),
         global_num(global_num), position(nullptr, 0) {
     this->position.shallowCopy(position);
   };
 
   IntegrationPoint(const IntegrationPoint & quad)
       : Element(quad), num_point(quad.num_point), global_num(quad.global_num),
         position(nullptr, 0) {
     position.shallowCopy(quad.position);
   };
 
   virtual ~IntegrationPoint() = default;
   /* ------------------------------------------------------------------------ */
   /* Methods                                                                  */
   /* ------------------------------------------------------------------------ */
 
   inline bool operator==(const IntegrationPoint & quad) const {
     return Element::operator==(quad) && this->num_point == quad.num_point;
   }
 
   inline bool operator!=(const IntegrationPoint & quad) const {
     return Element::operator!=(quad) || (num_point != quad.num_point) ||
            (global_num != quad.global_num);
   }
 
   bool operator<(const IntegrationPoint & rhs) const {
     bool res = Element::operator<(rhs) ||
                (Element::operator==(rhs) && this->num_point < rhs.num_point);
     return res;
   }
 
   inline IntegrationPoint & operator=(const IntegrationPoint & q) {
     if (this != &q) {
       element = q.element;
       type = q.type;
       ghost_type = q.ghost_type;
       num_point = q.num_point;
       global_num = q.global_num;
       position.shallowCopy(q.position);
     }
 
     return *this;
   }
 
   /// get the position of the integration point
   AKANTU_GET_MACRO(Position, position, const position_type &);
 
   /// set the position of the integration point
   void setPosition(const position_type & position) {
     this->position.shallowCopy(position);
   }
 
   /// deep copy of the position of the integration point
   void copyPosition(const position_type & position) {
     this->position.deepCopy(position);
   }
 
   /// function to print the containt of the class
   virtual void printself(std::ostream & stream, int indent = 0) const {
     std::string space;
     for (Int i = 0; i < indent; i++, space += AKANTU_INDENT)
       ;
     stream << space << "IntegrationPoint [";
     stream << *static_cast<const Element *>(this);
     stream << ", " << num_point << "(" << global_num << ")"
            << "]";
   }
 
   /* ------------------------------------------------------------------------ */
   /* Class Members                                                            */
   /* ------------------------------------------------------------------------ */
 
 public:
   /// number of quadrature point in the element
   UInt num_point;
   /// global number of the quadrature point
   UInt global_num{0};
   // TODO might be temporary: however this class should be tought maybe...
   std::string material_id;
 
 private:
   /// position of the quadrature point
   position_type position;
 };
 
 /// standard output stream operator
 inline std::ostream & operator<<(std::ostream & stream,
                                  const IntegrationPoint & _this) {
   _this.printself(stream);
   return stream;
 }
 
 } // akantu
 
 #endif /* AKANTU_QUADRATURE_POINT_H */
diff --git a/src/fe_engine/integrator.hh b/src/fe_engine/integrator.hh
index a9071ffe0..c751cfff4 100644
--- a/src/fe_engine/integrator.hh
+++ b/src/fe_engine/integrator.hh
@@ -1,136 +1,135 @@
 /**
  * @file   integrator.hh
  *
  * @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Fri Jun 18 2010
- * @date last modification: Thu Oct 22 2015
+ * @date last modification: Sun Dec 03 2017
  *
  * @brief  interface for integrator classes
  *
  * @section LICENSE
  *
- * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
- * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
- * Solides)
+ * 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
+ * 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
+ * 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_INTEGRATOR_HH__
 #define __AKANTU_INTEGRATOR_HH__
 
 /* -------------------------------------------------------------------------- */
 #include "aka_memory.hh"
 #include "mesh.hh"
 /* -------------------------------------------------------------------------- */
 namespace akantu {
 
 class Integrator : protected Memory {
   /* ------------------------------------------------------------------------ */
   /* Constructors/Destructors                                                 */
   /* ------------------------------------------------------------------------ */
 public:
   Integrator(const Mesh & mesh, const ID & id = "integrator",
              const MemoryID & memory_id = 0)
       : Memory(id, memory_id), mesh(mesh),
         jacobians("jacobians", id, memory_id) {
     AKANTU_DEBUG_IN();
 
     AKANTU_DEBUG_OUT();
   };
 
   ~Integrator() override = default;
 
   /* ------------------------------------------------------------------------ */
   /* Methods                                                                  */
   /* ------------------------------------------------------------------------ */
 public:
   /// empty method
   template <ElementType type>
   inline void precomputeJacobiansOnQuadraturePoints(__attribute__((unused))
                                                     GhostType ghost_type) {}
 
   /// empty method
   void integrateOnElement(const Array<Real> & /*f*/, Real * /*intf*/,
                           UInt /*nb_degree_of_freedom*/,
                           const Element & /*elem*/,
                           GhostType /*ghost_type*/) const {};
 
   /// function to print the contain of the class
   virtual void printself(std::ostream & stream, int indent = 0) const {
     std::string space;
     for (Int i = 0; i < indent; i++, space += AKANTU_INDENT)
       ;
     stream << space << "Integrator [" << std::endl;
     jacobians.printself(stream, indent + 1);
     stream << space << "]" << std::endl;
   };
 
   /* ------------------------------------------------------------------------ */
 public:
   virtual void onElementsAdded(const Array<Element> &) {}
   virtual void
   onElementsRemoved(const Array<Element> &,
                     const ElementTypeMapArray<UInt> & new_numbering) {
     jacobians.onElementsRemoved(new_numbering);
   }
   /* ------------------------------------------------------------------------ */
   /* Accessors                                                                */
   /* ------------------------------------------------------------------------ */
 public:
   /// access to the jacobians
   Array<Real> & getJacobians(const ElementType & type,
                              const GhostType & ghost_type = _not_ghost) {
     return jacobians(type, ghost_type);
   };
 
   /// access to the jacobians const
   const Array<Real> &
   getJacobians(const ElementType & type,
                const GhostType & ghost_type = _not_ghost) const {
     return jacobians(type, ghost_type);
   };
 
   AKANTU_GET_MACRO(Jacobians, jacobians, const ElementTypeMapArray<Real> &);
 
   /* ------------------------------------------------------------------------ */
   /* Class Members                                                            */
   /* ------------------------------------------------------------------------ */
 protected:
   /// mesh associated to the integrator
   const Mesh & mesh;
 
   /// jacobians for all elements
   ElementTypeMapArray<Real> jacobians;
 };
 
 /* -------------------------------------------------------------------------- */
 /* inline functions                                                           */
 /* -------------------------------------------------------------------------- */
 
 //#include "integrator_inline_impl.cc"
 
 /// standard output stream operator
 inline std::ostream & operator<<(std::ostream & stream,
                                  const Integrator & _this) {
   _this.printself(stream);
   return stream;
 }
 
 } // namespace akantu
 
 #endif /* __AKANTU_INTEGRATOR_HH__ */
diff --git a/src/fe_engine/integrator_gauss.hh b/src/fe_engine/integrator_gauss.hh
index 4b76a5962..469f19832 100644
--- a/src/fe_engine/integrator_gauss.hh
+++ b/src/fe_engine/integrator_gauss.hh
@@ -1,199 +1,199 @@
 /**
  * @file   integrator_gauss.hh
  *
  * @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Fri Jun 18 2010
- * @date last modification: Thu Oct 22 2015
+ * @date last modification: Wed Nov 08 2017
  *
  * @brief  Gauss integration facilities
  *
  * @section LICENSE
  *
- * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
- * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
- * Solides)
+ * 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
+ * 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
+ * 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 "integrator.hh"
 /* -------------------------------------------------------------------------- */
 
 #ifndef __AKANTU_INTEGRATOR_GAUSS_HH__
 #define __AKANTU_INTEGRATOR_GAUSS_HH__
 
 namespace akantu {
 namespace integrator {
   namespace details {
     template <ElementKind> struct GaussIntegratorComputeJacobiansHelper;
   } // namespace details
 } // namespace fe_engine
 
 /* -------------------------------------------------------------------------- */
 template <ElementKind kind, class IntegrationOrderFunctor>
 class IntegratorGauss : public Integrator {
   /* ------------------------------------------------------------------------ */
   /* Constructors/Destructors                                                 */
   /* ------------------------------------------------------------------------ */
 public:
   IntegratorGauss(const Mesh & mesh, const ID & id = "integrator_gauss",
                   const MemoryID & memory_id = 0);
 
   ~IntegratorGauss() override = default;
 
   /* ------------------------------------------------------------------------ */
   /* Methods                                                                  */
   /* ------------------------------------------------------------------------ */
 public:
   void initIntegrator(const Array<Real> & nodes, const ElementType & type,
                       const GhostType & ghost_type);
 
   template <ElementType type>
   inline void initIntegrator(const Array<Real> & nodes,
                              const GhostType & ghost_type);
 
   /// integrate f on the element "elem" of type "type"
   template <ElementType type>
   inline void integrateOnElement(const Array<Real> & f, Real * intf,
                                  UInt nb_degree_of_freedom, const UInt elem,
                                  const GhostType & ghost_type) const;
 
   /// integrate f for all elements of type "type"
   template <ElementType type>
   void integrate(const Array<Real> & in_f, Array<Real> & intf,
                  UInt nb_degree_of_freedom, const GhostType & ghost_type,
                  const Array<UInt> & filter_elements) const;
 
   /// integrate scalar field in_f
   template <ElementType type, UInt polynomial_degree>
   Real integrate(const Array<Real> & in_f,
                  const GhostType & ghost_type = _not_ghost) const;
 
   /// integrate partially around a quadrature point (@f$ intf_q = f_q * J_q *
   /// w_q @f$)
   template <ElementType type>
   Real integrate(const Vector<Real> & in_f, UInt index,
                  const GhostType & ghost_type) const;
 
   /// integrate scalar field in_f
   template <ElementType type>
   Real integrate(const Array<Real> & in_f, const GhostType & ghost_type,
                  const Array<UInt> & filter_elements) const;
 
   /// integrate a field without using the pre-computed values
   template <ElementType type, UInt polynomial_degree>
   void integrate(const Array<Real> & in_f, Array<Real> & intf,
                  UInt nb_degree_of_freedom, const GhostType & ghost_type) const;
 
   /// integrate partially around a quadrature point (@f$ intf_q = f_q * J_q *
   /// w_q @f$)
   template <ElementType type>
   void integrateOnIntegrationPoints(const Array<Real> & in_f,
                                     Array<Real> & intf,
                                     UInt nb_degree_of_freedom,
                                     const GhostType & ghost_type,
                                     const Array<UInt> & filter_elements) const;
 
   /// return a matrix with quadrature points natural coordinates
   template <ElementType type>
   const Matrix<Real> & getIntegrationPoints(const GhostType & ghost_type) const;
 
   /// return number of quadrature points
   template <ElementType type>
   UInt getNbIntegrationPoints(const GhostType & ghost_type) const;
 
   template <ElementType type, UInt n> Matrix<Real> getIntegrationPoints() const;
   template <ElementType type, UInt n>
   Vector<Real> getIntegrationWeights() const;
 
 protected:
   friend struct integrator::details::GaussIntegratorComputeJacobiansHelper<
       kind>;
 
   template <ElementType type>
   void computeJacobiansOnIntegrationPoints(
       const Array<Real> & nodes, const Matrix<Real> & quad_points,
       Array<Real> & jacobians, const GhostType & ghost_type,
       const Array<UInt> & filter_elements = empty_filter) const;
 
   void computeJacobiansOnIntegrationPoints(
       const Array<Real> & nodes, const Matrix<Real> & quad_points,
       Array<Real> & jacobians, const ElementType & type,
       const GhostType & ghost_type,
       const Array<UInt> & filter_elements = empty_filter) const;
 
   /// precompute jacobians on elements of type "type"
   template <ElementType type>
   void precomputeJacobiansOnQuadraturePoints(const Array<Real> & nodes,
                                              const GhostType & ghost_type);
 
   // multiply the jacobians by the integration weights and stores the results in
   // jacobians
   template <ElementType type, UInt polynomial_degree>
   void multiplyJacobiansByWeights(Array<Real> & jacobians) const;
 
   /// compute the vector of quadrature points natural coordinates
   template <ElementType type>
   void computeQuadraturePoints(const GhostType & ghost_type);
 
   /// check that the jacobians are not negative
   template <ElementType type>
   void checkJacobians(const GhostType & ghost_type) const;
 
   /// internal integrate partially around a quadrature point (@f$ intf_q = f_q *
   /// J_q *
   /// w_q @f$)
   void integrateOnIntegrationPoints(const Array<Real> & in_f,
                                     Array<Real> & intf,
                                     UInt nb_degree_of_freedom,
                                     const Array<Real> & jacobians,
                                     UInt nb_element) const;
 
   void integrate(const Array<Real> & in_f, Array<Real> & intf,
                  UInt nb_degree_of_freedom, const Array<Real> & jacobians,
                  UInt nb_element) const;
 
 public:
   /// compute the jacobians on quad points for a given element
   template <ElementType type>
   void
   computeJacobianOnQuadPointsByElement(const Matrix<Real> & node_coords,
                                        const Matrix<Real> & integration_points,
                                        Vector<Real> & jacobians) const;
 
 public:
   void onElementsAdded(const Array<Element> & elements) override;
 
   /* ------------------------------------------------------------------------ */
   /* Class Members                                                            */
   /* ------------------------------------------------------------------------ */
 protected:
   /// integrate the field f with the jacobian jac -> inte
   inline void integrate(Real * f, Real * jac, Real * inte,
                         UInt nb_degree_of_freedom,
                         UInt nb_quadrature_points) const;
 
 private:
   /// ElementTypeMap of the quadrature points
   ElementTypeMap<Matrix<Real>> quadrature_points;
 };
 
 } // namespace akantu
 
 #include "integrator_gauss_inline_impl.cc"
 
 #endif /* __AKANTU_INTEGRATOR_GAUSS_HH__ */
diff --git a/src/fe_engine/integrator_gauss_inline_impl.cc b/src/fe_engine/integrator_gauss_inline_impl.cc
index 681123e63..56fe0c8e3 100644
--- a/src/fe_engine/integrator_gauss_inline_impl.cc
+++ b/src/fe_engine/integrator_gauss_inline_impl.cc
@@ -1,709 +1,709 @@
 /**
  * @file   integrator_gauss_inline_impl.cc
  *
  * @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Tue Feb 15 2011
- * @date last modification: Thu Nov 19 2015
+ * @date last modification: Tue Feb 20 2018
  *
  * @brief  inline function of gauss integrator
  *
  * @section LICENSE
  *
- * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
- * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
- * Solides)
+ * 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
+ * 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
+ * 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 "fe_engine.hh"
 #include "mesh_iterators.hh"
 #if defined(AKANTU_DEBUG_TOOLS)
 #include "aka_debug_tools.hh"
 #endif
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 namespace debug {
   struct IntegratorGaussException : public Exception {};
 }
 /* -------------------------------------------------------------------------- */
 template <ElementKind kind, class IntegrationOrderFunctor>
 template <ElementType type>
 inline void IntegratorGauss<kind, IntegrationOrderFunctor>::integrateOnElement(
     const Array<Real> & f, Real * intf, UInt nb_degree_of_freedom,
     const UInt elem, const GhostType & ghost_type) const {
   Array<Real> & jac_loc = jacobians(type, ghost_type);
 
   UInt nb_quadrature_points = ElementClass<type>::getNbQuadraturePoints();
   AKANTU_DEBUG_ASSERT(f.getNbComponent() == nb_degree_of_freedom,
                       "The vector f do not have the good number of component.");
 
   Real * f_val = f.storage() + elem * f.getNbComponent();
   Real * jac_val = jac_loc.storage() + elem * nb_quadrature_points;
 
   integrate(f_val, jac_val, intf, nb_degree_of_freedom, nb_quadrature_points);
 }
 
 /* -------------------------------------------------------------------------- */
 template <ElementKind kind, class IntegrationOrderFunctor>
 template <ElementType type>
 inline Real IntegratorGauss<kind, IntegrationOrderFunctor>::integrate(
     const Vector<Real> & in_f, UInt index, const GhostType & ghost_type) const {
   const Array<Real> & jac_loc = jacobians(type, ghost_type);
 
   UInt nb_quadrature_points =
       GaussIntegrationElement<type>::getNbQuadraturePoints();
   AKANTU_DEBUG_ASSERT(in_f.size() == nb_quadrature_points,
                       "The vector f do not have nb_quadrature_points entries.");
 
   Real * jac_val = jac_loc.storage() + index * nb_quadrature_points;
   Real intf;
 
   integrate(in_f.storage(), jac_val, &intf, 1, nb_quadrature_points);
 
   return intf;
 }
 
 /* -------------------------------------------------------------------------- */
 template <ElementKind kind, class IntegrationOrderFunctor>
 inline void IntegratorGauss<kind, IntegrationOrderFunctor>::integrate(
     Real * f, Real * jac, Real * inte, UInt nb_degree_of_freedom,
     UInt nb_quadrature_points) const {
   memset(inte, 0, nb_degree_of_freedom * sizeof(Real));
 
   Real * cjac = jac;
   for (UInt q = 0; q < nb_quadrature_points; ++q) {
     for (UInt dof = 0; dof < nb_degree_of_freedom; ++dof) {
       inte[dof] += *f * *cjac;
       ++f;
     }
     ++cjac;
   }
 }
 
 /* -------------------------------------------------------------------------- */
 template <ElementKind kind, class IntegrationOrderFunctor>
 template <ElementType type>
 inline const Matrix<Real> &
 IntegratorGauss<kind, IntegrationOrderFunctor>::getIntegrationPoints(
     const GhostType & ghost_type) const {
   AKANTU_DEBUG_ASSERT(
       quadrature_points.exists(type, ghost_type),
       "Quadrature points for type "
           << quadrature_points.printType(type, ghost_type)
           << " have not been initialized."
           << " Did you use 'computeQuadraturePoints' function ?");
   return quadrature_points(type, ghost_type);
 }
 
 /* -------------------------------------------------------------------------- */
 template <ElementKind kind, class IntegrationOrderFunctor>
 template <ElementType type>
 inline UInt
 IntegratorGauss<kind, IntegrationOrderFunctor>::getNbIntegrationPoints(
     const GhostType & ghost_type) const {
   AKANTU_DEBUG_ASSERT(
       quadrature_points.exists(type, ghost_type),
       "Quadrature points for type "
           << quadrature_points.printType(type, ghost_type)
           << " have not been initialized."
           << " Did you use 'computeQuadraturePoints' function ?");
   return quadrature_points(type, ghost_type).cols();
 }
 
 /* -------------------------------------------------------------------------- */
 template <ElementKind kind, class IntegrationOrderFunctor>
 template <ElementType type, UInt polynomial_degree>
 inline Matrix<Real>
 IntegratorGauss<kind, IntegrationOrderFunctor>::getIntegrationPoints() const {
   return GaussIntegrationElement<type,
                                  polynomial_degree>::getQuadraturePoints();
 }
 
 /* -------------------------------------------------------------------------- */
 template <ElementKind kind, class IntegrationOrderFunctor>
 template <ElementType type, UInt polynomial_degree>
 inline Vector<Real>
 IntegratorGauss<kind, IntegrationOrderFunctor>::getIntegrationWeights() const {
   return GaussIntegrationElement<type, polynomial_degree>::getWeights();
 }
 
 /* -------------------------------------------------------------------------- */
 template <ElementKind kind, class IntegrationOrderFunctor>
 template <ElementType type>
 inline void
 IntegratorGauss<kind, IntegrationOrderFunctor>::computeQuadraturePoints(
     const GhostType & ghost_type) {
   Matrix<Real> & quads = quadrature_points(type, ghost_type);
   const UInt polynomial_degree =
       IntegrationOrderFunctor::template getOrder<type>();
   quads =
       GaussIntegrationElement<type, polynomial_degree>::getQuadraturePoints();
 }
 
 /* -------------------------------------------------------------------------- */
 template <ElementKind kind, class IntegrationOrderFunctor>
 template <ElementType type>
 inline void IntegratorGauss<kind, IntegrationOrderFunctor>::
     computeJacobianOnQuadPointsByElement(const Matrix<Real> & node_coords,
                                          const Matrix<Real> & quad,
                                          Vector<Real> & jacobians) const {
   // jacobian
   ElementClass<type>::computeJacobian(quad, node_coords, jacobians);
 }
 
 /* -------------------------------------------------------------------------- */
 template <ElementKind kind, class IntegrationOrderFunctor>
 IntegratorGauss<kind, IntegrationOrderFunctor>::IntegratorGauss(
     const Mesh & mesh, const ID & id, const MemoryID & memory_id)
     : Integrator(mesh, id, memory_id) {
   AKANTU_DEBUG_IN();
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <ElementKind kind, class IntegrationOrderFunctor>
 template <ElementType type>
 void IntegratorGauss<kind, IntegrationOrderFunctor>::checkJacobians(
     const GhostType & ghost_type) const {
   AKANTU_DEBUG_IN();
 
   UInt nb_quadrature_points = this->quadrature_points(type, ghost_type).cols();
 
   UInt nb_element = mesh.getConnectivity(type, ghost_type).size();
 
   Real * jacobians_val = jacobians(type, ghost_type).storage();
 
   for (UInt i = 0; i < nb_element * nb_quadrature_points;
        ++i, ++jacobians_val) {
     if (*jacobians_val < 0)
       AKANTU_CUSTOM_EXCEPTION_INFO(debug::IntegratorGaussException{},
                                    "Negative jacobian computed,"
                                        << " possible problem in the element "
                                           "node ordering (Quadrature Point "
                                        << i % nb_quadrature_points << ":"
                                        << i / nb_quadrature_points << ":"
                                        << type << ":" << ghost_type << ")");
   }
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <ElementKind kind, class IntegrationOrderFunctor>
 template <ElementType type>
 void IntegratorGauss<kind, IntegrationOrderFunctor>::
     computeJacobiansOnIntegrationPoints(
         const Array<Real> & nodes, const Matrix<Real> & quad_points,
         Array<Real> & jacobians, const GhostType & ghost_type,
         const Array<UInt> & filter_elements) const {
   AKANTU_DEBUG_IN();
 
   UInt spatial_dimension = mesh.getSpatialDimension();
   UInt nb_nodes_per_element = Mesh::getNbNodesPerElement(type);
   UInt nb_quadrature_points = quad_points.cols();
 
   UInt nb_element = mesh.getNbElement(type, ghost_type);
   jacobians.resize(nb_element * nb_quadrature_points);
 
   auto jacobians_it =
       jacobians.begin_reinterpret(nb_quadrature_points, nb_element);
   auto jacobians_begin = jacobians_it;
 
   Array<Real> x_el(0, spatial_dimension * nb_nodes_per_element);
   FEEngine::extractNodalToElementField(mesh, nodes, x_el, type, ghost_type,
                                        filter_elements);
 
   auto x_it = x_el.begin(spatial_dimension, nb_nodes_per_element);
 
   nb_element = x_el.size();
 
   //  Matrix<Real> local_coord(spatial_dimension, nb_nodes_per_element);
   for (UInt elem = 0; elem < nb_element; ++elem, ++x_it) {
     const Matrix<Real> & x = *x_it;
     Vector<Real> & J = *jacobians_it;
     computeJacobianOnQuadPointsByElement<type>(x, quad_points, J);
 
     if (filter_elements == empty_filter) {
       ++jacobians_it;
     } else {
       jacobians_it = jacobians_begin + filter_elements(elem);
     }
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 #if defined(AKANTU_STRUCTURAL_MECHANICS)
 template <>
 template <ElementType type>
 void IntegratorGauss<_ek_structural, DefaultIntegrationOrderFunctor>::
     computeJacobiansOnIntegrationPoints(
         const Array<Real> & nodes, const Matrix<Real> & quad_points,
         Array<Real> & jacobians, const GhostType & ghost_type,
         const Array<UInt> & filter_elements) const {
   AKANTU_DEBUG_IN();
 
   const UInt spatial_dimension = mesh.getSpatialDimension();
   const UInt nb_nodes_per_element = Mesh::getNbNodesPerElement(type);
   const UInt nb_quadrature_points = quad_points.cols();
   const UInt nb_dofs = ElementClass<type>::getNbDegreeOfFreedom();
 
   UInt nb_element = mesh.getNbElement(type, ghost_type);
   jacobians.resize(nb_element * nb_quadrature_points);
 
   auto jacobians_it =
       jacobians.begin_reinterpret(nb_quadrature_points, nb_element);
   auto jacobians_begin = jacobians_it;
 
   Array<Real> x_el(0, spatial_dimension * nb_nodes_per_element);
   FEEngine::extractNodalToElementField(mesh, nodes, x_el, type, ghost_type,
                                        filter_elements);
 
   auto x_it = x_el.begin(spatial_dimension, nb_nodes_per_element);
 
   nb_element = x_el.size();
 
   const bool has_extra_normal =
       mesh.hasData<Real>("extra_normal", type, ghost_type);
   Array<Real>::const_vector_iterator extra_normal, extra_normal_begin;
   if (has_extra_normal) {
     extra_normal = mesh.getData<Real>("extra_normal", type, ghost_type)
                        .begin(spatial_dimension);
     extra_normal_begin = extra_normal;
   }
 
   //  Matrix<Real> local_coord(spatial_dimension, nb_nodes_per_element);
   for (UInt elem = 0; elem < nb_element; ++elem, ++x_it) {
     const Matrix<Real> & X = *x_it;
     Vector<Real> & J = *jacobians_it;
     Matrix<Real> R(nb_dofs, nb_dofs);
 
     if (has_extra_normal)
       ElementClass<type>::computeRotationMatrix(R, X, *extra_normal);
     else
       ElementClass<type>::computeRotationMatrix(R, X, Vector<Real>(X.rows()));
     // Extracting relevant lines
     auto x = (R.block(0, 0, spatial_dimension, spatial_dimension) * X)
                  .block(0, 0, ElementClass<type>::getNaturalSpaceDimension(),
                         ElementClass<type>::getNbNodesPerElement());
 
     computeJacobianOnQuadPointsByElement<type>(x, quad_points, J);
 
     if (filter_elements == empty_filter) {
       ++jacobians_it;
       ++extra_normal;
     } else {
       jacobians_it = jacobians_begin + filter_elements(elem);
       extra_normal = extra_normal_begin + filter_elements(elem);
     }
   }
 
   AKANTU_DEBUG_OUT();
 }
 #endif
 
 /* -------------------------------------------------------------------------- */
 #if defined(AKANTU_COHESIVE_ELEMENT)
 template <>
 template <ElementType type>
 void IntegratorGauss<_ek_cohesive, DefaultIntegrationOrderFunctor>::
     computeJacobiansOnIntegrationPoints(
         const Array<Real> & nodes, const Matrix<Real> & quad_points,
         Array<Real> & jacobians, const GhostType & ghost_type,
         const Array<UInt> & filter_elements) const {
   AKANTU_DEBUG_IN();
 
   UInt spatial_dimension = mesh.getSpatialDimension();
   UInt nb_nodes_per_element = Mesh::getNbNodesPerElement(type);
   UInt nb_quadrature_points = quad_points.cols();
 
   UInt nb_element = mesh.getNbElement(type, ghost_type);
 
   jacobians.resize(nb_element * nb_quadrature_points);
 
   auto jacobians_it =
       jacobians.begin_reinterpret(nb_quadrature_points, nb_element);
   auto jacobians_begin = jacobians_it;
 
   Vector<Real> weights = GaussIntegrationElement<type>::getWeights();
 
   Array<Real> x_el(0, spatial_dimension * nb_nodes_per_element);
   FEEngine::extractNodalToElementField(mesh, nodes, x_el, type, ghost_type,
                                        filter_elements);
 
   auto x_it = x_el.begin(spatial_dimension, nb_nodes_per_element);
 
   UInt nb_nodes_per_subelement = nb_nodes_per_element / 2;
   Matrix<Real> x(spatial_dimension, nb_nodes_per_subelement);
 
   nb_element = x_el.size();
 
   auto compute = [&](const auto & el) {
     Vector<Real> J(jacobians_begin[el]);
 
     for (UInt s = 0; s < spatial_dimension; ++s)
       for (UInt n = 0; n < nb_nodes_per_subelement; ++n)
         x(s, n) =
             ((*x_it)(s, n) + (*x_it)(s, n + nb_nodes_per_subelement)) * .5;
 
     if (type == _cohesive_1d_2)
       J(0) = 1;
     else
       this->computeJacobianOnQuadPointsByElement<type>(x, quad_points, J);
   };
 
   for_each_element(nb_element, filter_elements, compute);
   AKANTU_DEBUG_OUT();
 }
 #endif
 /* -------------------------------------------------------------------------- */
 template <ElementKind kind, class IntegrationOrderFunctor>
 template <ElementType type>
 void IntegratorGauss<kind, IntegrationOrderFunctor>::
     precomputeJacobiansOnQuadraturePoints(const Array<Real> & nodes,
                                           const GhostType & ghost_type) {
   AKANTU_DEBUG_IN();
 
   Array<Real> & jacobians_tmp = jacobians.alloc(0, 1, type, ghost_type);
 
   this->computeJacobiansOnIntegrationPoints<type>(
       nodes, quadrature_points(type, ghost_type), jacobians_tmp, ghost_type);
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <ElementKind kind, class IntegrationOrderFunctor>
 template <ElementType type, UInt polynomial_degree>
 void IntegratorGauss<kind, IntegrationOrderFunctor>::multiplyJacobiansByWeights(
     Array<Real> & jacobians) const {
   AKANTU_DEBUG_IN();
 
   UInt nb_quadrature_points =
       GaussIntegrationElement<type, polynomial_degree>::getNbQuadraturePoints();
   UInt nb_element = jacobians.size() / nb_quadrature_points;
 
   Vector<Real> weights =
       GaussIntegrationElement<type, polynomial_degree>::getWeights();
 
   auto jacobians_it =
       jacobians.begin_reinterpret(nb_quadrature_points, nb_element);
   auto jacobians_end =
       jacobians.end_reinterpret(nb_quadrature_points, nb_element);
 
   for (; jacobians_it != jacobians_end; ++jacobians_it) {
     Vector<Real> & J = *jacobians_it;
     J *= weights;
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <ElementKind kind, class IntegrationOrderFunctor>
 void IntegratorGauss<kind, IntegrationOrderFunctor>::integrate(
     const Array<Real> & in_f, Array<Real> & intf, UInt nb_degree_of_freedom,
     const Array<Real> & jacobians, UInt nb_element) const {
   AKANTU_DEBUG_IN();
 
   intf.resize(nb_element);
   if (nb_element == 0)
     return;
 
   UInt nb_points = jacobians.size() / nb_element;
 
   Array<Real>::const_matrix_iterator J_it;
   Array<Real>::matrix_iterator inte_it;
   Array<Real>::const_matrix_iterator f_it;
 
   f_it = in_f.begin_reinterpret(nb_degree_of_freedom, nb_points, nb_element);
   inte_it = intf.begin_reinterpret(nb_degree_of_freedom, 1, nb_element);
   J_it = jacobians.begin_reinterpret(nb_points, 1, nb_element);
 
   for (UInt el = 0; el < nb_element; ++el, ++J_it, ++f_it, ++inte_it) {
     const Matrix<Real> & f = *f_it;
     const Matrix<Real> & J = *J_it;
     Matrix<Real> & inte_f = *inte_it;
 
     inte_f.mul<false, false>(f, J);
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <ElementKind kind, class IntegrationOrderFunctor>
 template <ElementType type>
 void IntegratorGauss<kind, IntegrationOrderFunctor>::integrate(
     const Array<Real> & in_f, Array<Real> & intf, UInt nb_degree_of_freedom,
     const GhostType & ghost_type, const Array<UInt> & filter_elements) const {
   AKANTU_DEBUG_IN();
 
   AKANTU_DEBUG_ASSERT(jacobians.exists(type, ghost_type),
                       "No jacobians for the type "
                           << jacobians.printType(type, ghost_type));
 
   const Array<Real> & jac_loc = jacobians(type, ghost_type);
   if (filter_elements != empty_filter) {
     UInt nb_element = filter_elements.size();
     Array<Real> * filtered_J = new Array<Real>(0, jac_loc.getNbComponent());
     FEEngine::filterElementalData(mesh, jac_loc, *filtered_J, type, ghost_type,
                                   filter_elements);
     this->integrate(in_f, intf, nb_degree_of_freedom, *filtered_J, nb_element);
     delete filtered_J;
   } else {
     UInt nb_element = mesh.getNbElement(type, ghost_type);
     this->integrate(in_f, intf, nb_degree_of_freedom, jac_loc, nb_element);
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <ElementKind kind, class IntegrationOrderFunctor>
 template <ElementType type, UInt polynomial_degree>
 void IntegratorGauss<kind, IntegrationOrderFunctor>::integrate(
     const Array<Real> & in_f, Array<Real> & intf, UInt nb_degree_of_freedom,
     const GhostType & ghost_type) const {
   AKANTU_DEBUG_IN();
 
   Matrix<Real> quads = this->getIntegrationPoints<type, polynomial_degree>();
 
   Array<Real> jacobians;
   this->computeJacobiansOnIntegrationPoints<type>(mesh.getNodes(), quads,
                                                   jacobians, ghost_type);
   this->multiplyJacobiansByWeights<type, polynomial_degree>(jacobians);
 
   this->integrate(in_f, intf, nb_degree_of_freedom, jacobians,
                   mesh.getNbElement(type, ghost_type));
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <ElementKind kind, class IntegrationOrderFunctor>
 template <ElementType type, UInt polynomial_degree>
 Real IntegratorGauss<kind, IntegrationOrderFunctor>::integrate(
     const Array<Real> & in_f, const GhostType & ghost_type) const {
   AKANTU_DEBUG_IN();
 
   Array<Real> intfv(0, 1);
   integrate<type, polynomial_degree>(in_f, intfv, 1, ghost_type);
 
   Real res = Math::reduce(intfv);
 
   AKANTU_DEBUG_OUT();
   return res;
 }
 
 /* -------------------------------------------------------------------------- */
 template <ElementKind kind, class IntegrationOrderFunctor>
 template <ElementType type>
 Real IntegratorGauss<kind, IntegrationOrderFunctor>::integrate(
     const Array<Real> & in_f, const GhostType & ghost_type,
     const Array<UInt> & filter_elements) const {
   AKANTU_DEBUG_IN();
 
   AKANTU_DEBUG_ASSERT(jacobians.exists(type, ghost_type),
                       "No jacobians for the type "
                           << jacobians.printType(type, ghost_type));
 
   Array<Real> intfv(0, 1);
   integrate<type>(in_f, intfv, 1, ghost_type, filter_elements);
 
   Real res = Math::reduce(intfv);
 
   AKANTU_DEBUG_OUT();
   return res;
 }
 
 /* -------------------------------------------------------------------------- */
 template <ElementKind kind, class IntegrationOrderFunctor>
 void IntegratorGauss<kind, IntegrationOrderFunctor>::
     integrateOnIntegrationPoints(const Array<Real> & in_f, Array<Real> & intf,
                                  UInt nb_degree_of_freedom,
                                  const Array<Real> & jacobians,
                                  UInt nb_element) const {
   AKANTU_DEBUG_IN();
 
   UInt nb_points = jacobians.size() / nb_element;
 
   intf.resize(nb_element * nb_points);
 
   auto J_it = jacobians.begin();
   auto f_it = in_f.begin(nb_degree_of_freedom);
   auto inte_it = intf.begin(nb_degree_of_freedom);
 
   for (UInt el = 0; el < nb_element; ++el, ++J_it, ++f_it, ++inte_it) {
     const Real & J = *J_it;
     const Vector<Real> & f = *f_it;
     Vector<Real> & inte_f = *inte_it;
 
     inte_f = f;
     inte_f *= J;
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <ElementKind kind, class IntegrationOrderFunctor>
 template <ElementType type>
 void IntegratorGauss<kind, IntegrationOrderFunctor>::
     integrateOnIntegrationPoints(const Array<Real> & in_f, Array<Real> & intf,
                                  UInt nb_degree_of_freedom,
                                  const GhostType & ghost_type,
                                  const Array<UInt> & filter_elements) const {
   AKANTU_DEBUG_IN();
 
   AKANTU_DEBUG_ASSERT(jacobians.exists(type, ghost_type),
                       "No jacobians for the type "
                           << jacobians.printType(type, ghost_type));
 
   const Array<Real> & jac_loc = this->jacobians(type, ghost_type);
 
   if (filter_elements != empty_filter) {
 
     UInt nb_element = filter_elements.size();
     Array<Real> * filtered_J = new Array<Real>(0, jac_loc.getNbComponent());
     FEEngine::filterElementalData(mesh, jac_loc, *filtered_J, type, ghost_type,
                                   filter_elements);
 
     this->integrateOnIntegrationPoints(in_f, intf, nb_degree_of_freedom,
                                        *filtered_J, nb_element);
   } else {
     UInt nb_element = mesh.getNbElement(type, ghost_type);
     this->integrateOnIntegrationPoints(in_f, intf, nb_degree_of_freedom,
                                        jac_loc, nb_element);
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <ElementKind kind, class IntegrationOrderFunctor>
 void IntegratorGauss<kind, IntegrationOrderFunctor>::onElementsAdded(
     const Array<Element> & new_elements) {
 
   const auto & nodes = mesh.getNodes();
 
   for (auto elements_range : MeshElementsByTypes(new_elements)) {
     auto type = elements_range.getType();
     auto ghost_type = elements_range.getGhostType();
 
     if (mesh.getKind(type) != kind)
       continue;
 
     auto & elements = elements_range.getElements();
 
     if (not jacobians.exists(type, ghost_type))
       jacobians.alloc(0, 1, type, ghost_type);
 
     this->computeJacobiansOnIntegrationPoints(
         nodes, quadrature_points(type, ghost_type), jacobians(type, ghost_type),
         type, ghost_type, elements);
   }
 }
 
 /* -------------------------------------------------------------------------- */
 template <ElementKind kind, class IntegrationOrderFunctor>
 template <ElementType type>
 inline void IntegratorGauss<kind, IntegrationOrderFunctor>::initIntegrator(
     const Array<Real> & nodes, const GhostType & ghost_type) {
   computeQuadraturePoints<type>(ghost_type);
   precomputeJacobiansOnQuadraturePoints<type>(nodes, ghost_type);
   checkJacobians<type>(ghost_type);
   constexpr UInt polynomial_degree =
       IntegrationOrderFunctor::template getOrder<type>();
   multiplyJacobiansByWeights<type, polynomial_degree>(
       this->jacobians(type, ghost_type));
 }
 
 namespace integrator {
   namespace details {
     template <ElementKind kind> struct GaussIntegratorInitHelper {};
 
 #define INIT_INTEGRATOR(type)                                                  \
   _int.template initIntegrator<type>(nodes, ghost_type)
 
 #define AKANTU_GAUSS_INTERGRATOR_INIT_HELPER(kind)                             \
   template <> struct GaussIntegratorInitHelper<kind> {                         \
     template <ElementKind k, class IOF>                                        \
     static void call(IntegratorGauss<k, IOF> & _int,                           \
                      const Array<Real> & nodes, const ElementType & type,      \
                      const GhostType & ghost_type) {                           \
       AKANTU_BOOST_KIND_ELEMENT_SWITCH(INIT_INTEGRATOR, kind);                 \
     }                                                                          \
   };
 
     AKANTU_BOOST_ALL_KIND(AKANTU_GAUSS_INTERGRATOR_INIT_HELPER)
 
 #undef AKANTU_GAUSS_INTERGRATOR_INIT_HELPER
 #undef INIT_INTEGRATOR
   } // namespace details
 } // namespace integrator
 
 template <ElementKind kind, class IntegrationOrderFunctor>
 inline void IntegratorGauss<kind, IntegrationOrderFunctor>::initIntegrator(
     const Array<Real> & nodes, const ElementType & type,
     const GhostType & ghost_type) {
   integrator::details::GaussIntegratorInitHelper<kind>::call(*this, nodes, type,
                                                              ghost_type);
 }
 
 namespace integrator {
   namespace details {
     template <ElementKind kind> struct GaussIntegratorComputeJacobiansHelper {};
 
 #define AKANTU_COMPUTE_JACOBIANS(type)                                         \
   _int.template computeJacobiansOnIntegrationPoints<type>(                     \
       nodes, quad_points, jacobians, ghost_type, filter_elements);
 
 #define AKANTU_GAUSS_INTERGRATOR_COMPUTE_JACOBIANS(kind)                       \
   template <> struct GaussIntegratorComputeJacobiansHelper<kind> {             \
     template <ElementKind k, class IOF>                                        \
     static void                                                                \
     call(const IntegratorGauss<k, IOF> & _int, const Array<Real> & nodes,      \
          const Matrix<Real> & quad_points, Array<Real> & jacobians,            \
          const ElementType & type, const GhostType & ghost_type,               \
          const Array<UInt> & filter_elements) {                                \
       AKANTU_BOOST_KIND_ELEMENT_SWITCH(AKANTU_COMPUTE_JACOBIANS, kind);        \
     }                                                                          \
   };
 
     AKANTU_BOOST_ALL_KIND(AKANTU_GAUSS_INTERGRATOR_COMPUTE_JACOBIANS)
 
 #undef AKANTU_GAUSS_INTERGRATOR_COMPUTE_JACOBIANS
 #undef AKANTU_COMPUTE_JACOBIANS
   } // namespace details
 } // namespace integrator
 
 template <ElementKind kind, class IntegrationOrderFunctor>
 void IntegratorGauss<kind, IntegrationOrderFunctor>::
     computeJacobiansOnIntegrationPoints(
         const Array<Real> & nodes, const Matrix<Real> & quad_points,
         Array<Real> & jacobians, const ElementType & type,
         const GhostType & ghost_type,
         const Array<UInt> & filter_elements) const {
   integrator::details::GaussIntegratorComputeJacobiansHelper<kind>::call(
       *this, nodes, quad_points, jacobians, type, ghost_type, filter_elements);
 }
 
 } // namespace akantu
diff --git a/src/fe_engine/interpolation_element_tmpl.hh b/src/fe_engine/interpolation_element_tmpl.hh
index 9507deb58..febbb6ddd 100644
--- a/src/fe_engine/interpolation_element_tmpl.hh
+++ b/src/fe_engine/interpolation_element_tmpl.hh
@@ -1,73 +1,73 @@
 /**
  * @file   interpolation_element_tmpl.hh
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Thu Jun 06 2013
- * @date last modification: Tue Apr 07 2015
+ * @date last modification: Wed Nov 29 2017
  *
  * @brief  interpolation property description
  *
  * @section LICENSE
  *
- * Copyright  (©)  2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de Lausanne)
+ * 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
+ * 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
+ * A PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 #include "element_class.hh"
 /* -------------------------------------------------------------------------- */
 
 #ifndef __AKANTU_INTERPOLATION_ELEMENT_TMPL_HH__
 #define __AKANTU_INTERPOLATION_ELEMENT_TMPL_HH__
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 /* Regular Elements                                                           */
 /* -------------------------------------------------------------------------- */
 AKANTU_DEFINE_INTERPOLATION_TYPE_PROPERTY(_itp_not_defined, _itk_not_defined, 0,
                                           0);
 AKANTU_DEFINE_INTERPOLATION_TYPE_PROPERTY(_itp_lagrange_point_1,
                                           _itk_lagrangian, 1, 0);
 AKANTU_DEFINE_INTERPOLATION_TYPE_PROPERTY(_itp_lagrange_segment_2,
                                           _itk_lagrangian, 2, 1);
 AKANTU_DEFINE_INTERPOLATION_TYPE_PROPERTY(_itp_lagrange_segment_3,
                                           _itk_lagrangian, 3, 1);
 AKANTU_DEFINE_INTERPOLATION_TYPE_PROPERTY(_itp_lagrange_triangle_3,
                                           _itk_lagrangian, 3, 2);
 AKANTU_DEFINE_INTERPOLATION_TYPE_PROPERTY(_itp_lagrange_triangle_6,
                                           _itk_lagrangian, 6, 2);
 AKANTU_DEFINE_INTERPOLATION_TYPE_PROPERTY(_itp_lagrange_tetrahedron_4,
                                           _itk_lagrangian, 4, 3);
 AKANTU_DEFINE_INTERPOLATION_TYPE_PROPERTY(_itp_lagrange_tetrahedron_10,
                                           _itk_lagrangian, 10, 3);
 AKANTU_DEFINE_INTERPOLATION_TYPE_PROPERTY(_itp_lagrange_quadrangle_4,
                                           _itk_lagrangian, 4, 2);
 AKANTU_DEFINE_INTERPOLATION_TYPE_PROPERTY(_itp_serendip_quadrangle_8,
                                           _itk_lagrangian, 8, 2);
 AKANTU_DEFINE_INTERPOLATION_TYPE_PROPERTY(_itp_lagrange_hexahedron_8,
                                           _itk_lagrangian, 8, 3);
 AKANTU_DEFINE_INTERPOLATION_TYPE_PROPERTY(_itp_serendip_hexahedron_20,
                                           _itk_lagrangian, 20, 3);
 AKANTU_DEFINE_INTERPOLATION_TYPE_PROPERTY(_itp_lagrange_pentahedron_6,
                                           _itk_lagrangian, 6, 3);
 AKANTU_DEFINE_INTERPOLATION_TYPE_PROPERTY(_itp_lagrange_pentahedron_15,
                                           _itk_lagrangian, 15, 3);
 
 } // akantu
 #endif /* __AKANTU_INTERPOLATION_ELEMENT_TMPL_HH__ */
diff --git a/src/fe_engine/shape_cohesive.hh b/src/fe_engine/shape_cohesive.hh
index 96e0867e9..45c4bfd40 100644
--- a/src/fe_engine/shape_cohesive.hh
+++ b/src/fe_engine/shape_cohesive.hh
@@ -1,183 +1,182 @@
 /**
  * @file   shape_cohesive.hh
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  * @author Marco Vocialta <marco.vocialta@epfl.ch>
  *
  * @date creation: Tue Feb 15 2011
- * @date last modification: Thu Oct 22 2015
+ * @date last modification: Tue Feb 20 2018
  *
  * @brief  shape functions for cohesive elements description
  *
  * @section LICENSE
  *
- * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
- * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
- * Solides)
+ * 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
+ * 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
+ * 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_array.hh"
 #include "shape_lagrange.hh"
 /* -------------------------------------------------------------------------- */
 
 #ifndef __AKANTU_SHAPE_COHESIVE_HH__
 #define __AKANTU_SHAPE_COHESIVE_HH__
 
 namespace akantu {
 
 struct CohesiveReduceFunctionMean {
   inline Real operator()(Real u_plus, Real u_minus) {
     return .5 * (u_plus + u_minus);
   }
 };
 
 struct CohesiveReduceFunctionOpening {
   inline Real operator()(Real u_plus, Real u_minus) {
     return (u_plus - u_minus);
   }
 };
 
 template <> class ShapeLagrange<_ek_cohesive> : public ShapeLagrangeBase {
   /* ------------------------------------------------------------------------ */
   /* Constructors/Destructors                                                 */
   /* ------------------------------------------------------------------------ */
 public:
   ShapeLagrange(const Mesh & mesh, const ID & id = "shape_cohesive",
                 const MemoryID & memory_id = 0);
 
   ~ShapeLagrange() override = default;
 
   /* ------------------------------------------------------------------------ */
   /* Methods                                                                  */
   /* ------------------------------------------------------------------------ */
 public:
   inline void initShapeFunctions(const Array<Real> & nodes,
                                  const Matrix<Real> & integration_points,
                                  const ElementType & type,
                                  const GhostType & ghost_type);
 
   /// extract the nodal values and store them per element
   template <ElementType type, class ReduceFunction>
   void extractNodalToElementField(
       const Array<Real> & nodal_f, Array<Real> & elemental_f,
       const GhostType & ghost_type = _not_ghost,
       const Array<UInt> & filter_elements = empty_filter) const;
 
   /// computes the shape functions derivatives for given interpolation points
   template <ElementType type>
   void computeShapeDerivativesOnIntegrationPoints(
       const Array<Real> & nodes, const Matrix<Real> & integration_points,
       Array<Real> & shape_derivatives, const GhostType & ghost_type,
       const Array<UInt> & filter_elements = empty_filter) const;
 
   void computeShapeDerivativesOnIntegrationPoints(
       const Array<Real> & nodes, const Matrix<Real> & integration_points,
       Array<Real> & shape_derivatives, const ElementType & type,
       const GhostType & ghost_type,
       const Array<UInt> & filter_elements) const override;
 
   /// pre compute all shapes on the element integration points from natural
   /// coordinates
   template <ElementType type>
   void precomputeShapesOnIntegrationPoints(const Array<Real> & nodes,
                                            GhostType ghost_type);
 
   /// pre compute all shape derivatives on the element integration points from
   /// natural coordinates
   template <ElementType type>
   void precomputeShapeDerivativesOnIntegrationPoints(const Array<Real> & nodes,
                                                      GhostType ghost_type);
 
   /// interpolate nodal values on the integration points
   template <ElementType type, class ReduceFunction>
   void interpolateOnIntegrationPoints(
       const Array<Real> & u, Array<Real> & uq, UInt nb_degree_of_freedom,
       const GhostType ghost_type = _not_ghost,
       const Array<UInt> & filter_elements = empty_filter) const;
 
   template <ElementType type>
   void interpolateOnIntegrationPoints(
       const Array<Real> & u, Array<Real> & uq, UInt nb_degree_of_freedom,
       const GhostType ghost_type = _not_ghost,
       const Array<UInt> & filter_elements = empty_filter) const {
     interpolateOnIntegrationPoints<type, CohesiveReduceFunctionMean>(
         u, uq, nb_degree_of_freedom, ghost_type, filter_elements);
   }
 
   /// compute the gradient of u on the integration points in the natural
   /// coordinates
   template <ElementType type>
   void gradientOnIntegrationPoints(
       const Array<Real> & u, Array<Real> & nablauq, UInt nb_degree_of_freedom,
       GhostType ghost_type = _not_ghost,
       const Array<UInt> & filter_elements = empty_filter) const {
     variationOnIntegrationPoints<type, CohesiveReduceFunctionMean>(
         u, nablauq, nb_degree_of_freedom, ghost_type, filter_elements);
   }
 
   template <ElementType type>
   void computeBtD(const Array<Real> & /*Ds*/, Array<Real> & /*BtDs*/,
                   GhostType /*ghost_type*/,
                   const Array<UInt> & /*filter_elements*/) const {
     AKANTU_TO_IMPLEMENT();
   }
 
   template <ElementType type>
   void computeBtDB(const Array<Real> & /*Ds*/, Array<Real> & /*BtDBs*/,
                    UInt /*order_d*/, GhostType /*ghost_type*/,
                    const Array<UInt> & /*filter_elements*/) const {
     AKANTU_TO_IMPLEMENT();
   }
 
   /// compute the gradient of u on the integration points
   template <ElementType type, class ReduceFunction>
   void variationOnIntegrationPoints(
       const Array<Real> & u, Array<Real> & nablauq, UInt nb_degree_of_freedom,
       GhostType ghost_type = _not_ghost,
       const Array<UInt> & filter_elements = empty_filter) const;
 
   /// compute the normals to the field u on integration points
   template <ElementType type, class ReduceFunction>
   void computeNormalsOnIntegrationPoints(
       const Array<Real> & u, Array<Real> & normals_u,
       GhostType ghost_type = _not_ghost,
       const Array<UInt> & filter_elements = empty_filter) const;
 
   /// multiply a field by shape functions
   template <ElementType type>
   void fieldTimesShapes(__attribute__((unused)) const Array<Real> & field,
                         __attribute__((unused))
                         Array<Real> & fiedl_times_shapes,
                         __attribute__((unused)) GhostType ghost_type) const {
     AKANTU_TO_IMPLEMENT();
   }
 };
 
 /// standard output stream operator
 template <class ShapeFunction>
 inline std::ostream & operator<<(std::ostream & stream,
                                  const ShapeCohesive<ShapeFunction> & _this) {
   _this.printself(stream);
   return stream;
 }
 
 } // namespace akantu
 
 #include "shape_cohesive_inline_impl.cc"
 
 #endif /* __AKANTU_SHAPE_COHESIVE_HH__ */
diff --git a/src/fe_engine/shape_cohesive_inline_impl.cc b/src/fe_engine/shape_cohesive_inline_impl.cc
index df81e9a8f..ad02dbffc 100644
--- a/src/fe_engine/shape_cohesive_inline_impl.cc
+++ b/src/fe_engine/shape_cohesive_inline_impl.cc
@@ -1,328 +1,328 @@
 /**
  * @file   shape_cohesive_inline_impl.cc
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  * @author Marco Vocialta <marco.vocialta@epfl.ch>
  *
  * @date creation: Fri Feb 03 2012
- * @date last modification: Thu Oct 15 2015
+ * @date last modification: Mon Feb 19 2018
  *
  * @brief  ShapeCohesive inline implementation
  *
  * @section LICENSE
  *
- * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
- * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
- * Solides)
+ * 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
+ * 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
+ * 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 "shape_cohesive.hh"
 /* -------------------------------------------------------------------------- */
 
 #ifndef __AKANTU_SHAPE_COHESIVE_INLINE_IMPL_CC__
 #define __AKANTU_SHAPE_COHESIVE_INLINE_IMPL_CC__
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 inline ShapeLagrange<_ek_cohesive>::ShapeLagrange(const Mesh & mesh,
                                                   const ID & id,
                                                   const MemoryID & memory_id)
     : ShapeLagrangeBase(mesh, _ek_cohesive, id, memory_id) {}
 
 #define INIT_SHAPE_FUNCTIONS(type)                                             \
   setIntegrationPointsByType<type>(integration_points, ghost_type);            \
   precomputeShapesOnIntegrationPoints<type>(nodes, ghost_type);                \
   precomputeShapeDerivativesOnIntegrationPoints<type>(nodes, ghost_type);
 
 /* -------------------------------------------------------------------------- */
 inline void ShapeLagrange<_ek_cohesive>::initShapeFunctions(
     const Array<Real> & nodes, const Matrix<Real> & integration_points,
     const ElementType & type, const GhostType & ghost_type) {
   AKANTU_BOOST_COHESIVE_ELEMENT_SWITCH(INIT_SHAPE_FUNCTIONS);
 }
 
 /* -------------------------------------------------------------------------- */
 
 /* -------------------------------------------------------------------------- */
 template <ElementType type>
 void ShapeLagrange<_ek_cohesive>::computeShapeDerivativesOnIntegrationPoints(
     const Array<Real> &, const Matrix<Real> & integration_points,
     Array<Real> & shape_derivatives, const GhostType & ghost_type,
     const Array<UInt> & filter_elements) const {
   AKANTU_DEBUG_IN();
 
   UInt size_of_shapesd = ElementClass<type>::getShapeDerivativesSize();
   UInt spatial_dimension = ElementClass<type>::getNaturalSpaceDimension();
   UInt nb_nodes_per_element =
       ElementClass<type>::getNbNodesPerInterpolationElement();
 
   UInt nb_points = integration_points.cols();
   UInt nb_element = mesh.getConnectivity(type, ghost_type).size();
 
   AKANTU_DEBUG_ASSERT(shape_derivatives.getNbComponent() == size_of_shapesd,
                       "The shapes_derivatives array does not have the correct "
                           << "number of component");
 
   shape_derivatives.resize(nb_element * nb_points);
   Real * shapesd_val = shape_derivatives.storage();
 
   auto compute = [&](const auto & el) {
     auto ptr = shapesd_val + el * nb_points * size_of_shapesd;
     Tensor3<Real> B(ptr, spatial_dimension, nb_nodes_per_element, nb_points);
     ElementClass<type>::computeDNDS(integration_points, B);
   };
 
   for_each_element(nb_element, filter_elements, compute);
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 inline void
 ShapeLagrange<_ek_cohesive>::computeShapeDerivativesOnIntegrationPoints(
     const Array<Real> & nodes, const Matrix<Real> & integration_points,
     Array<Real> & shape_derivatives, const ElementType & type,
     const GhostType & ghost_type, const Array<UInt> & filter_elements) const {
 #define AKANTU_COMPUTE_SHAPES(type)                                            \
   computeShapeDerivativesOnIntegrationPoints<type>(                            \
       nodes, integration_points, shape_derivatives, ghost_type,                \
       filter_elements);
 
   AKANTU_BOOST_COHESIVE_ELEMENT_SWITCH(AKANTU_COMPUTE_SHAPES);
 
 #undef AKANTU_COMPUTE_SHAPES
 }
 
 /* -------------------------------------------------------------------------- */
 template <ElementType type>
 void ShapeLagrange<_ek_cohesive>::precomputeShapesOnIntegrationPoints(
     const Array<Real> & nodes, GhostType ghost_type) {
   AKANTU_DEBUG_IN();
 
   InterpolationType itp_type = ElementClassProperty<type>::interpolation_type;
   Matrix<Real> & natural_coords = integration_points(type, ghost_type);
   UInt size_of_shapes = ElementClass<type>::getShapeSize();
 
   Array<Real> & shapes_tmp =
       shapes.alloc(0, size_of_shapes, itp_type, ghost_type);
 
   this->computeShapesOnIntegrationPoints<type>(nodes, natural_coords,
                                                shapes_tmp, ghost_type);
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <ElementType type>
 void ShapeLagrange<_ek_cohesive>::precomputeShapeDerivativesOnIntegrationPoints(
     const Array<Real> & nodes, GhostType ghost_type) {
   AKANTU_DEBUG_IN();
 
   InterpolationType itp_type = ElementClassProperty<type>::interpolation_type;
   Matrix<Real> & natural_coords = integration_points(type, ghost_type);
   UInt size_of_shapesd = ElementClass<type>::getShapeDerivativesSize();
 
   Array<Real> & shapes_derivatives_tmp =
       shapes_derivatives.alloc(0, size_of_shapesd, itp_type, ghost_type);
 
   this->computeShapeDerivativesOnIntegrationPoints<type>(
       nodes, natural_coords, shapes_derivatives_tmp, ghost_type);
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <ElementType type, class ReduceFunction>
 void ShapeLagrange<_ek_cohesive>::extractNodalToElementField(
     const Array<Real> & nodal_f, Array<Real> & elemental_f,
     const GhostType & ghost_type, const Array<UInt> & filter_elements) const {
   AKANTU_DEBUG_IN();
 
   UInt nb_nodes_per_itp_element =
       ElementClass<type>::getNbNodesPerInterpolationElement();
   UInt nb_degree_of_freedom = nodal_f.getNbComponent();
   UInt nb_element = this->mesh.getNbElement(type, ghost_type);
 
   const auto & conn_array = this->mesh.getConnectivity(type, ghost_type);
   auto conn = conn_array.begin(conn_array.getNbComponent() / 2, 2);
 
   if (filter_elements != empty_filter) {
     nb_element = filter_elements.size();
   }
 
   elemental_f.resize(nb_element);
 
   Array<Real>::matrix_iterator u_it =
       elemental_f.begin(nb_degree_of_freedom, nb_nodes_per_itp_element);
 
   ReduceFunction reduce_function;
 
   auto compute = [&](const auto & el) {
     Matrix<Real> & u = *u_it;
     Matrix<UInt> el_conn(conn[el]);
 
     // compute the average/difference of the nodal field loaded from cohesive
     // element
     for (UInt n = 0; n < el_conn.rows(); ++n) {
       UInt node_plus = el_conn(n, 0);
       UInt node_minus = el_conn(n, 1);
       for (UInt d = 0; d < nb_degree_of_freedom; ++d) {
         Real u_plus = nodal_f(node_plus, d);
         Real u_minus = nodal_f(node_minus, d);
         u(d, n) = reduce_function(u_plus, u_minus);
       }
     }
 
     ++u_it;
   };
 
   for_each_element(nb_element, filter_elements, compute);
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <ElementType type, class ReduceFunction>
 void ShapeLagrange<_ek_cohesive>::interpolateOnIntegrationPoints(
     const Array<Real> & in_u, Array<Real> & out_uq, UInt nb_degree_of_freedom,
     GhostType ghost_type, const Array<UInt> & filter_elements) const {
   AKANTU_DEBUG_IN();
 
   InterpolationType itp_type = ElementClassProperty<type>::interpolation_type;
 
   AKANTU_DEBUG_ASSERT(this->shapes.exists(itp_type, ghost_type),
                       "No shapes for the type "
                           << this->shapes.printType(itp_type, ghost_type));
 
   UInt nb_nodes_per_element =
       ElementClass<type>::getNbNodesPerInterpolationElement();
   Array<Real> u_el(0, nb_degree_of_freedom * nb_nodes_per_element);
   this->extractNodalToElementField<type, ReduceFunction>(in_u, u_el, ghost_type,
                                                          filter_elements);
 
   this->template interpolateElementalFieldOnIntegrationPoints<type>(
       u_el, out_uq, ghost_type, shapes(itp_type, ghost_type), filter_elements);
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <ElementType type, class ReduceFunction>
 void ShapeLagrange<_ek_cohesive>::variationOnIntegrationPoints(
     const Array<Real> & in_u, Array<Real> & nablauq, UInt nb_degree_of_freedom,
     GhostType ghost_type, const Array<UInt> & filter_elements) const {
   AKANTU_DEBUG_IN();
 
   InterpolationType itp_type = ElementClassProperty<type>::interpolation_type;
 
   AKANTU_DEBUG_ASSERT(
       this->shapes_derivatives.exists(itp_type, ghost_type),
       "No shapes for the type "
           << this->shapes_derivatives.printType(itp_type, ghost_type));
 
   UInt nb_nodes_per_element =
       ElementClass<type>::getNbNodesPerInterpolationElement();
   Array<Real> u_el(0, nb_degree_of_freedom * nb_nodes_per_element);
   this->extractNodalToElementField<type, ReduceFunction>(in_u, u_el, ghost_type,
                                                          filter_elements);
 
   this->template gradientElementalFieldOnIntegrationPoints<type>(
       u_el, nablauq, ghost_type, shapes_derivatives(itp_type, ghost_type),
       filter_elements);
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <ElementType type, class ReduceFunction>
 void ShapeLagrange<_ek_cohesive>::computeNormalsOnIntegrationPoints(
     const Array<Real> & u, Array<Real> & normals_u, GhostType ghost_type,
     const Array<UInt> & filter_elements) const {
   AKANTU_DEBUG_IN();
 
   UInt nb_element = this->mesh.getNbElement(type, ghost_type);
   UInt nb_points = this->integration_points(type, ghost_type).cols();
   UInt spatial_dimension = this->mesh.getSpatialDimension();
 
   if (filter_elements != empty_filter)
     nb_element = filter_elements.size();
 
   normals_u.resize(nb_points * nb_element);
 
   Array<Real> tangents_u(0, (spatial_dimension * (spatial_dimension - 1)));
 
   if (spatial_dimension > 1) {
     tangents_u.resize(nb_element * nb_points);
     this->template variationOnIntegrationPoints<type, ReduceFunction>(
         u, tangents_u, spatial_dimension, ghost_type, filter_elements);
   }
 
   Real * tangent = tangents_u.storage();
 
   if (spatial_dimension == 3) {
     for (auto & normal : make_view(normals_u, spatial_dimension)) {
       Math::vectorProduct3(tangent, tangent + spatial_dimension,
                            normal.storage());
 
       normal /= normal.norm();
       tangent += spatial_dimension * 2;
     }
   } else if (spatial_dimension == 2) {
     for (auto & normal : make_view(normals_u, spatial_dimension)) {
       Vector<Real> a1(tangent, spatial_dimension);
 
       normal(0) = -a1(1);
       normal(1) = a1(0);
       normal.normalize();
 
       tangent += spatial_dimension;
     }
   } else if (spatial_dimension == 1) {
     const auto facet_type = Mesh::getFacetType(type);
     const auto & mesh_facets = mesh.getMeshFacets();
     const auto & facets = mesh_facets.getSubelementToElement(type, ghost_type);
     const auto & segments =
         mesh_facets.getElementToSubelement(facet_type, ghost_type);
 
     Real values[2];
 
     for (auto el : arange(nb_element)) {
       if (filter_elements != empty_filter)
         el = filter_elements(el);
 
       for (UInt p = 0; p < 2; ++p) {
         Element facet = facets(el, p);
         Element segment = segments(facet.element)[0];
         Vector<Real> barycenter(values + p, 1);
         mesh.getBarycenter(segment, barycenter);
       }
 
       Real difference = values[0] - values[1];
 
       AKANTU_DEBUG_ASSERT(difference != 0.,
                           "Error in normal computation for cohesive elements");
 
       normals_u(el) = difference / std::abs(difference);
     }
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 } // namespace akantu
 #endif /* __AKANTU_SHAPE_COHESIVE_INLINE_IMPL_CC__ */
diff --git a/src/fe_engine/shape_functions.cc b/src/fe_engine/shape_functions.cc
index 15d67f780..b45c222a9 100644
--- a/src/fe_engine/shape_functions.cc
+++ b/src/fe_engine/shape_functions.cc
@@ -1,243 +1,245 @@
 /**
  * @file   shape_functions.cc
  *
- * @author Nicolas Richart
+ * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
- * @date creation  Thu Jul 27 2017
+ * @date creation: Wed Aug 09 2017
+ * @date last modification: Wed Oct 11 2017
  *
- * @brief implementation of th shape functions interface
+ * @brief  implementation of th shape functions interface
  *
  * @section LICENSE
  *
- * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * 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
+ * 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
+ * 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 "shape_functions.hh"
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 ShapeFunctions::ShapeFunctions(const Mesh & mesh, const ID & id,
                                const MemoryID & memory_id)
     : Memory(id, memory_id), shapes("shapes_generic", id, memory_id),
       shapes_derivatives("shapes_derivatives_generic", id, memory_id),
       mesh(mesh) {}
 
 /* -------------------------------------------------------------------------- */
 template <ElementType type>
 inline void
 ShapeFunctions::initElementalFieldInterpolationFromIntegrationPoints(
     const Array<Real> & interpolation_points_coordinates,
     ElementTypeMapArray<Real> & interpolation_points_coordinates_matrices,
     ElementTypeMapArray<Real> & quad_points_coordinates_inv_matrices,
     const Array<Real> & quadrature_points_coordinates,
     const GhostType & ghost_type, const Array<UInt> & element_filter) const {
 
   AKANTU_DEBUG_IN();
 
   UInt spatial_dimension = this->mesh.getSpatialDimension();
   UInt nb_element = this->mesh.getNbElement(type, ghost_type);
   UInt nb_element_filter;
 
   if (element_filter == empty_filter)
     nb_element_filter = nb_element;
   else
     nb_element_filter = element_filter.size();
 
   UInt nb_quad_per_element =
       GaussIntegrationElement<type>::getNbQuadraturePoints();
   UInt nb_interpolation_points_per_elem =
       interpolation_points_coordinates.size() / nb_element;
 
   AKANTU_DEBUG_ASSERT(interpolation_points_coordinates.size() % nb_element == 0,
                       "Number of interpolation points should be a multiple of "
                       "total number of elements");
 
   if (!quad_points_coordinates_inv_matrices.exists(type, ghost_type))
     quad_points_coordinates_inv_matrices.alloc(
         nb_element_filter, nb_quad_per_element * nb_quad_per_element, type,
         ghost_type);
   else
     quad_points_coordinates_inv_matrices(type, ghost_type)
         .resize(nb_element_filter);
 
   if (!interpolation_points_coordinates_matrices.exists(type, ghost_type))
     interpolation_points_coordinates_matrices.alloc(
         nb_element_filter,
         nb_interpolation_points_per_elem * nb_quad_per_element, type,
         ghost_type);
   else
     interpolation_points_coordinates_matrices(type, ghost_type)
         .resize(nb_element_filter);
 
   Array<Real> & quad_inv_mat =
       quad_points_coordinates_inv_matrices(type, ghost_type);
   Array<Real> & interp_points_mat =
       interpolation_points_coordinates_matrices(type, ghost_type);
 
   Matrix<Real> quad_coord_matrix(nb_quad_per_element, nb_quad_per_element);
 
   Array<Real>::const_matrix_iterator quad_coords_it =
       quadrature_points_coordinates.begin_reinterpret(
           spatial_dimension, nb_quad_per_element, nb_element_filter);
 
   Array<Real>::const_matrix_iterator points_coords_begin =
       interpolation_points_coordinates.begin_reinterpret(
           spatial_dimension, nb_interpolation_points_per_elem, nb_element);
 
   Array<Real>::matrix_iterator inv_quad_coord_it =
       quad_inv_mat.begin(nb_quad_per_element, nb_quad_per_element);
 
   Array<Real>::matrix_iterator int_points_mat_it = interp_points_mat.begin(
       nb_interpolation_points_per_elem, nb_quad_per_element);
 
   /// loop over the elements of the current material and element type
   for (UInt el = 0; el < nb_element_filter;
        ++el, ++inv_quad_coord_it, ++int_points_mat_it, ++quad_coords_it) {
     /// matrix containing the quadrature points coordinates
     const Matrix<Real> & quad_coords = *quad_coords_it;
     /// matrix to store the matrix inversion result
     Matrix<Real> & inv_quad_coord_matrix = *inv_quad_coord_it;
 
     /// insert the quad coordinates in a matrix compatible with the
     /// interpolation
     buildElementalFieldInterpolationMatrix<type>(quad_coords,
                                                  quad_coord_matrix);
 
     /// invert the interpolation matrix
     inv_quad_coord_matrix.inverse(quad_coord_matrix);
 
     /// matrix containing the interpolation points coordinates
     const Matrix<Real> & points_coords =
         points_coords_begin[element_filter(el)];
     /// matrix to store the interpolation points coordinates
     /// compatible with these functions
     Matrix<Real> & inv_points_coord_matrix = *int_points_mat_it;
 
     /// insert the quad coordinates in a matrix compatible with the
     /// interpolation
     buildElementalFieldInterpolationMatrix<type>(points_coords,
                                                  inv_points_coord_matrix);
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void ShapeFunctions::initElementalFieldInterpolationFromIntegrationPoints(
     const ElementTypeMapArray<Real> & interpolation_points_coordinates,
     ElementTypeMapArray<Real> & interpolation_points_coordinates_matrices,
     ElementTypeMapArray<Real> & quad_points_coordinates_inv_matrices,
     const ElementTypeMapArray<Real> & quadrature_points_coordinates,
     const ElementTypeMapArray<UInt> * element_filter) const {
 
   AKANTU_DEBUG_IN();
 
   UInt spatial_dimension = this->mesh.getSpatialDimension();
 
   for (auto ghost_type : ghost_types) {
     Mesh::type_iterator it, last;
     if (element_filter) {
       it = element_filter->firstType(spatial_dimension, ghost_type);
       last = element_filter->lastType(spatial_dimension, ghost_type);
     } else {
       it = mesh.firstType(spatial_dimension, ghost_type);
       last = mesh.lastType(spatial_dimension, ghost_type);
     }
     for (; it != last; ++it) {
 
       ElementType type = *it;
       UInt nb_element = mesh.getNbElement(type, ghost_type);
       if (nb_element == 0)
         continue;
 
       const Array<UInt> * elem_filter;
       if (element_filter)
         elem_filter = &((*element_filter)(type, ghost_type));
       else
         elem_filter = &(empty_filter);
 
 #define AKANTU_INIT_ELEMENTAL_FIELD_INTERPOLATION_FROM_C_POINTS(type)          \
   this->initElementalFieldInterpolationFromIntegrationPoints<type>(            \
       interpolation_points_coordinates(type, ghost_type),                      \
       interpolation_points_coordinates_matrices,                               \
       quad_points_coordinates_inv_matrices,                                    \
       quadrature_points_coordinates(type, ghost_type), ghost_type,             \
       *elem_filter)
 
       AKANTU_BOOST_REGULAR_ELEMENT_SWITCH(
           AKANTU_INIT_ELEMENTAL_FIELD_INTERPOLATION_FROM_C_POINTS);
 #undef AKANTU_INIT_ELEMENTAL_FIELD_INTERPOLATION_FROM_C_POINTS
     }
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void ShapeFunctions::interpolateElementalFieldFromIntegrationPoints(
     const ElementTypeMapArray<Real> & field,
     const ElementTypeMapArray<Real> & interpolation_points_coordinates_matrices,
     const ElementTypeMapArray<Real> & quad_points_coordinates_inv_matrices,
     ElementTypeMapArray<Real> & result, const GhostType & ghost_type,
     const ElementTypeMapArray<UInt> * element_filter) const {
 
   AKANTU_DEBUG_IN();
 
   UInt spatial_dimension = this->mesh.getSpatialDimension();
 
   Mesh::type_iterator it, last;
 
   if (element_filter) {
     it = element_filter->firstType(spatial_dimension, ghost_type);
     last = element_filter->lastType(spatial_dimension, ghost_type);
   } else {
     it = mesh.firstType(spatial_dimension, ghost_type);
     last = mesh.lastType(spatial_dimension, ghost_type);
   }
 
   for (; it != last; ++it) {
 
     ElementType type = *it;
     UInt nb_element = mesh.getNbElement(type, ghost_type);
     if (nb_element == 0)
       continue;
 
     const Array<UInt> * elem_filter;
     if (element_filter)
       elem_filter = &((*element_filter)(type, ghost_type));
     else
       elem_filter = &(empty_filter);
 
 #define AKANTU_INTERPOLATE_ELEMENTAL_FIELD_FROM_C_POINTS(type)                 \
   interpolateElementalFieldFromIntegrationPoints<type>(                        \
       field(type, ghost_type),                                                 \
       interpolation_points_coordinates_matrices(type, ghost_type),             \
       quad_points_coordinates_inv_matrices(type, ghost_type), result,          \
       ghost_type, *elem_filter)
 
     AKANTU_BOOST_REGULAR_ELEMENT_SWITCH(
         AKANTU_INTERPOLATE_ELEMENTAL_FIELD_FROM_C_POINTS);
 #undef AKANTU_INTERPOLATE_ELEMENTAL_FIELD_FROM_C_POINTS
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 } // namespace akantu
diff --git a/src/fe_engine/shape_functions.hh b/src/fe_engine/shape_functions.hh
index 8d2626a4a..1780f87b8 100644
--- a/src/fe_engine/shape_functions.hh
+++ b/src/fe_engine/shape_functions.hh
@@ -1,215 +1,214 @@
 /**
  * @file   shape_functions.hh
  *
  * @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Fri Jun 18 2010
- * @date last modification: Thu Oct 22 2015
+ * @date last modification: Tue Feb 20 2018
  *
  * @brief  shape function class
  *
  * @section LICENSE
  *
- * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
- * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
- * Solides)
+ * 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
+ * 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
+ * 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_memory.hh"
 #include "mesh.hh"
 
 /* -------------------------------------------------------------------------- */
 
 #ifndef __AKANTU_SHAPE_FUNCTIONS_HH__
 #define __AKANTU_SHAPE_FUNCTIONS_HH__
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 class ShapeFunctions : protected Memory {
   /* ------------------------------------------------------------------------ */
   /* Constructors/Destructors                                                 */
   /* ------------------------------------------------------------------------ */
 public:
   ShapeFunctions(const Mesh & mesh, const ID & id = "shape",
                  const MemoryID & memory_id = 0);
   ~ShapeFunctions() override = default;
 
   /* ------------------------------------------------------------------------ */
   /* Methods                                                                  */
   /* ------------------------------------------------------------------------ */
 public:
   /// function to print the contain of the class
   virtual void printself(std::ostream & stream, int indent = 0) const {
     std::string space;
     for (Int i = 0; i < indent; i++, space += AKANTU_INDENT)
       ;
     stream << space << "Shapes [" << std::endl;
     integration_points.printself(stream, indent + 1);
     // shapes.printself(stream, indent + 1);
     // shapes_derivatives.printself(stream, indent + 1);
     stream << space << "]" << std::endl;
   }
 
   /// set the integration points for a given element
   template <ElementType type>
   void setIntegrationPointsByType(const Matrix<Real> & integration_points,
                                   const GhostType & ghost_type);
 
   /// Build pre-computed matrices for interpolation of field form integration
   /// points at other given positions (interpolation_points)
   void initElementalFieldInterpolationFromIntegrationPoints(
       const ElementTypeMapArray<Real> & interpolation_points_coordinates,
       ElementTypeMapArray<Real> & interpolation_points_coordinates_matrices,
       ElementTypeMapArray<Real> & quad_points_coordinates_inv_matrices,
       const ElementTypeMapArray<Real> & quadrature_points_coordinates,
       const ElementTypeMapArray<UInt> * element_filter) const;
 
   /// Interpolate field at given position from given values of this field at
   /// integration points (field)
   /// using matrices precomputed with
   /// initElementalFieldInterplationFromIntegrationPoints
   void interpolateElementalFieldFromIntegrationPoints(
       const ElementTypeMapArray<Real> & field,
       const ElementTypeMapArray<Real> &
           interpolation_points_coordinates_matrices,
       const ElementTypeMapArray<Real> & quad_points_coordinates_inv_matrices,
       ElementTypeMapArray<Real> & result, const GhostType & ghost_type,
       const ElementTypeMapArray<UInt> * element_filter) const;
 
 protected:
   /// interpolate nodal values stored by element on the integration points
   template <ElementType type>
   void interpolateElementalFieldOnIntegrationPoints(
       const Array<Real> & u_el, Array<Real> & uq, const GhostType & ghost_type,
       const Array<Real> & shapes,
       const Array<UInt> & filter_elements = empty_filter) const;
 
   /// gradient of nodal values stored by element on the control points
   template <ElementType type>
   void gradientElementalFieldOnIntegrationPoints(
       const Array<Real> & u_el, Array<Real> & out_nablauq,
       const GhostType & ghost_type, const Array<Real> & shapes_derivatives,
       const Array<UInt> & filter_elements) const;
 
 protected:
   /// By element versions of non-templated eponym methods
   template <ElementType type>
   inline void interpolateElementalFieldFromIntegrationPoints(
       const Array<Real> & field,
       const Array<Real> & interpolation_points_coordinates_matrices,
       const Array<Real> & quad_points_coordinates_inv_matrices,
       ElementTypeMapArray<Real> & result, const GhostType & ghost_type,
       const Array<UInt> & element_filter) const;
 
   /// Interpolate field at given position from given values of this field at
   /// integration points (field)
   /// using matrices precomputed with
   /// initElementalFieldInterplationFromIntegrationPoints
   template <ElementType type>
   inline void initElementalFieldInterpolationFromIntegrationPoints(
       const Array<Real> & interpolation_points_coordinates,
       ElementTypeMapArray<Real> & interpolation_points_coordinates_matrices,
       ElementTypeMapArray<Real> & quad_points_coordinates_inv_matrices,
       const Array<Real> & quadrature_points_coordinates,
       const GhostType & ghost_type, const Array<UInt> & element_filter) const;
 
   /// build matrix for the interpolation of field form integration points
   template <ElementType type>
   inline void buildElementalFieldInterpolationMatrix(
       const Matrix<Real> & coordinates, Matrix<Real> & coordMatrix,
       UInt integration_order =
           ElementClassProperty<type>::polynomial_degree) const;
 
   /// build the so called interpolation matrix (first collumn is 1, then the
   /// other collumns are the traansposed coordinates)
   inline void buildInterpolationMatrix(const Matrix<Real> & coordinates,
                                        Matrix<Real> & coordMatrix,
                                        UInt integration_order) const;
 
 public:
   virtual void onElementsAdded(const Array<Element> &) {
     AKANTU_TO_IMPLEMENT();
   }
   virtual void onElementsRemoved(const Array<Element> &,
                                  const ElementTypeMapArray<UInt> &) {
     AKANTU_TO_IMPLEMENT();
   }
   /* ------------------------------------------------------------------------ */
   /* Accessors                                                                */
   /* ------------------------------------------------------------------------ */
 public:
   /// get the size of the shapes returned by the element class
   static inline UInt getShapeSize(const ElementType & type);
 
   /// get the size of the shapes derivatives returned by the element class
   static inline UInt getShapeDerivativesSize(const ElementType & type);
 
   inline const Matrix<Real> &
   getIntegrationPoints(const ElementType & type,
                        const GhostType & ghost_type) const {
     return integration_points(type, ghost_type);
   }
 
   /* ------------------------------------------------------------------------ */
   /* Accessors                                                                */
   /* ------------------------------------------------------------------------ */
 public:
   /// get a the shapes vector
   inline const Array<Real> &
   getShapes(const ElementType & el_type,
             const GhostType & ghost_type = _not_ghost) const;
 
   /// get a the shapes derivatives vector
   inline const Array<Real> &
   getShapesDerivatives(const ElementType & el_type,
                        const GhostType & ghost_type = _not_ghost) const;
 
   /* ------------------------------------------------------------------------ */
   /* Class Members                                                            */
   /* ------------------------------------------------------------------------ */
 protected:
   /// shape functions for all elements
   ElementTypeMapArray<Real, InterpolationType> shapes;
 
   /// shape functions derivatives for all elements
   ElementTypeMapArray<Real, InterpolationType> shapes_derivatives;
 
   /// associated mesh
   const Mesh & mesh;
 
   /// shape functions for all elements
   ElementTypeMap<Matrix<Real>> integration_points;
 };
 
 /* -------------------------------------------------------------------------- */
 /* inline functions                                                           */
 /* -------------------------------------------------------------------------- */
 /// standard output stream operator
 inline std::ostream & operator<<(std::ostream & stream,
                                  const ShapeFunctions & _this) {
   _this.printself(stream);
   return stream;
 }
 
 } // namespace akantu
 #include "shape_functions_inline_impl.cc"
 
 #endif /* __AKANTU_SHAPE_FUNCTIONS_HH__ */
diff --git a/src/fe_engine/shape_functions_inline_impl.cc b/src/fe_engine/shape_functions_inline_impl.cc
index f7d05f8c4..84814402b 100644
--- a/src/fe_engine/shape_functions_inline_impl.cc
+++ b/src/fe_engine/shape_functions_inline_impl.cc
@@ -1,402 +1,401 @@
 /**
  * @file   shape_functions_inline_impl.cc
  *
  * @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
  * @author Fabian Barras <fabian.barras@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  * @author Marco Vocialta <marco.vocialta@epfl.ch>
  *
  * @date creation: Wed Oct 27 2010
- * @date last modification: Thu Oct 15 2015
+ * @date last modification: Tue Feb 20 2018
  *
  * @brief  ShapeFunctions inline implementation
  *
  * @section LICENSE
  *
- * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
- * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
- * Solides)
+ * 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
+ * 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
+ * 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 "fe_engine.hh"
 #include "shape_functions.hh"
 /* -------------------------------------------------------------------------- */
 
 #ifndef __AKANTU_SHAPE_FUNCTIONS_INLINE_IMPL_CC__
 #define __AKANTU_SHAPE_FUNCTIONS_INLINE_IMPL_CC__
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 inline const Array<Real> &
 ShapeFunctions::getShapes(const ElementType & el_type,
                           const GhostType & ghost_type) const {
   return shapes(FEEngine::getInterpolationType(el_type), ghost_type);
 }
 
 /* -------------------------------------------------------------------------- */
 inline const Array<Real> &
 ShapeFunctions::getShapesDerivatives(const ElementType & el_type,
                                      const GhostType & ghost_type) const {
   return shapes_derivatives(FEEngine::getInterpolationType(el_type),
                             ghost_type);
 }
 
 /* -------------------------------------------------------------------------- */
 inline UInt ShapeFunctions::getShapeSize(const ElementType & type) {
   AKANTU_DEBUG_IN();
 
   UInt shape_size = 0;
 #define GET_SHAPE_SIZE(type) shape_size = ElementClass<type>::getShapeSize()
 
   AKANTU_BOOST_ALL_ELEMENT_SWITCH(GET_SHAPE_SIZE); // ,
 
 #undef GET_SHAPE_SIZE
 
   AKANTU_DEBUG_OUT();
   return shape_size;
 }
 
 /* -------------------------------------------------------------------------- */
 inline UInt ShapeFunctions::getShapeDerivativesSize(const ElementType & type) {
   AKANTU_DEBUG_IN();
 
   UInt shape_derivatives_size = 0;
 #define GET_SHAPE_DERIVATIVES_SIZE(type)                                       \
   shape_derivatives_size = ElementClass<type>::getShapeDerivativesSize()
 
   AKANTU_BOOST_ALL_ELEMENT_SWITCH(GET_SHAPE_DERIVATIVES_SIZE); // ,
 
 #undef GET_SHAPE_DERIVATIVES_SIZE
 
   AKANTU_DEBUG_OUT();
   return shape_derivatives_size;
 }
 
 /* -------------------------------------------------------------------------- */
 template <ElementType type>
 void ShapeFunctions::setIntegrationPointsByType(const Matrix<Real> & points,
                                                 const GhostType & ghost_type) {
   if (not this->integration_points.exists(type, ghost_type))
     this->integration_points(type, ghost_type).shallowCopy(points);
 }
 
 /* -------------------------------------------------------------------------- */
 inline void
 ShapeFunctions::buildInterpolationMatrix(const Matrix<Real> & coordinates,
                                          Matrix<Real> & coordMatrix,
                                          UInt integration_order) const {
   switch (integration_order) {
   case 1: {
     for (UInt i = 0; i < coordinates.cols(); ++i)
       coordMatrix(i, 0) = 1;
     break;
   }
   case 2: {
     UInt nb_quadrature_points = coordMatrix.cols();
 
     for (UInt i = 0; i < coordinates.cols(); ++i) {
       coordMatrix(i, 0) = 1;
       for (UInt j = 1; j < nb_quadrature_points; ++j)
         coordMatrix(i, j) = coordinates(j - 1, i);
     }
     break;
   }
   default: {
     AKANTU_TO_IMPLEMENT();
     break;
   }
   }
 }
 
 /* -------------------------------------------------------------------------- */
 template <ElementType type>
 inline void ShapeFunctions::buildElementalFieldInterpolationMatrix(
     const Matrix<Real> &, Matrix<Real> &, UInt) const {
   AKANTU_TO_IMPLEMENT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <>
 inline void ShapeFunctions::buildElementalFieldInterpolationMatrix<_segment_2>(
     const Matrix<Real> & coordinates, Matrix<Real> & coordMatrix,
     UInt integration_order) const {
   buildInterpolationMatrix(coordinates, coordMatrix, integration_order);
 }
 
 /* -------------------------------------------------------------------------- */
 template <>
 inline void ShapeFunctions::buildElementalFieldInterpolationMatrix<_segment_3>(
     const Matrix<Real> & coordinates, Matrix<Real> & coordMatrix,
     UInt integration_order) const {
   buildInterpolationMatrix(coordinates, coordMatrix, integration_order);
 }
 
 /* -------------------------------------------------------------------------- */
 template <>
 inline void ShapeFunctions::buildElementalFieldInterpolationMatrix<_triangle_3>(
     const Matrix<Real> & coordinates, Matrix<Real> & coordMatrix,
     UInt integration_order) const {
   buildInterpolationMatrix(coordinates, coordMatrix, integration_order);
 }
 
 /* -------------------------------------------------------------------------- */
 template <>
 inline void ShapeFunctions::buildElementalFieldInterpolationMatrix<_triangle_6>(
     const Matrix<Real> & coordinates, Matrix<Real> & coordMatrix,
     UInt integration_order) const {
   buildInterpolationMatrix(coordinates, coordMatrix, integration_order);
 }
 
 /* -------------------------------------------------------------------------- */
 template <>
 inline void
 ShapeFunctions::buildElementalFieldInterpolationMatrix<_tetrahedron_4>(
     const Matrix<Real> & coordinates, Matrix<Real> & coordMatrix,
     UInt integration_order) const {
   buildInterpolationMatrix(coordinates, coordMatrix, integration_order);
 }
 
 /* -------------------------------------------------------------------------- */
 template <>
 inline void
 ShapeFunctions::buildElementalFieldInterpolationMatrix<_tetrahedron_10>(
     const Matrix<Real> & coordinates, Matrix<Real> & coordMatrix,
     UInt integration_order) const {
   buildInterpolationMatrix(coordinates, coordMatrix, integration_order);
 }
 
 /**
  * @todo Write a more efficient interpolation for quadrangles by
  * dropping unnecessary quadrature points
  *
  */
 
 /* -------------------------------------------------------------------------- */
 template <>
 inline void
 ShapeFunctions::buildElementalFieldInterpolationMatrix<_quadrangle_4>(
     const Matrix<Real> & coordinates, Matrix<Real> & coordMatrix,
     UInt integration_order) const {
 
   if (integration_order !=
       ElementClassProperty<_quadrangle_4>::polynomial_degree) {
     AKANTU_TO_IMPLEMENT();
   } else {
     for (UInt i = 0; i < coordinates.cols(); ++i) {
       Real x = coordinates(0, i);
       Real y = coordinates(1, i);
 
       coordMatrix(i, 0) = 1;
       coordMatrix(i, 1) = x;
       coordMatrix(i, 2) = y;
       coordMatrix(i, 3) = x * y;
     }
   }
 }
 
 /* -------------------------------------------------------------------------- */
 template <>
 inline void
 ShapeFunctions::buildElementalFieldInterpolationMatrix<_quadrangle_8>(
     const Matrix<Real> & coordinates, Matrix<Real> & coordMatrix,
     UInt integration_order) const {
 
   if (integration_order !=
       ElementClassProperty<_quadrangle_8>::polynomial_degree) {
     AKANTU_TO_IMPLEMENT();
   } else {
     for (UInt i = 0; i < coordinates.cols(); ++i) {
       // UInt j = 0;
       Real x = coordinates(0, i);
       Real y = coordinates(1, i);
 
       coordMatrix(i, 0) = 1;
       coordMatrix(i, 1) = x;
       coordMatrix(i, 2) = y;
       coordMatrix(i, 3) = x * y;
       // for (UInt e = 0; e <= 2; ++e) {
       //   for (UInt n = 0; n <= 2; ++n) {
       //     coordMatrix(i, j) = std::pow(x, e) * std::pow(y, n);
       //     ++j;
       //   }
       // }
     }
   }
 }
 /* -------------------------------------------------------------------------- */
 template <ElementType type>
 inline void ShapeFunctions::interpolateElementalFieldFromIntegrationPoints(
     const Array<Real> & field,
     const Array<Real> & interpolation_points_coordinates_matrices,
     const Array<Real> & quad_points_coordinates_inv_matrices,
     ElementTypeMapArray<Real> & result, const GhostType & ghost_type,
     const Array<UInt> & element_filter) const {
   AKANTU_DEBUG_IN();
 
   auto nb_element = this->mesh.getNbElement(type, ghost_type);
 
   auto nb_quad_per_element =
       GaussIntegrationElement<type>::getNbQuadraturePoints();
   auto nb_interpolation_points_per_elem =
       interpolation_points_coordinates_matrices.getNbComponent() /
       nb_quad_per_element;
 
   if (!result.exists(type, ghost_type))
     result.alloc(nb_element * nb_interpolation_points_per_elem,
                  field.getNbComponent(), type, ghost_type);
 
   if (element_filter != empty_filter)
     nb_element = element_filter.size();
 
   Matrix<Real> coefficients(nb_quad_per_element, field.getNbComponent());
 
   auto & result_vec = result(type, ghost_type);
 
   auto field_it = field.begin_reinterpret(field.getNbComponent(),
                                           nb_quad_per_element, nb_element);
 
   auto interpolation_points_coordinates_it =
       interpolation_points_coordinates_matrices.begin(
           nb_interpolation_points_per_elem, nb_quad_per_element);
 
   auto result_begin = result_vec.begin_reinterpret(
       field.getNbComponent(), nb_interpolation_points_per_elem,
       result_vec.size() / nb_interpolation_points_per_elem);
 
   auto inv_quad_coord_it = quad_points_coordinates_inv_matrices.begin(
       nb_quad_per_element, nb_quad_per_element);
 
   /// loop over the elements of the current filter and element type
   for (UInt el = 0; el < nb_element; ++el, ++field_it, ++inv_quad_coord_it,
             ++interpolation_points_coordinates_it) {
     /**
      * matrix containing the inversion of the quadrature points'
      * coordinates
      */
     const auto & inv_quad_coord_matrix = *inv_quad_coord_it;
 
     /**
      * multiply it by the field values over quadrature points to get
      * the interpolation coefficients
      */
     coefficients.mul<false, true>(inv_quad_coord_matrix, *field_it);
 
     /// matrix containing the points' coordinates
     const auto & coord = *interpolation_points_coordinates_it;
 
     /// multiply the coordinates matrix by the coefficients matrix and store the
     /// result
     Matrix<Real> res(result_begin[element_filter(el)]);
     res.mul<true, true>(coefficients, coord);
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <ElementType type>
 inline void ShapeFunctions::interpolateElementalFieldOnIntegrationPoints(
     const Array<Real> & u_el, Array<Real> & uq, const GhostType & ghost_type,
     const Array<Real> & shapes, const Array<UInt> & filter_elements) const {
   auto nb_element = mesh.getNbElement(type, ghost_type);
   auto nb_nodes_per_element = ElementClass<type>::getShapeSize();
   auto nb_points = shapes.size() / mesh.getNbElement(type, ghost_type);
   auto nb_degree_of_freedom = u_el.getNbComponent() / nb_nodes_per_element;
 
   Array<Real>::const_matrix_iterator N_it;
   Array<Real> * filtered_N = nullptr;
   if (filter_elements != empty_filter) {
     nb_element = filter_elements.size();
     filtered_N = new Array<Real>(0, shapes.getNbComponent());
     FEEngine::filterElementalData(mesh, shapes, *filtered_N, type, ghost_type,
                                   filter_elements);
     N_it = filtered_N->begin_reinterpret(nb_nodes_per_element, nb_points,
                                          nb_element);
   } else {
     N_it =
         shapes.begin_reinterpret(nb_nodes_per_element, nb_points, nb_element);
   }
 
   uq.resize(nb_element * nb_points);
 
   auto u_it = u_el.begin(nb_degree_of_freedom, nb_nodes_per_element);
   auto inter_u_it =
       uq.begin_reinterpret(nb_degree_of_freedom, nb_points, nb_element);
 
   for (UInt el = 0; el < nb_element; ++el, ++N_it, ++u_it, ++inter_u_it) {
     const auto & u = *u_it;
     const auto & N = *N_it;
     auto & inter_u = *inter_u_it;
 
     inter_u.template mul<false, false>(u, N);
   }
 
   delete filtered_N;
 }
 
 /* -------------------------------------------------------------------------- */
 template <ElementType type>
 void ShapeFunctions::gradientElementalFieldOnIntegrationPoints(
     const Array<Real> & u_el, Array<Real> & out_nablauq,
     const GhostType & ghost_type, const Array<Real> & shapes_derivatives,
     const Array<UInt> & filter_elements) const {
   AKANTU_DEBUG_IN();
 
   auto nb_nodes_per_element =
       ElementClass<type>::getNbNodesPerInterpolationElement();
   auto nb_points = integration_points(type, ghost_type).cols();
   auto element_dimension = ElementClass<type>::getNaturalSpaceDimension();
   auto nb_degree_of_freedom = u_el.getNbComponent() / nb_nodes_per_element;
   auto nb_element = mesh.getNbElement(type, ghost_type);
 
   Array<Real>::const_matrix_iterator B_it;
 
   Array<Real> * filtered_B = nullptr;
   if (filter_elements != empty_filter) {
     nb_element = filter_elements.size();
     filtered_B = new Array<Real>(0, shapes_derivatives.getNbComponent());
     FEEngine::filterElementalData(mesh, shapes_derivatives, *filtered_B, type,
                                   ghost_type, filter_elements);
     B_it = filtered_B->begin(element_dimension, nb_nodes_per_element);
   } else {
     B_it = shapes_derivatives.begin(element_dimension, nb_nodes_per_element);
   }
 
   out_nablauq.resize(nb_element * nb_points);
   auto u_it = u_el.begin(nb_degree_of_freedom, nb_nodes_per_element);
   auto nabla_u_it = out_nablauq.begin(nb_degree_of_freedom, element_dimension);
 
   for (UInt el = 0; el < nb_element; ++el, ++u_it) {
     const auto & u = *u_it;
     for (UInt q = 0; q < nb_points; ++q, ++B_it, ++nabla_u_it) {
       const auto & B = *B_it;
       auto & nabla_u = *nabla_u_it;
       nabla_u.template mul<false, true>(u, B);
     }
   }
 
   delete filtered_B;
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 } // namespace akantu
 
 #endif /* __AKANTU_SHAPE_FUNCTIONS_INLINE_IMPL_CC__ */
diff --git a/src/fe_engine/shape_lagrange.hh b/src/fe_engine/shape_lagrange.hh
index 36a3c321f..d3ff031d1 100644
--- a/src/fe_engine/shape_lagrange.hh
+++ b/src/fe_engine/shape_lagrange.hh
@@ -1,172 +1,172 @@
 /**
  * @file   shape_lagrange.hh
  *
  * @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Tue Feb 15 2011
- * @date last modification: Thu Nov 05 2015
+ * @date last modification: Mon Jan 29 2018
  *
  * @brief  lagrangian shape functions class
  *
  * @section LICENSE
  *
- * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
- * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
- * Solides)
+ * 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
+ * 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
+ * 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 "shape_lagrange_base.hh"
 /* -------------------------------------------------------------------------- */
 
 #ifndef __AKANTU_SHAPE_LAGRANGE_HH__
 #define __AKANTU_SHAPE_LAGRANGE_HH__
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 template <class Shape> class ShapeCohesive;
 class ShapeIGFEM;
 
 template <ElementKind kind> class ShapeLagrange : public ShapeLagrangeBase {
   /* ------------------------------------------------------------------------ */
   /* Constructors/Destructors                                                 */
   /* ------------------------------------------------------------------------ */
 public:
   ShapeLagrange(const Mesh & mesh, const ID & id = "shape_lagrange",
                 const MemoryID & memory_id = 0);
   ~ShapeLagrange() override = default;
 
   /* ------------------------------------------------------------------------ */
   /* Methods                                                                  */
   /* ------------------------------------------------------------------------ */
 public:
   /// initialization function for structural elements not yet implemented
   inline void initShapeFunctions(const Array<Real> & nodes,
                                  const Matrix<Real> & integration_points,
                                  const ElementType & type,
                                  const GhostType & ghost_type);
 
   /// computes the shape functions derivatives for given interpolation points
   template <ElementType type>
   void computeShapeDerivativesOnIntegrationPoints(
       const Array<Real> & nodes, const Matrix<Real> & integration_points,
       Array<Real> & shape_derivatives, const GhostType & ghost_type,
       const Array<UInt> & filter_elements = empty_filter) const;
 
   void computeShapeDerivativesOnIntegrationPoints(
       const Array<Real> & nodes, const Matrix<Real> & integration_points,
       Array<Real> & shape_derivatives, const ElementType & type,
       const GhostType & ghost_type,
       const Array<UInt> & filter_elements) const override;
 
   /// pre compute all shapes on the element integration points from natural
   /// coordinates
   template <ElementType type>
   void precomputeShapesOnIntegrationPoints(const Array<Real> & nodes,
                                            const GhostType & ghost_type);
 
   /// pre compute all shape derivatives on the element integration points from
   /// natural coordinates
   template <ElementType type>
   void
   precomputeShapeDerivativesOnIntegrationPoints(const Array<Real> & nodes,
                                                 const GhostType & ghost_type);
 
   /// interpolate nodal values on the integration points
   template <ElementType type>
   void interpolateOnIntegrationPoints(
       const Array<Real> & u, Array<Real> & uq, UInt nb_degree_of_freedom,
       GhostType ghost_type = _not_ghost,
       const Array<UInt> & filter_elements = empty_filter) const;
 
   template <ElementType type>
   void interpolateOnIntegrationPoints(
       const Array<Real> & in_u, Array<Real> & out_uq, UInt nb_degree_of_freedom,
       const Array<Real> & shapes, GhostType ghost_type = _not_ghost,
       const Array<UInt> & filter_elements = empty_filter) const;
 
   /// interpolate on physical point
   template <ElementType type>
   void interpolate(const Vector<Real> & real_coords, UInt elem,
                    const Matrix<Real> & nodal_values,
                    Vector<Real> & interpolated,
                    const GhostType & ghost_type) const;
 
   /// compute the gradient of u on the integration points
   template <ElementType type>
   void gradientOnIntegrationPoints(
       const Array<Real> & u, Array<Real> & nablauq, UInt nb_degree_of_freedom,
       GhostType ghost_type = _not_ghost,
       const Array<UInt> & filter_elements = empty_filter) const;
 
   template <ElementType type>
   void computeBtD(const Array<Real> & Ds, Array<Real> & BtDs,
                   GhostType ghost_type,
                   const Array<UInt> & filter_elements) const;
 
   template <ElementType type>
   void computeBtDB(const Array<Real> & Ds, Array<Real> & BtDBs, UInt order_d,
                    GhostType ghost_type,
                    const Array<UInt> & filter_elements) const;
 
   /// multiply a field by shape functions  @f$ fts_{ij} = f_i * \varphi_j @f$
   template <ElementType type>
   void fieldTimesShapes(const Array<Real> & field,
                         Array<Real> & field_times_shapes,
                         GhostType ghost_type) const;
 
   /// find natural coords from real coords provided an element
   template <ElementType type>
   void inverseMap(const Vector<Real> & real_coords, UInt element,
                   Vector<Real> & natural_coords,
                   const GhostType & ghost_type = _not_ghost) const;
 
   /// return true if the coordinates provided are inside the element, false
   /// otherwise
   template <ElementType type>
   bool contains(const Vector<Real> & real_coords, UInt elem,
                 const GhostType & ghost_type) const;
 
   /// compute the shape on a provided point
   template <ElementType type>
   void computeShapes(const Vector<Real> & real_coords, UInt elem,
                      Vector<Real> & shapes, const GhostType & ghost_type) const;
 
   /// compute the shape derivatives on a provided point
   template <ElementType type>
   void computeShapeDerivatives(const Matrix<Real> & real_coords, UInt elem,
                                Tensor3<Real> & shapes,
                                const GhostType & ghost_type) const;
 
 protected:
   /// compute the shape derivatives on integration points for a given element
   template <ElementType type>
   inline void
   computeShapeDerivativesOnCPointsByElement(const Matrix<Real> & node_coords,
                                             const Matrix<Real> & natural_coords,
                                             Tensor3<Real> & shapesd) const;
 };
 
 } // namespace akantu
 
 /* -------------------------------------------------------------------------- */
 /* inline functions                                                           */
 /* -------------------------------------------------------------------------- */
 #include "shape_lagrange_inline_impl.cc"
 
 #endif /* __AKANTU_SHAPE_LAGRANGE_HH__ */
diff --git a/src/fe_engine/shape_lagrange_base.cc b/src/fe_engine/shape_lagrange_base.cc
index 30fa00208..f2ef2f88a 100644
--- a/src/fe_engine/shape_lagrange_base.cc
+++ b/src/fe_engine/shape_lagrange_base.cc
@@ -1,158 +1,162 @@
 /**
  * @file   shape_lagrange_base.cc
  *
- * @author Nicolas Richart
+ * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
- * @date creation  Thu Jul 27 2017
+ * @date creation: Wed Aug 09 2017
+ * @date last modification: Tue Feb 20 2018
+ *
+ * @brief  common par for the shape lagrange
  *
  * @section LICENSE
  *
- * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * 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
+ * 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
+ * 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 "shape_lagrange_base.hh"
 #include "mesh_iterators.hh"
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 
 ShapeLagrangeBase::ShapeLagrangeBase(const Mesh & mesh,
                                      const ElementKind & kind, const ID & id,
                                      const MemoryID & memory_id)
     : ShapeFunctions(mesh, id, memory_id), _kind(kind) {}
 
 /* -------------------------------------------------------------------------- */
 ShapeLagrangeBase::~ShapeLagrangeBase() = default;
 
 /* -------------------------------------------------------------------------- */
 #define AKANTU_COMPUTE_SHAPES(type)                                            \
   _this.template computeShapesOnIntegrationPoints<type>(                       \
       nodes, integration_points, shapes, ghost_type, filter_elements)
 
 namespace shape_lagrange {
   namespace details {
     template <ElementKind kind> struct Helper {
       template <class S>
       static void call(const S &, const Array<Real> &, const Matrix<Real> &,
                        Array<Real> &, const ElementType &, const GhostType &,
                        const Array<UInt> &) {
         AKANTU_TO_IMPLEMENT();
       }
     };
 
 #define AKANTU_COMPUTE_SHAPES_KIND(kind)                                       \
   template <> struct Helper<kind> {                                            \
     template <class S>                                                         \
     static void call(const S & _this, const Array<Real> & nodes,               \
                      const Matrix<Real> & integration_points,                  \
                      Array<Real> & shapes, const ElementType & type,           \
                      const GhostType & ghost_type,                             \
                      const Array<UInt> & filter_elements) {                    \
       AKANTU_BOOST_KIND_ELEMENT_SWITCH(AKANTU_COMPUTE_SHAPES, kind);           \
     }                                                                          \
   };
 
     AKANTU_BOOST_ALL_KIND_LIST(AKANTU_COMPUTE_SHAPES_KIND,
                                AKANTU_FE_ENGINE_LIST_LAGRANGE_BASE)
 
   } // namespace details
 } // namespace shape_lagrange
 
 /* -------------------------------------------------------------------------- */
 void ShapeLagrangeBase::computeShapesOnIntegrationPoints(
     const Array<Real> & nodes, const Matrix<Real> & integration_points,
     Array<Real> & shapes, const ElementType & type,
     const GhostType & ghost_type, const Array<UInt> & filter_elements) const {
 
   auto kind = Mesh::getKind(type);
 
 #define AKANTU_COMPUTE_SHAPES_KIND_SWITCH(kind)                                \
   shape_lagrange::details::Helper<kind>::call(                                 \
       *this, nodes, integration_points, shapes, type, ghost_type,              \
       filter_elements);
 
   AKANTU_BOOST_LIST_SWITCH(
       AKANTU_COMPUTE_SHAPES_KIND_SWITCH,
       BOOST_PP_LIST_TO_SEQ(AKANTU_FE_ENGINE_LIST_LAGRANGE_BASE), kind);
 
 #undef AKANTU_COMPUTE_SHAPES
 #undef AKANTU_COMPUTE_SHAPES_KIND
 #undef AKANTU_COMPUTE_SHAPES_KIND_SWITCH
 }
 
 /* -------------------------------------------------------------------------- */
 void ShapeLagrangeBase::onElementsAdded(const Array<Element> & new_elements) {
   AKANTU_DEBUG_IN();
   const auto & nodes = mesh.getNodes();
 
   for (auto elements_range : MeshElementsByTypes(new_elements)) {
     auto type = elements_range.getType();
     auto ghost_type = elements_range.getGhostType();
 
     if (mesh.getKind(type) != _kind)
       continue;
 
     auto & elements = elements_range.getElements();
 
     auto itp_type = FEEngine::getInterpolationType(type);
 
     if (not this->shapes_derivatives.exists(itp_type, ghost_type)) {
       auto size_of_shapesd = this->getShapeDerivativesSize(type);
       this->shapes_derivatives.alloc(0, size_of_shapesd, itp_type, ghost_type);
     }
 
     if (not shapes.exists(itp_type, ghost_type)) {
       auto size_of_shapes = this->getShapeSize(type);
       this->shapes.alloc(0, size_of_shapes, itp_type, ghost_type);
     }
 
     const auto & natural_coords = integration_points(type, ghost_type);
     computeShapesOnIntegrationPoints(nodes, natural_coords,
                                      shapes(itp_type, ghost_type), type,
                                      ghost_type, elements);
 
     computeShapeDerivativesOnIntegrationPoints(
         nodes, natural_coords, shapes_derivatives(itp_type, ghost_type), type,
         ghost_type, elements);
   }
 #undef INIT_SHAPE_FUNCTIONS
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void ShapeLagrangeBase::onElementsRemoved(
     const Array<Element> &, const ElementTypeMapArray<UInt> & new_numbering) {
   this->shapes.onElementsRemoved(new_numbering);
   this->shapes_derivatives.onElementsRemoved(new_numbering);
 }
 
 /* -------------------------------------------------------------------------- */
 void ShapeLagrangeBase::printself(std::ostream & stream, int indent) const {
   std::string space;
   for (Int i = 0; i < indent; i++, space += AKANTU_INDENT)
     ;
 
   stream << space << "Shapes Lagrange [" << std::endl;
   ShapeFunctions::printself(stream, indent + 1);
   shapes.printself(stream, indent + 1);
   shapes_derivatives.printself(stream, indent + 1);
   stream << space << "]" << std::endl;
 }
 
 } // namespace akantu
diff --git a/src/fe_engine/shape_lagrange_base.hh b/src/fe_engine/shape_lagrange_base.hh
index 08d915f7d..c50b27689 100644
--- a/src/fe_engine/shape_lagrange_base.hh
+++ b/src/fe_engine/shape_lagrange_base.hh
@@ -1,91 +1,92 @@
-
 /**
  * @file   shape_lagrange_base.hh
  *
- * @author Nicolas Richart
+ * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
- * @date creation  Thu Jul 27 2017
+ * @date creation: Wed Aug 09 2017
+ * @date last modification: Wed Nov 08 2017
  *
- * @brief Base class for the shape lagrange
+ * @brief  Base class for the shape lagrange
  *
  * @section LICENSE
  *
- * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * 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
+ * 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
+ * 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 "shape_functions.hh"
 /* -------------------------------------------------------------------------- */
 
 #ifndef __AKANTU_SHAPE_LAGRANGE_BASE_HH__
 #define __AKANTU_SHAPE_LAGRANGE_BASE_HH__
 
 namespace akantu {
 
 class ShapeLagrangeBase : public ShapeFunctions {
   /* ------------------------------------------------------------------------ */
   /* Constructors/Destructors                                                 */
   /* ------------------------------------------------------------------------ */
 public:
   ShapeLagrangeBase(const Mesh & mesh, const ElementKind & kind,
                     const ID & id = "shape_lagrange",
                     const MemoryID & memory_id = 0);
   ~ShapeLagrangeBase() override;
 
   /* ------------------------------------------------------------------------ */
   /* Methods                                                                  */
   /* ------------------------------------------------------------------------ */
 public:
   /// computes the shape functions for given interpolation points
   virtual void computeShapesOnIntegrationPoints(
       const Array<Real> & nodes, const Matrix<Real> & integration_points,
       Array<Real> & shapes, const ElementType & type,
       const GhostType & ghost_type,
       const Array<UInt> & filter_elements = empty_filter) const;
 
   /// computes the shape functions derivatives for given interpolation points
   virtual void computeShapeDerivativesOnIntegrationPoints(
       const Array<Real> & nodes, const Matrix<Real> & integration_points,
       Array<Real> & shape_derivatives, const ElementType & type,
       const GhostType & ghost_type,
       const Array<UInt> & filter_elements = empty_filter) const = 0;
 
   /// function to print the containt of the class
   void printself(std::ostream & stream, int indent = 0) const override;
 
   template <ElementType type>
   void computeShapesOnIntegrationPoints(
       const Array<Real> & nodes, const Matrix<Real> & integration_points,
       Array<Real> & shapes, const GhostType & ghost_type,
       const Array<UInt> & filter_elements = empty_filter) const;
 
 public:
   void onElementsAdded(const Array<Element> & elements) override;
   void
   onElementsRemoved(const Array<Element> & elements,
                     const ElementTypeMapArray<UInt> & new_numbering) override;
 
 protected:
   /// The kind to consider
   ElementKind _kind;
 };
 
 } // namespace akantu
 
 #include "shape_lagrange_base_inline_impl.cc"
 
 #endif /* __AKANTU_SHAPE_LAGRANGE_BASE_HH__ */
diff --git a/src/fe_engine/shape_lagrange_base_inline_impl.cc b/src/fe_engine/shape_lagrange_base_inline_impl.cc
index 4b9ebbf08..448d3b36a 100644
--- a/src/fe_engine/shape_lagrange_base_inline_impl.cc
+++ b/src/fe_engine/shape_lagrange_base_inline_impl.cc
@@ -1,82 +1,84 @@
 /**
  * @file   shape_lagrange_base_inline_impl.cc
  *
- * @author Nicolas Richart
+ * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
- * @date creation  Thu Jul 27 2017
+ * @date creation: Wed Aug 09 2017
+ * @date last modification: Wed Oct 11 2017
  *
- * @brief A Documented file.
+ * @brief  A Documented file.
  *
  * @section LICENSE
  *
- * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * 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
+ * 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
+ * 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 "shape_lagrange_base.hh"
 /* -------------------------------------------------------------------------- */
 
 #ifndef __AKANTU_SHAPE_LAGRANGE_BASE_INLINE_IMPL_CC__
 #define __AKANTU_SHAPE_LAGRANGE_BASE_INLINE_IMPL_CC__
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 template <ElementType type>
 void ShapeLagrangeBase::computeShapesOnIntegrationPoints(
     const Array<Real> &, const Matrix<Real> & integration_points,
     Array<Real> & shapes, const GhostType & ghost_type,
     const Array<UInt> & filter_elements) const {
   AKANTU_DEBUG_IN();
 
   UInt nb_points = integration_points.cols();
   UInt nb_element = mesh.getConnectivity(type, ghost_type).size();
 
   shapes.resize(nb_element * nb_points);
 
 #if !defined(AKANTU_NDEBUG)
   UInt size_of_shapes = ElementClass<type>::getShapeSize();
   AKANTU_DEBUG_ASSERT(shapes.getNbComponent() == size_of_shapes,
                       "The shapes array does not have the correct "
                           << "number of component");
 #endif
 
   auto shapes_it = shapes.begin_reinterpret(
       ElementClass<type>::getNbNodesPerInterpolationElement(), nb_points,
       nb_element);
   auto shapes_begin = shapes_it;
   if (filter_elements != empty_filter) {
     nb_element = filter_elements.size();
   }
 
   for (UInt elem = 0; elem < nb_element; ++elem) {
     if (filter_elements != empty_filter)
       shapes_it = shapes_begin + filter_elements(elem);
 
     Matrix<Real> & N = *shapes_it;
     ElementClass<type>::computeShapes(integration_points, N);
 
     if (filter_elements == empty_filter)
       ++shapes_it;
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 } // namespace akantu
 
 #endif /* __AKANTU_SHAPE_LAGRANGE_BASE_INLINE_IMPL_CC__ */
diff --git a/src/fe_engine/shape_lagrange_inline_impl.cc b/src/fe_engine/shape_lagrange_inline_impl.cc
index e8b8aaba0..7a86db51f 100644
--- a/src/fe_engine/shape_lagrange_inline_impl.cc
+++ b/src/fe_engine/shape_lagrange_inline_impl.cc
@@ -1,526 +1,526 @@
 /**
  * @file   shape_lagrange_inline_impl.cc
  *
  * @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Wed Oct 27 2010
- * @date last modification: Thu Oct 15 2015
+ * @date last modification: Tue Feb 20 2018
  *
  * @brief  ShapeLagrange inline implementation
  *
  * @section LICENSE
  *
- * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
- * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
- * Solides)
+ * 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
+ * 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
+ * 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_iterators.hh"
 #include "aka_voigthelper.hh"
 #include "fe_engine.hh"
 #include "shape_lagrange.hh"
 /* -------------------------------------------------------------------------- */
 
 #ifndef __AKANTU_SHAPE_LAGRANGE_INLINE_IMPL_CC__
 #define __AKANTU_SHAPE_LAGRANGE_INLINE_IMPL_CC__
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 #define INIT_SHAPE_FUNCTIONS(type)                                             \
   setIntegrationPointsByType<type>(integration_points, ghost_type);            \
   precomputeShapesOnIntegrationPoints<type>(nodes, ghost_type);                \
   if (ElementClass<type>::getNaturalSpaceDimension() ==                        \
           mesh.getSpatialDimension() ||                                        \
       kind != _ek_regular)                                                     \
     precomputeShapeDerivativesOnIntegrationPoints<type>(nodes, ghost_type);
 
 template <ElementKind kind>
 inline void ShapeLagrange<kind>::initShapeFunctions(
     const Array<Real> & nodes, const Matrix<Real> & integration_points,
     const ElementType & type, const GhostType & ghost_type) {
   AKANTU_BOOST_REGULAR_ELEMENT_SWITCH(INIT_SHAPE_FUNCTIONS);
 }
 
 #undef INIT_SHAPE_FUNCTIONS
 
 /* -------------------------------------------------------------------------- */
 template <ElementKind kind>
 template <ElementType type>
 inline void ShapeLagrange<kind>::computeShapeDerivativesOnCPointsByElement(
     const Matrix<Real> & node_coords, const Matrix<Real> & natural_coords,
     Tensor3<Real> & shapesd) const {
   AKANTU_DEBUG_IN();
 
   // compute dnds
   Tensor3<Real> dnds(node_coords.rows(), node_coords.cols(),
                      natural_coords.cols());
   ElementClass<type>::computeDNDS(natural_coords, dnds);
   // compute jacobian
   Tensor3<Real> J(node_coords.rows(), natural_coords.rows(),
                   natural_coords.cols());
   ElementClass<type>::computeJMat(dnds, node_coords, J);
 
   // compute dndx
   ElementClass<type>::computeShapeDerivatives(J, dnds, shapesd);
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <ElementKind kind>
 template <ElementType type>
 void ShapeLagrange<kind>::inverseMap(const Vector<Real> & real_coords,
                                      UInt elem, Vector<Real> & natural_coords,
                                      const GhostType & ghost_type) const {
 
   AKANTU_DEBUG_IN();
 
   UInt spatial_dimension = mesh.getSpatialDimension();
   UInt nb_nodes_per_element =
       ElementClass<type>::getNbNodesPerInterpolationElement();
 
   UInt * elem_val = mesh.getConnectivity(type, ghost_type).storage();
   Matrix<Real> nodes_coord(spatial_dimension, nb_nodes_per_element);
 
   mesh.extractNodalValuesFromElement(mesh.getNodes(), nodes_coord.storage(),
                                      elem_val + elem * nb_nodes_per_element,
                                      nb_nodes_per_element, spatial_dimension);
 
   ElementClass<type>::inverseMap(real_coords, nodes_coord, natural_coords);
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <ElementKind kind>
 template <ElementType type>
 bool ShapeLagrange<kind>::contains(const Vector<Real> & real_coords, UInt elem,
                                    const GhostType & ghost_type) const {
 
   UInt spatial_dimension = mesh.getSpatialDimension();
   Vector<Real> natural_coords(spatial_dimension);
 
   inverseMap<type>(real_coords, elem, natural_coords, ghost_type);
   return ElementClass<type>::contains(natural_coords);
 }
 
 /* -------------------------------------------------------------------------- */
 template <ElementKind kind>
 template <ElementType type>
 void ShapeLagrange<kind>::interpolate(const Vector<Real> & real_coords,
                                       UInt elem,
                                       const Matrix<Real> & nodal_values,
                                       Vector<Real> & interpolated,
                                       const GhostType & ghost_type) const {
   UInt nb_shapes = ElementClass<type>::getShapeSize();
   Vector<Real> shapes(nb_shapes);
   computeShapes<type>(real_coords, elem, shapes, ghost_type);
   ElementClass<type>::interpolate(nodal_values, shapes, interpolated);
 }
 
 /* -------------------------------------------------------------------------- */
 template <ElementKind kind>
 template <ElementType type>
 void ShapeLagrange<kind>::computeShapes(const Vector<Real> & real_coords,
                                         UInt elem, Vector<Real> & shapes,
                                         const GhostType & ghost_type) const {
 
   AKANTU_DEBUG_IN();
 
   UInt spatial_dimension = mesh.getSpatialDimension();
   Vector<Real> natural_coords(spatial_dimension);
 
   inverseMap<type>(real_coords, elem, natural_coords, ghost_type);
   ElementClass<type>::computeShapes(natural_coords, shapes);
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <ElementKind kind>
 template <ElementType type>
 void ShapeLagrange<kind>::computeShapeDerivatives(
     const Matrix<Real> & real_coords, UInt elem, Tensor3<Real> & shapesd,
     const GhostType & ghost_type) const {
 
   AKANTU_DEBUG_IN();
 
   UInt spatial_dimension = mesh.getSpatialDimension();
   UInt nb_points = real_coords.cols();
   UInt nb_nodes_per_element =
       ElementClass<type>::getNbNodesPerInterpolationElement();
 
   AKANTU_DEBUG_ASSERT(mesh.getSpatialDimension() == shapesd.size(0) &&
                           nb_nodes_per_element == shapesd.size(1),
                       "Shape size doesn't match");
   AKANTU_DEBUG_ASSERT(nb_points == shapesd.size(2),
                       "Number of points doesn't match shapes size");
 
   Matrix<Real> natural_coords(spatial_dimension, nb_points);
 
   // Creates the matrix of natural coordinates
   for (UInt i = 0; i < nb_points; i++) {
     Vector<Real> real_point = real_coords(i);
     Vector<Real> natural_point = natural_coords(i);
 
     inverseMap<type>(real_point, elem, natural_point, ghost_type);
   }
 
   UInt * elem_val = mesh.getConnectivity(type, ghost_type).storage();
   Matrix<Real> nodes_coord(spatial_dimension, nb_nodes_per_element);
 
   mesh.extractNodalValuesFromElement(mesh.getNodes(), nodes_coord.storage(),
                                      elem_val + elem * nb_nodes_per_element,
                                      nb_nodes_per_element, spatial_dimension);
 
   computeShapeDerivativesOnCPointsByElement<type>(nodes_coord, natural_coords,
                                                   shapesd);
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <ElementKind kind>
 ShapeLagrange<kind>::ShapeLagrange(const Mesh & mesh, const ID & id,
                                    const MemoryID & memory_id)
     : ShapeLagrangeBase(mesh, kind, id, memory_id) {}
 
 /* -------------------------------------------------------------------------- */
 template <ElementKind kind>
 template <ElementType type>
 void ShapeLagrange<kind>::computeShapeDerivativesOnIntegrationPoints(
     const Array<Real> & nodes, const Matrix<Real> & integration_points,
     Array<Real> & shape_derivatives, const GhostType & ghost_type,
     const Array<UInt> & filter_elements) const {
   AKANTU_DEBUG_IN();
 
   UInt spatial_dimension = mesh.getSpatialDimension();
 
   UInt nb_nodes_per_element =
       ElementClass<type>::getNbNodesPerInterpolationElement();
 
   UInt nb_points = integration_points.cols();
   UInt nb_element = mesh.getConnectivity(type, ghost_type).size();
 
   UInt size_of_shapesd = ElementClass<type>::getShapeDerivativesSize();
   AKANTU_DEBUG_ASSERT(shape_derivatives.getNbComponent() == size_of_shapesd,
                       "The shapes_derivatives array does not have the correct "
                           << "number of component");
   shape_derivatives.resize(nb_element * nb_points);
 
   Array<Real> x_el(0, spatial_dimension * nb_nodes_per_element);
   FEEngine::extractNodalToElementField(mesh, nodes, x_el, type, ghost_type,
                                        filter_elements);
 
   Real * shapesd_val = shape_derivatives.storage();
   Array<Real>::matrix_iterator x_it =
       x_el.begin(spatial_dimension, nb_nodes_per_element);
 
   if (filter_elements != empty_filter)
     nb_element = filter_elements.size();
 
   for (UInt elem = 0; elem < nb_element; ++elem, ++x_it) {
     if (filter_elements != empty_filter)
       shapesd_val = shape_derivatives.storage() +
                     filter_elements(elem) * size_of_shapesd * nb_points;
 
     Matrix<Real> & X = *x_it;
     Tensor3<Real> B(shapesd_val, spatial_dimension, nb_nodes_per_element,
                     nb_points);
     computeShapeDerivativesOnCPointsByElement<type>(X, integration_points, B);
 
     if (filter_elements == empty_filter)
       shapesd_val += size_of_shapesd * nb_points;
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <ElementKind kind>
 void ShapeLagrange<kind>::computeShapeDerivativesOnIntegrationPoints(
     const Array<Real> & nodes, const Matrix<Real> & integration_points,
     Array<Real> & shape_derivatives, const ElementType & type,
     const GhostType & ghost_type, const Array<UInt> & filter_elements) const {
 #define AKANTU_COMPUTE_SHAPES(type)                                            \
   computeShapeDerivativesOnIntegrationPoints<type>(                            \
       nodes, integration_points, shape_derivatives, ghost_type,                \
       filter_elements);
 
   AKANTU_BOOST_REGULAR_ELEMENT_SWITCH(AKANTU_COMPUTE_SHAPES);
 
 #undef AKANTU_COMPUTE_SHAPES
 }
 
 /* -------------------------------------------------------------------------- */
 template <ElementKind kind>
 template <ElementType type>
 void ShapeLagrange<kind>::precomputeShapesOnIntegrationPoints(
     const Array<Real> & nodes, const GhostType & ghost_type) {
   AKANTU_DEBUG_IN();
 
   InterpolationType itp_type = ElementClassProperty<type>::interpolation_type;
   Matrix<Real> & natural_coords = integration_points(type, ghost_type);
   UInt size_of_shapes = ElementClass<type>::getShapeSize();
 
   Array<Real> & shapes_tmp =
       shapes.alloc(0, size_of_shapes, itp_type, ghost_type);
 
   this->computeShapesOnIntegrationPoints<type>(nodes, natural_coords,
                                                shapes_tmp, ghost_type);
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <ElementKind kind>
 template <ElementType type>
 void ShapeLagrange<kind>::precomputeShapeDerivativesOnIntegrationPoints(
     const Array<Real> & nodes, const GhostType & ghost_type) {
   AKANTU_DEBUG_IN();
 
   InterpolationType itp_type = ElementClassProperty<type>::interpolation_type;
   Matrix<Real> & natural_coords = integration_points(type, ghost_type);
   UInt size_of_shapesd = ElementClass<type>::getShapeDerivativesSize();
 
   Array<Real> & shapes_derivatives_tmp =
       shapes_derivatives.alloc(0, size_of_shapesd, itp_type, ghost_type);
 
   this->computeShapeDerivativesOnIntegrationPoints<type>(
       nodes, natural_coords, shapes_derivatives_tmp, ghost_type);
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 /* -------------------------------------------------------------------------- */
 template <ElementKind kind>
 template <ElementType type>
 void ShapeLagrange<kind>::interpolateOnIntegrationPoints(
     const Array<Real> & in_u, Array<Real> & out_uq, UInt nb_degree_of_freedom,
     const Array<Real> & shapes, GhostType ghost_type,
     const Array<UInt> & filter_elements) const {
   AKANTU_DEBUG_IN();
 
   UInt nb_nodes_per_element =
       ElementClass<type>::getNbNodesPerInterpolationElement();
 
   Array<Real> u_el(0, nb_degree_of_freedom * nb_nodes_per_element);
   FEEngine::extractNodalToElementField(mesh, in_u, u_el, type, ghost_type,
                                        filter_elements);
 
   this->interpolateElementalFieldOnIntegrationPoints<type>(
       u_el, out_uq, ghost_type, shapes, filter_elements);
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <ElementKind kind>
 template <ElementType type>
 void ShapeLagrange<kind>::interpolateOnIntegrationPoints(
     const Array<Real> & in_u, Array<Real> & out_uq, UInt nb_degree_of_freedom,
     GhostType ghost_type, const Array<UInt> & filter_elements) const {
   AKANTU_DEBUG_IN();
 
   InterpolationType itp_type = ElementClassProperty<type>::interpolation_type;
   AKANTU_DEBUG_ASSERT(shapes.exists(itp_type, ghost_type),
                       "No shapes for the type "
                           << shapes.printType(itp_type, ghost_type));
 
   this->interpolateOnIntegrationPoints<type>(in_u, out_uq, nb_degree_of_freedom,
                                              shapes(itp_type, ghost_type),
                                              ghost_type, filter_elements);
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <ElementKind kind>
 template <ElementType type>
 void ShapeLagrange<kind>::gradientOnIntegrationPoints(
     const Array<Real> & in_u, Array<Real> & out_nablauq,
     UInt nb_degree_of_freedom, GhostType ghost_type,
     const Array<UInt> & filter_elements) const {
   AKANTU_DEBUG_IN();
 
   InterpolationType itp_type = ElementClassProperty<type>::interpolation_type;
   AKANTU_DEBUG_ASSERT(
       shapes_derivatives.exists(itp_type, ghost_type),
       "No shapes derivatives for the type "
           << shapes_derivatives.printType(itp_type, ghost_type));
 
   UInt nb_nodes_per_element =
       ElementClass<type>::getNbNodesPerInterpolationElement();
 
   Array<Real> u_el(0, nb_degree_of_freedom * nb_nodes_per_element);
   FEEngine::extractNodalToElementField(mesh, in_u, u_el, type, ghost_type,
                                        filter_elements);
 
   this->gradientElementalFieldOnIntegrationPoints<type>(
       u_el, out_nablauq, ghost_type, shapes_derivatives(itp_type, ghost_type),
       filter_elements);
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <ElementKind kind>
 template <ElementType type>
 void ShapeLagrange<kind>::computeBtD(
     const Array<Real> & Ds, Array<Real> & BtDs, GhostType ghost_type,
     const Array<UInt> & filter_elements) const {
   auto itp_type = ElementClassProperty<type>::interpolation_type;
   const auto & shapes_derivatives =
       this->shapes_derivatives(itp_type, ghost_type);
 
   auto spatial_dimension = mesh.getSpatialDimension();
   auto nb_nodes_per_element = mesh.getNbNodesPerElement(type);
 
   Array<Real> shapes_derivatives_filtered(0,
                                           shapes_derivatives.getNbComponent());
   auto && view =
       make_view(shapes_derivatives, spatial_dimension, nb_nodes_per_element);
   auto B_it = view.begin();
   auto B_end = view.end();
 
   if (filter_elements != empty_filter) {
     FEEngine::filterElementalData(this->mesh, shapes_derivatives,
                                   shapes_derivatives_filtered, type, ghost_type,
                                   filter_elements);
     auto && view = make_view(shapes_derivatives_filtered, spatial_dimension,
                              nb_nodes_per_element);
     B_it = view.begin();
     B_end = view.end();
   }
 
   for (auto && values :
        zip(range(B_it, B_end),
            make_view(Ds, Ds.getNbComponent() / spatial_dimension,
                      spatial_dimension),
            make_view(BtDs, BtDs.getNbComponent() / nb_nodes_per_element,
                      nb_nodes_per_element))) {
     const auto & B = std::get<0>(values);
     const auto & D = std::get<1>(values);
     auto & Bt_D = std::get<2>(values);
     // transposed due to the storage layout of B
     Bt_D.template mul<false, false>(D, B);
   }
 }
 
 /* -------------------------------------------------------------------------- */
 template <ElementKind kind>
 template <ElementType type>
 void ShapeLagrange<kind>::computeBtDB(
     const Array<Real> & Ds, Array<Real> & BtDBs, UInt order_d,
     GhostType ghost_type, const Array<UInt> & filter_elements) const {
   auto itp_type = ElementClassProperty<type>::interpolation_type;
   const auto & shapes_derivatives =
       this->shapes_derivatives(itp_type, ghost_type);
 
   constexpr auto dim = ElementClass<type>::getSpatialDimension();
   auto nb_nodes_per_element = mesh.getNbNodesPerElement(type);
 
   Array<Real> shapes_derivatives_filtered(0,
                                           shapes_derivatives.getNbComponent());
   auto && view = make_view(shapes_derivatives, dim, nb_nodes_per_element);
   auto B_it = view.begin();
   auto B_end = view.end();
 
   if (filter_elements != empty_filter) {
     FEEngine::filterElementalData(this->mesh, shapes_derivatives,
                                   shapes_derivatives_filtered, type, ghost_type,
                                   filter_elements);
     auto && view =
         make_view(shapes_derivatives_filtered, dim, nb_nodes_per_element);
     B_it = view.begin();
     B_end = view.end();
   }
 
   if (order_d == 4) {
     UInt tangent_size = VoigtHelper<dim>::size;
     Matrix<Real> B(tangent_size, dim * nb_nodes_per_element);
     Matrix<Real> Bt_D(dim * nb_nodes_per_element, tangent_size);
 
     for (auto && values :
          zip(range(B_it, B_end), make_view(Ds, tangent_size, tangent_size),
              make_view(BtDBs, dim * nb_nodes_per_element,
                        dim * nb_nodes_per_element))) {
       const auto & Bfull = std::get<0>(values);
       const auto & D = std::get<1>(values);
       auto & Bt_D_B = std::get<2>(values);
 
       VoigtHelper<dim>::transferBMatrixToSymVoigtBMatrix(Bfull, B,
                                                          nb_nodes_per_element);
       Bt_D.template mul<true, false>(B, D);
       Bt_D_B.template mul<false, false>(Bt_D, B);
     }
   } else if (order_d == 2) {
     Matrix<Real> Bt_D(nb_nodes_per_element, dim);
     for (auto && values :
          zip(range(B_it, B_end), make_view(Ds, dim, dim),
              make_view(BtDBs, nb_nodes_per_element, nb_nodes_per_element))) {
       const auto & B = std::get<0>(values);
       const auto & D = std::get<1>(values);
       auto & Bt_D_B = std::get<2>(values);
       Bt_D.template mul<true, false>(B, D);
       Bt_D_B.template mul<false, false>(Bt_D, B);
     }
   }
 }
 
 template <>
 template <>
 inline void ShapeLagrange<_ek_regular>::computeBtDB<_point_1>(
     const Array<Real> & /*Ds*/, Array<Real> & /*BtDBs*/, UInt /*order_d*/,
     GhostType /*ghost_type*/, const Array<UInt> & /*filter_elements*/) const {
   AKANTU_TO_IMPLEMENT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <ElementKind kind>
 template <ElementType type>
 void ShapeLagrange<kind>::fieldTimesShapes(const Array<Real> & field,
                                            Array<Real> & field_times_shapes,
                                            GhostType ghost_type) const {
   AKANTU_DEBUG_IN();
 
   field_times_shapes.resize(field.size());
 
   UInt size_of_shapes = ElementClass<type>::getShapeSize();
   InterpolationType itp_type = ElementClassProperty<type>::interpolation_type;
   UInt nb_degree_of_freedom = field.getNbComponent();
 
   const auto & shape = shapes(itp_type, ghost_type);
 
   auto field_it = field.begin(nb_degree_of_freedom, 1);
   auto shapes_it = shape.begin(1, size_of_shapes);
 
   auto it = field_times_shapes.begin(nb_degree_of_freedom, size_of_shapes);
   auto end = field_times_shapes.end(nb_degree_of_freedom, size_of_shapes);
 
   for (; it != end; ++it, ++field_it, ++shapes_it) {
     it->template mul<false, false>(*field_it, *shapes_it);
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 } // namespace akantu
 
 #endif /* __AKANTU_SHAPE_LAGRANGE_INLINE_IMPL_CC__ */
diff --git a/src/fe_engine/shape_structural.cc b/src/fe_engine/shape_structural.cc
index cf7315dd2..ef9b443c0 100644
--- a/src/fe_engine/shape_structural.cc
+++ b/src/fe_engine/shape_structural.cc
@@ -1,53 +1,53 @@
 /**
  * @file   shape_structural.cc
  *
  * @author Fabian Barras <fabian.barras@epfl.ch>
+ * @author Lucas Frerot <lucas.frerot@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
- * @date creation: Fri Jul 15 2011
- * @date last modification: Sun Oct 19 2014
+ * @date creation: Thu Feb 21 2013
+ * @date last modification: Thu Dec 21 2017
  *
  * @brief  ShapeStructural implementation
  *
  * @section LICENSE
  *
- * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
- * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
- * Solides)
+ * 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
+ * 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
+ * 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 "shape_structural.hh"
 #include "aka_memory.hh"
 #include "mesh.hh"
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 template <>
 ShapeStructural<_ek_structural>::ShapeStructural(Mesh & mesh, const ID & id,
                                                  const MemoryID & memory_id)
     : ShapeFunctions(mesh, id, memory_id),
       rotation_matrices("rotation_matrices", id, memory_id) {}
 
 /* -------------------------------------------------------------------------- */
 template <> ShapeStructural<_ek_structural>::~ShapeStructural() = default;
 
 /* -------------------------------------------------------------------------- */
 
 } // namespace akantu
diff --git a/src/fe_engine/shape_structural.hh b/src/fe_engine/shape_structural.hh
index bd888aa0e..cefe2841f 100644
--- a/src/fe_engine/shape_structural.hh
+++ b/src/fe_engine/shape_structural.hh
@@ -1,177 +1,176 @@
 /**
  * @file   shape_structural.hh
  *
  * @author Fabian Barras <fabian.barras@epfl.ch>
+ * @author Lucas Frerot <lucas.frerot@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Tue Feb 15 2011
- * @date last modification: Thu Oct 22 2015
+ * @date last modification: Tue Feb 20 2018
  *
  * @brief  shape class for element with different set of shapes functions
  *
  * @section LICENSE
  *
- * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
- * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
- * Solides)
+ * 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
+ * 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
+ * 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 "shape_functions.hh"
 /* -------------------------------------------------------------------------- */
 
 #ifndef __AKANTU_SHAPE_STRUCTURAL_HH__
 #define __AKANTU_SHAPE_STRUCTURAL_HH__
 
 namespace akantu {
 
 template <ElementKind kind> class ShapeStructural : public ShapeFunctions {
   /* ------------------------------------------------------------------------ */
   /* Constructors/Destructors                                                 */
   /* ------------------------------------------------------------------------ */
   // Ctors/Dtors should be explicitely implemented for _ek_structural
 public:
   ShapeStructural(Mesh & mesh, const ID & id = "shape_structural",
                   const MemoryID & memory_id = 0);
   ~ShapeStructural() override;
 
   /* ------------------------------------------------------------------------ */
   /* Methods                                                                  */
   /* ------------------------------------------------------------------------ */
 public:
   /// function to print the contain of the class
   void printself(std::ostream & stream, int indent = 0) const override {
     std::string space;
     for (Int i = 0; i < indent; i++, space += AKANTU_INDENT)
       ;
     stream << space << "ShapesStructural [" << std::endl;
     rotation_matrices.printself(stream, indent + 1);
     ShapeFunctions::printself(stream, indent + 1);
     stream << space << "]" << std::endl;
   }
 
   /// compute shape functions on given integration points
   template <ElementType type>
   void computeShapesOnIntegrationPoints(
       const Array<Real> &, const Matrix<Real> & integration_points,
       Array<Real> & shapes, const GhostType & ghost_type,
       const Array<UInt> & filter_elements = empty_filter) const;
 
   /// initialization function for structural elements
   inline void initShapeFunctions(const Array<Real> & nodes,
                                  const Matrix<Real> & integration_points,
                                  const ElementType & type,
                                  const GhostType & ghost_type);
 
   /// precompute the rotation matrices for the elements dofs
   template <ElementType type>
   void precomputeRotationMatrices(const Array<Real> & nodes,
                                   const GhostType & ghost_type);
 
   /// pre compute all shapes on the element integration points from natural
   /// coordinates
   template <ElementType type>
   void precomputeShapesOnIntegrationPoints(const Array<Real> & nodes,
                                            const GhostType & ghost_type);
 
   /// pre compute all shapes on the element integration points from natural
   /// coordinates
   template <ElementType type>
   void
   precomputeShapeDerivativesOnIntegrationPoints(const Array<Real> & nodes,
                                                 const GhostType & ghost_type);
 
   /// interpolate nodal values on the integration points
   template <ElementType type>
   void interpolateOnIntegrationPoints(
       const Array<Real> & u, Array<Real> & uq, UInt nb_degree_of_freedom,
       const GhostType & ghost_type = _not_ghost,
       const Array<UInt> & filter_elements = empty_filter) const;
 
   /// compute the gradient of u on the integration points
   template <ElementType type>
   void gradientOnIntegrationPoints(
       const Array<Real> & u, Array<Real> & nablauq, UInt nb_degree_of_freedom,
       const GhostType & ghost_type = _not_ghost,
       const Array<UInt> & filter_elements = empty_filter) const;
 
   /// interpolate on physical point
   template <ElementType type>
   void interpolate(const Vector<Real> & /*real_coords*/, UInt /*elem*/,
                    const Matrix<Real> & /*nodal_values*/,
                    Vector<Real> & /*interpolated*/,
                    const GhostType & /*ghost_type*/) const {
     AKANTU_TO_IMPLEMENT();
   }
 
   /// compute the shapes on a provided point
   template <ElementType type>
   void computeShapes(const Vector<Real> & /*real_coords*/, UInt /*elem*/,
                      Vector<Real> & /*shapes*/,
                      const GhostType & /*ghost_type*/) const {
     AKANTU_TO_IMPLEMENT();
   }
 
   /// compute the shape derivatives on a provided point
   template <ElementType type>
   void computeShapeDerivatives(const Matrix<Real> & /*real_coords*/,
                                UInt /*elem*/, Tensor3<Real> & /*shapes*/,
                                const GhostType & /*ghost_type*/) const {
     AKANTU_TO_IMPLEMENT();
   }
 
   /// multiply a field by shape functions
   template <ElementType type>
   void
   fieldTimesShapes(__attribute__((unused)) const Array<Real> & field,
                    __attribute__((unused)) Array<Real> & field_times_shapes,
                    __attribute__((unused)) const GhostType & ghost_type) const {
     AKANTU_TO_IMPLEMENT();
   }
 
   /// get the rotations vector
   inline const Array<Real> &
   getRotations(const ElementType & el_type,
                __attribute__((unused))
                const GhostType & ghost_type = _not_ghost) const {
     return rotation_matrices(el_type);
   }
 
   template <ElementType type>
   void computeBtD(const Array<Real> & /*Ds*/, Array<Real> & /*BtDs*/,
                   GhostType /*ghost_type*/,
                   const Array<UInt> & /*filter_elements*/) const {
     AKANTU_TO_IMPLEMENT();
   }
 
   template <ElementType type>
   void computeBtDB(const Array<Real> & /*Ds*/, Array<Real> & /*BtDBs*/,
                    UInt /*order_d*/, GhostType /*ghost_type*/,
                    const Array<UInt> & /*filter_elements*/) const {
     AKANTU_TO_IMPLEMENT();
   }
 
 protected:
   ElementTypeMapArray<Real> rotation_matrices;
 };
 
 } // namespace akantu
 
 #include "shape_structural_inline_impl.cc"
 
 #endif /* __AKANTU_SHAPE_STRUCTURAL_HH__ */
diff --git a/src/fe_engine/shape_structural_inline_impl.cc b/src/fe_engine/shape_structural_inline_impl.cc
index 1919521a3..b13bc8b4d 100644
--- a/src/fe_engine/shape_structural_inline_impl.cc
+++ b/src/fe_engine/shape_structural_inline_impl.cc
@@ -1,430 +1,431 @@
 /**
  * @file   shape_structural_inline_impl.cc
  *
  * @author Fabian Barras <fabian.barras@epfl.ch>
+ * @author Lucas Frerot <lucas.frerot@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
- * @date creation: Mon Dec 13 2010
- * @date last modification: Thu Oct 15 2015
+ * @date creation: Wed Oct 11 2017
+ * @date last modification: Wed Feb 21 2018
  *
  * @brief  ShapeStructural inline implementation
  *
  * @section LICENSE
  *
- * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
- * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
- * Solides)
+ * 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
+ * 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
+ * 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 "mesh_iterators.hh"
 #include "shape_structural.hh"
 /* -------------------------------------------------------------------------- */
 
 #ifndef __AKANTU_SHAPE_STRUCTURAL_INLINE_IMPL_CC__
 #define __AKANTU_SHAPE_STRUCTURAL_INLINE_IMPL_CC__
 
 namespace akantu {
 
 namespace {
   /// Extract nodal coordinates per elements
   template <ElementType type>
   std::unique_ptr<Array<Real>>
   getNodesPerElement(const Mesh & mesh, const Array<Real> & nodes,
                      const GhostType & ghost_type) {
     const auto dim = ElementClass<type>::getSpatialDimension();
     const auto nb_nodes_per_element = Mesh::getNbNodesPerElement(type);
 
     auto nodes_per_element =
         std::make_unique<Array<Real>>(0, dim * nb_nodes_per_element);
     FEEngine::extractNodalToElementField(mesh, nodes, *nodes_per_element, type,
                                          ghost_type);
     return nodes_per_element;
   }
 }
 
 template <ElementKind kind>
 inline void ShapeStructural<kind>::initShapeFunctions(
     const Array<Real> & /* unused */, const Matrix<Real> & /* unused */,
     const ElementType & /* unused */, const GhostType & /* unused */) {
   AKANTU_TO_IMPLEMENT();
 }
 
 /* -------------------------------------------------------------------------- */
 #define INIT_SHAPE_FUNCTIONS(type)                                             \
   setIntegrationPointsByType<type>(integration_points, ghost_type);            \
   precomputeRotationMatrices<type>(nodes, ghost_type);                         \
   precomputeShapesOnIntegrationPoints<type>(nodes, ghost_type);                \
   precomputeShapeDerivativesOnIntegrationPoints<type>(nodes, ghost_type);
 
 template <>
 inline void ShapeStructural<_ek_structural>::initShapeFunctions(
     const Array<Real> & nodes, const Matrix<Real> & integration_points,
     const ElementType & type, const GhostType & ghost_type) {
   AKANTU_BOOST_STRUCTURAL_ELEMENT_SWITCH(INIT_SHAPE_FUNCTIONS);
 }
 
 #undef INIT_SHAPE_FUNCTIONS
 
 /* -------------------------------------------------------------------------- */
 template <>
 template <ElementType type>
 void ShapeStructural<_ek_structural>::computeShapesOnIntegrationPoints(
     const Array<Real> & nodes, const Matrix<Real> & integration_points,
     Array<Real> & shapes, const GhostType & ghost_type,
     const Array<UInt> & filter_elements) const {
 
   UInt nb_points = integration_points.cols();
   UInt nb_element = mesh.getConnectivity(type, ghost_type).size();
 
   shapes.resize(nb_element * nb_points);
 
   UInt ndof = ElementClass<type>::getNbDegreeOfFreedom();
 
 #if !defined(AKANTU_NDEBUG)
   UInt size_of_shapes = ElementClass<type>::getShapeSize();
   AKANTU_DEBUG_ASSERT(shapes.getNbComponent() == size_of_shapes,
                       "The shapes array does not have the correct "
                           << "number of component");
 #endif
 
   auto shapes_it = shapes.begin_reinterpret(
       ElementClass<type>::getNbNodesPerInterpolationElement(), ndof, nb_points,
       nb_element);
 
   auto shapes_begin = shapes_it;
   if (filter_elements != empty_filter) {
     nb_element = filter_elements.size();
   }
 
   auto nodes_per_element = getNodesPerElement<type>(mesh, nodes, ghost_type);
   auto nodes_it = nodes_per_element->begin(mesh.getSpatialDimension(),
                                            Mesh::getNbNodesPerElement(type));
   auto nodes_begin = nodes_it;
 
   for (UInt elem = 0; elem < nb_element; ++elem) {
     if (filter_elements != empty_filter) {
       shapes_it = shapes_begin + filter_elements(elem);
       nodes_it = nodes_begin + filter_elements(elem);
     }
 
     Tensor3<Real> & N = *shapes_it;
     auto & real_coord = *nodes_it;
     ElementClass<type>::computeShapes(integration_points, real_coord, N);
 
     if (filter_elements == empty_filter)
       ++shapes_it;
   }
 }
 
 /* -------------------------------------------------------------------------- */
 template <ElementKind kind>
 template <ElementType type>
 void ShapeStructural<kind>::precomputeRotationMatrices(
     const Array<Real> & nodes, const GhostType & ghost_type) {
   AKANTU_DEBUG_IN();
 
   const auto spatial_dimension = mesh.getSpatialDimension();
   const auto nb_nodes_per_element = Mesh::getNbNodesPerElement(type);
   const auto nb_element = mesh.getNbElement(type, ghost_type);
   const auto nb_dof = ElementClass<type>::getNbDegreeOfFreedom();
 
   if (not this->rotation_matrices.exists(type, ghost_type)) {
     this->rotation_matrices.alloc(0, nb_dof * nb_dof, type, ghost_type);
   }
 
   auto & rot_matrices = this->rotation_matrices(type, ghost_type);
   rot_matrices.resize(nb_element);
 
   Array<Real> x_el(0, spatial_dimension * nb_nodes_per_element);
   FEEngine::extractNodalToElementField(mesh, nodes, x_el, type, ghost_type);
 
   bool has_extra_normal = mesh.hasData<Real>("extra_normal", type, ghost_type);
   Array<Real>::const_vector_iterator extra_normal;
   if (has_extra_normal)
     extra_normal = mesh.getData<Real>("extra_normal", type, ghost_type)
                        .begin(spatial_dimension);
 
   for (auto && tuple :
        zip(make_view(x_el, spatial_dimension, nb_nodes_per_element),
            make_view(rot_matrices, nb_dof, nb_dof))) {
     // compute shape derivatives
     auto & X = std::get<0>(tuple);
     auto & R = std::get<1>(tuple);
 
     if (has_extra_normal) {
       ElementClass<type>::computeRotationMatrix(R, X, *extra_normal);
       ++extra_normal;
     } else {
       ElementClass<type>::computeRotationMatrix(
           R, X, Vector<Real>(spatial_dimension));
     }
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 
 template <ElementKind kind>
 template <ElementType type>
 void ShapeStructural<kind>::precomputeShapesOnIntegrationPoints(
     const Array<Real> & nodes, const GhostType & ghost_type) {
   AKANTU_DEBUG_IN();
 
   const auto & natural_coords = integration_points(type, ghost_type);
   auto nb_nodes_per_element = Mesh::getNbNodesPerElement(type);
   auto nb_points = integration_points(type, ghost_type).cols();
   auto nb_element = mesh.getNbElement(type, ghost_type);
   auto nb_dof = ElementClass<type>::getNbDegreeOfFreedom();
   const auto dim = ElementClass<type>::getSpatialDimension();
 
   auto itp_type = FEEngine::getInterpolationType(type);
   if (not shapes.exists(itp_type, ghost_type)) {
     auto size_of_shapes = this->getShapeSize(type);
     this->shapes.alloc(0, size_of_shapes, itp_type, ghost_type);
   }
 
   auto & shapes_ = this->shapes(itp_type, ghost_type);
   shapes_.resize(nb_element * nb_points);
 
   auto nodes_per_element = getNodesPerElement<type>(mesh, nodes, ghost_type);
 
   for (auto && tuple :
        zip(make_view(shapes_, nb_dof, nb_dof * nb_nodes_per_element, nb_points),
            make_view(*nodes_per_element, dim, nb_nodes_per_element))) {
     auto & N = std::get<0>(tuple);
     auto & real_coord = std::get<1>(tuple);
     ElementClass<type>::computeShapes(natural_coords, real_coord, N);
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <ElementKind kind>
 template <ElementType type>
 void ShapeStructural<kind>::precomputeShapeDerivativesOnIntegrationPoints(
     const Array<Real> & nodes, const GhostType & ghost_type) {
   AKANTU_DEBUG_IN();
 
   const auto & natural_coords = integration_points(type, ghost_type);
   const auto spatial_dimension = mesh.getSpatialDimension();
   const auto natural_spatial_dimension =
       ElementClass<type>::getNaturalSpaceDimension();
   const auto nb_nodes_per_element = Mesh::getNbNodesPerElement(type);
   const auto nb_points = natural_coords.cols();
   const auto nb_dof = ElementClass<type>::getNbDegreeOfFreedom();
   const auto nb_element = mesh.getNbElement(type, ghost_type);
   const auto nb_stress_components = ElementClass<type>::getNbStressComponents();
 
   auto itp_type = FEEngine::getInterpolationType(type);
   if (not this->shapes_derivatives.exists(itp_type, ghost_type)) {
     auto size_of_shapesd = this->getShapeDerivativesSize(type);
     this->shapes_derivatives.alloc(0, size_of_shapesd, itp_type, ghost_type);
   }
 
   auto & rot_matrices = this->rotation_matrices(type, ghost_type);
 
   Array<Real> x_el(0, spatial_dimension * nb_nodes_per_element);
   FEEngine::extractNodalToElementField(mesh, nodes, x_el, type, ghost_type);
 
   auto & shapesd = this->shapes_derivatives(itp_type, ghost_type);
   shapesd.resize(nb_element * nb_points);
 
   for (auto && tuple :
        zip(make_view(x_el, spatial_dimension, nb_nodes_per_element),
            make_view(shapesd, nb_stress_components,
                      nb_nodes_per_element * nb_dof, nb_points),
            make_view(rot_matrices, nb_dof, nb_dof))) {
     // compute shape derivatives
     auto & X = std::get<0>(tuple);
     auto & B = std::get<1>(tuple);
     auto & RDOFs = std::get<2>(tuple);
 
     Tensor3<Real> dnds(natural_spatial_dimension,
                        ElementClass<type>::interpolation_property::dnds_columns,
                        B.size(2));
     ElementClass<type>::computeDNDS(natural_coords, X, dnds);
 
     Tensor3<Real> J(natural_spatial_dimension, natural_spatial_dimension,
                     natural_coords.cols());
 
     // Computing the coordinates of the element in the natural space
     auto R = RDOFs.block(0, 0, spatial_dimension, spatial_dimension);
     Matrix<Real> T(B.size(1), B.size(1), 0);
 
     for (UInt i = 0; i < nb_nodes_per_element; ++i) {
       T.block(RDOFs, i * RDOFs.rows(), i * RDOFs.rows());
     }
 
     // Rotate to local basis
     auto x =
         (R * X).block(0, 0, natural_spatial_dimension, nb_nodes_per_element);
 
     ElementClass<type>::computeJMat(natural_coords, x, J);
     ElementClass<type>::computeShapeDerivatives(J, dnds, T, B);
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <ElementKind kind>
 template <ElementType type>
 void ShapeStructural<kind>::interpolateOnIntegrationPoints(
     const Array<Real> & in_u, Array<Real> & out_uq, UInt nb_dof,
     const GhostType & ghost_type, const Array<UInt> & filter_elements) const {
   AKANTU_DEBUG_IN();
 
   AKANTU_DEBUG_ASSERT(out_uq.getNbComponent() == nb_dof,
                       "The output array shape is not correct");
 
   auto itp_type = FEEngine::getInterpolationType(type);
   const auto & shapes_ = shapes(itp_type, ghost_type);
 
   auto nb_element = mesh.getNbElement(type, ghost_type);
   auto nb_nodes_per_element = ElementClass<type>::getNbNodesPerElement();
   auto nb_quad_points_per_element = integration_points(type, ghost_type).cols();
 
   Array<Real> u_el(0, nb_nodes_per_element * nb_dof);
   FEEngine::extractNodalToElementField(mesh, in_u, u_el, type, ghost_type,
                                        filter_elements);
 
   auto nb_quad_points = nb_quad_points_per_element * u_el.size();
   out_uq.resize(nb_quad_points);
 
   auto out_it = out_uq.begin_reinterpret(nb_dof, 1, nb_quad_points_per_element,
                                          u_el.size());
   auto shapes_it =
       shapes_.begin_reinterpret(nb_dof, nb_dof * nb_nodes_per_element,
                                 nb_quad_points_per_element, nb_element);
   auto u_it = u_el.begin_reinterpret(nb_dof * nb_nodes_per_element, 1,
                                      nb_quad_points_per_element, u_el.size());
 
   for_each_element(nb_element, filter_elements, [&](auto && el) {
     auto & uq = *out_it;
     const auto & u = *u_it;
     auto N = Tensor3<Real>(shapes_it[el]);
 
     for (auto && q : arange(uq.size(2))) {
       auto uq_q = Matrix<Real>(uq(q));
       auto u_q = Matrix<Real>(u(q));
       auto N_q = Matrix<Real>(N(q));
 
       uq_q.mul<false, false>(N_q, u_q);
     }
 
     ++out_it;
     ++u_it;
   });
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <ElementKind kind>
 template <ElementType type>
 void ShapeStructural<kind>::gradientOnIntegrationPoints(
     const Array<Real> & in_u, Array<Real> & out_nablauq, UInt nb_dof,
     const GhostType & ghost_type, const Array<UInt> & filter_elements) const {
   AKANTU_DEBUG_IN();
 
   auto itp_type = FEEngine::getInterpolationType(type);
   const auto & shapesd = shapes_derivatives(itp_type, ghost_type);
 
   auto nb_element = mesh.getNbElement(type, ghost_type);
   auto element_dimension = ElementClass<type>::getSpatialDimension();
   auto nb_quad_points_per_element = integration_points(type, ghost_type).cols();
   auto nb_nodes_per_element = ElementClass<type>::getNbNodesPerElement();
 
   Array<Real> u_el(0, nb_nodes_per_element * nb_dof);
   FEEngine::extractNodalToElementField(mesh, in_u, u_el, type, ghost_type,
                                        filter_elements);
 
   auto nb_quad_points = nb_quad_points_per_element * u_el.size();
   out_nablauq.resize(nb_quad_points);
 
   auto out_it = out_nablauq.begin_reinterpret(
       element_dimension, 1, nb_quad_points_per_element, u_el.size());
   auto shapesd_it = shapesd.begin_reinterpret(
       element_dimension, nb_dof * nb_nodes_per_element,
       nb_quad_points_per_element, nb_element);
   auto u_it = u_el.begin_reinterpret(nb_dof * nb_nodes_per_element, 1,
                                      nb_quad_points_per_element, u_el.size());
 
   for_each_element(nb_element, filter_elements, [&](auto && el) {
     auto & nablau = *out_it;
     const auto & u = *u_it;
     auto B = Tensor3<Real>(shapesd_it[el]);
 
     for (auto && q : arange(nablau.size(2))) {
       auto nablau_q = Matrix<Real>(nablau(q));
       auto u_q = Matrix<Real>(u(q));
       auto B_q = Matrix<Real>(B(q));
 
       nablau_q.mul<false, false>(B_q, u_q);
     }
 
     ++out_it;
     ++u_it;
   });
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <>
 template <ElementType type>
 void ShapeStructural<_ek_structural>::computeBtD(
     const Array<Real> & Ds, Array<Real> & BtDs, GhostType ghost_type,
     const Array<UInt> & filter_elements) const {
   auto itp_type = ElementClassProperty<type>::interpolation_type;
 
   auto nb_stress = ElementClass<type>::getNbStressComponents();
   auto nb_dof_per_element = ElementClass<type>::getNbDegreeOfFreedom() *
                             mesh.getNbNodesPerElement(type);
 
   const auto & shapes_derivatives =
       this->shapes_derivatives(itp_type, ghost_type);
 
   Array<Real> shapes_derivatives_filtered(0,
                                           shapes_derivatives.getNbComponent());
   auto && view = make_view(shapes_derivatives, nb_stress, nb_dof_per_element);
   auto B_it = view.begin();
   auto B_end = view.end();
 
   if (filter_elements != empty_filter) {
     FEEngine::filterElementalData(this->mesh, shapes_derivatives,
                                   shapes_derivatives_filtered, type, ghost_type,
                                   filter_elements);
     auto && view =
         make_view(shapes_derivatives_filtered, nb_stress, nb_dof_per_element);
     B_it = view.begin();
     B_end = view.end();
   }
 
   for (auto && values : zip(range(B_it, B_end), make_view(Ds, nb_stress),
                             make_view(BtDs, BtDs.getNbComponent()))) {
     const auto & B = std::get<0>(values);
     const auto & D = std::get<1>(values);
     auto & Bt_D = std::get<2>(values);
     Bt_D.template mul<true>(B, D);
   }
 }
 
 } // namespace akantu
 
 #endif /* __AKANTU_SHAPE_STRUCTURAL_INLINE_IMPL_CC__ */
diff --git a/src/geometry/aabb_primitives/aabb_primitive.cc b/src/geometry/aabb_primitives/aabb_primitive.cc
index 56b56a7bd..93c51c16b 100644
--- a/src/geometry/aabb_primitives/aabb_primitive.cc
+++ b/src/geometry/aabb_primitives/aabb_primitive.cc
@@ -1,49 +1,49 @@
 /**
  * @file   aabb_primitive.cc
  *
  * @author Lucas Frerot <lucas.frerot@epfl.ch>
  * @author Clement Roux <clement.roux@epfl.ch>
  *
  * @date creation: Fri Jan 04 2013
- * @date last modification: Thu Jan 14 2016
+ * @date last modification: Wed Jan 31 2018
  *
  * @brief  Macro classe (primitive) for AABB CGAL algos
  *
  * @section LICENSE
  *
- * Copyright  (©)  2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de Lausanne)
+ * 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
+ * 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
+ * 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 "aabb_primitive.hh"
 
 namespace akantu {
 
 Triangle_primitive::Point Triangle_primitive::reference_point() const {
   return primitive.vertex(0);
 }
 
 Line_arc_primitive::Point Line_arc_primitive::reference_point() const {
   Real x = to_double(primitive.source().x());
   Real y = to_double(primitive.source().y());
   Real z = to_double(primitive.source().z());
   return cgal::Spherical::Point_3(x, y, z);
 }
 
 } // akantu
diff --git a/src/geometry/aabb_primitives/aabb_primitive.hh b/src/geometry/aabb_primitives/aabb_primitive.hh
index af9ac05f4..9bae09a10 100644
--- a/src/geometry/aabb_primitives/aabb_primitive.hh
+++ b/src/geometry/aabb_primitives/aabb_primitive.hh
@@ -1,89 +1,89 @@
 /**
  * @file   aabb_primitive.hh
  *
  * @author Lucas Frerot <lucas.frerot@epfl.ch>
  * @author Clement Roux <clement.roux@epfl.ch>
  *
  * @date creation: Fri Mar 13 2015
- * @date last modification: Thu Jan 14 2016
+ * @date last modification: Wed Jan 31 2018
  *
  * @brief  Macro classe (primitive) for AABB CGAL algos
  *
  * @section LICENSE
  *
- * Copyright (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne) Laboratory
- * (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * Copyright (©) 2015-2018 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
- * terms  of the  GNU Lesser  General Public  License as  published by  the Free
+ * 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
+ * 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_AABB_PRIMITIVE_HH__
 #define __AKANTU_AABB_PRIMITIVE_HH__
 
 #include "aka_common.hh"
 #include "line_arc.hh"
 #include "tetrahedron.hh"
 #include "triangle.hh"
 
 #include "mesh_geom_common.hh"
 
 namespace akantu {
 
 /**
  * This macro defines a class that is used in the CGAL AABB tree algorithm.
  * All the `typedef`s and methods are required by the AABB module.
  *
  * The member variables are
  *  - the id of the element associated to the primitive
  *  - the geometric primitive of the element
  *
  *  @param name the name of the primitive type
  *  @param kernel the name of the kernel used
  */
 #define AKANTU_AABB_CLASS(name, kernel)                                        \
   class name##_primitive {                                                     \
     typedef std::list<name<kernel>>::iterator Iterator;                        \
                                                                                \
   public:                                                                      \
     typedef UInt Id;                                                           \
     typedef kernel::Point_3 Point;                                             \
     typedef kernel::name##_3 Datum;                                            \
                                                                                \
   public:                                                                      \
     name##_primitive() : meshId(0), primitive() {}                             \
     name##_primitive(Iterator it) : meshId(it->id()), primitive(*it) {}        \
                                                                                \
   public:                                                                      \
     const Datum & datum() const { return primitive; }                          \
     Point reference_point() const;                                             \
     const Id & id() const { return meshId; }                                   \
                                                                                \
   protected:                                                                   \
     Id meshId;                                                                 \
     name<kernel> primitive;                                                    \
   }
 
 // If the primitive is supported by CGAL::intersection() then the
 // implementation process is really easy with this macro
 AKANTU_AABB_CLASS(Triangle, cgal::Cartesian);
 AKANTU_AABB_CLASS(Line_arc, cgal::Spherical);
 
 #undef AKANTU_AABB_CLASS
 
 } // akantu
 
 #endif // __AKANTU_AABB_PRIMITIVE_HH__
diff --git a/src/geometry/aabb_primitives/line_arc.hh b/src/geometry/aabb_primitives/line_arc.hh
index 603525067..611649790 100644
--- a/src/geometry/aabb_primitives/line_arc.hh
+++ b/src/geometry/aabb_primitives/line_arc.hh
@@ -1,77 +1,77 @@
 /**
  * @file   line_arc.hh
  *
  * @author Clement Roux <clement.roux@epfl.ch>
  *
  * @date creation: Fri Jan 04 2013
- * @date last modification: Thu Jan 14 2016
+ * @date last modification: Mon Jun 19 2017
  *
  * @brief  Segment classe (geometry) for AABB CGAL algos
  *
  * @section LICENSE
  *
- * Copyright  (©)  2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de Lausanne)
+ * 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
+ * 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
+ * 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_LINE_ARC_HH__
 #define __AKANTU_LINE_ARC_HH__
 
 #include "aka_common.hh"
 
 #include "mesh_geom_common.hh"
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 
 /// Class used for substitution of CGAL::Triangle_3 primitive
 template <typename K> class Line_arc : public CGAL::Line_arc_3<K> {
 public:
   /// Default constructor
   Line_arc() : CGAL::Line_arc_3<K>(), mesh_id(0), seg_id(0) {}
 
   /// Copy constructor
   Line_arc(const Line_arc & other)
       : CGAL::Line_arc_3<K>(other), mesh_id(other.mesh_id),
         seg_id(other.seg_id) {}
 
   /// Construct from 3 points
   // "CGAL-4.5/doc_html/Circular_kernel_3/classCGAL_1_1Line__arc__3.html"
   Line_arc(const CGAL::Line_3<K> & l, const CGAL::Circular_arc_point_3<K> & a,
            const CGAL::Circular_arc_point_3<K> & b)
       : CGAL::Line_arc_3<K>(l, a, b), mesh_id(0), seg_id(0) {}
 
 public:
   UInt id() const { return mesh_id; }
   UInt segId() const { return seg_id; }
   void setId(UInt newId) { mesh_id = newId; }
   void setSegId(UInt newId) { seg_id = newId; }
 
 protected:
   /// Id of the element represented by the primitive
   UInt mesh_id;
 
   /// Id of the segment represented by the primitive
   UInt seg_id;
 };
 
 } // akantu
 
 #endif // __AKANTU_LINE_ARC_HH__
diff --git a/src/geometry/aabb_primitives/tetrahedron.hh b/src/geometry/aabb_primitives/tetrahedron.hh
index c6d31b3de..64e7855a7 100644
--- a/src/geometry/aabb_primitives/tetrahedron.hh
+++ b/src/geometry/aabb_primitives/tetrahedron.hh
@@ -1,70 +1,70 @@
 /**
  * @file   tetrahedron.hh
  *
  * @author Lucas Frerot <lucas.frerot@epfl.ch>
  *
  * @date creation: Fri Feb 27 2015
- * @date last modification: Thu Jan 14 2016
+ * @date last modification: Mon Jun 19 2017
  *
  * @brief  Tetrahedron classe (geometry) for AABB CGAL algos
  *
  * @section LICENSE
  *
- * Copyright (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne) Laboratory
- * (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * Copyright (©) 2015-2018 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
- * terms  of the  GNU Lesser  General Public  License as  published by  the Free
+ * 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
+ * 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_TETRAHEDRON_HH__
 #define __AKANTU_TETRAHEDRON_HH__
 
 #include "aka_common.hh"
 
 #include "mesh_geom_common.hh"
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 
 /// Class used for substitution of CGAL::Tetrahedron_3 primitive
 template <typename K> class Tetrahedron : public CGAL::Tetrahedron_3<K> {
 public:
   /// Default constructor
   Tetrahedron() : CGAL::Tetrahedron_3<K>(), meshId(0) {}
 
   /// Copy constructor
   Tetrahedron(const Tetrahedron & other)
       : CGAL::Tetrahedron_3<K>(other), meshId(other.meshId) {}
 
   /// Construct from 4 points
   Tetrahedron(const CGAL::Point_3<K> & a, const CGAL::Point_3<K> & b,
               const CGAL::Point_3<K> & c, const CGAL::Point_3<K> & d)
       : CGAL::Tetrahedron_3<K>(a, b, c, d), meshId(0) {}
 
 public:
   UInt id() const { return meshId; }
   void setId(UInt newId) { meshId = newId; }
 
 protected:
   /// Id of the element represented by the primitive
   UInt meshId;
 };
 
 } // akantu
 
 #endif
diff --git a/src/geometry/aabb_primitives/triangle.hh b/src/geometry/aabb_primitives/triangle.hh
index 90a36b4bd..17d7b194a 100644
--- a/src/geometry/aabb_primitives/triangle.hh
+++ b/src/geometry/aabb_primitives/triangle.hh
@@ -1,70 +1,70 @@
 /**
  * @file   triangle.hh
  *
  * @author Lucas Frerot <lucas.frerot@epfl.ch>
  *
  * @date creation: Fri Jan 04 2013
- * @date last modification: Thu Jan 14 2016
+ * @date last modification: Mon Jun 19 2017
  *
  * @brief  Triangle classe (geometry) for AABB CGAL algos
  *
  * @section LICENSE
  *
- * Copyright  (©)  2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de Lausanne)
+ * 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
+ * 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
+ * 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_TRIANGLE_HH__
 #define __AKANTU_TRIANGLE_HH__
 
 #include "aka_common.hh"
 
 #include "mesh_geom_common.hh"
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 
 /// Class used for substitution of CGAL::Triangle_3 primitive
 template <typename K> class Triangle : public CGAL::Triangle_3<K> {
 public:
   /// Default constructor
   Triangle() : CGAL::Triangle_3<K>(), meshId(0) {}
 
   /// Copy constructor
   Triangle(const Triangle & other)
       : CGAL::Triangle_3<K>(other), meshId(other.meshId) {}
 
   /// Construct from 3 points
   Triangle(const CGAL::Point_3<K> & a, const CGAL::Point_3<K> & b,
            const CGAL::Point_3<K> & c)
       : CGAL::Triangle_3<K>(a, b, c), meshId(0) {}
 
 public:
   UInt id() const { return meshId; }
   void setId(UInt newId) { meshId = newId; }
 
 protected:
   /// Id of the element represented by the primitive
   UInt meshId;
 };
 
 } // akantu
 
 #endif // __AKANTU_TRIANGLE_HH__
diff --git a/src/geometry/geom_helper_functions.hh b/src/geometry/geom_helper_functions.hh
index 0d68d20e2..f3cc29d22 100644
--- a/src/geometry/geom_helper_functions.hh
+++ b/src/geometry/geom_helper_functions.hh
@@ -1,112 +1,112 @@
 /**
  * @file   geom_helper_functions.hh
  *
  * @author Lucas Frerot <lucas.frerot@epfl.ch>
  * @author Clement Roux <clement.roux@epfl.ch>
  *
  * @date creation: Fri Jan 04 2013
- * @date last modification: Thu Jan 14 2016
+ * @date last modification: Wed Jan 31 2018
  *
  * @brief  Helper functions for the computational geometry algorithms
  *
  * @section LICENSE
  *
- * Copyright  (©)  2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de Lausanne)
+ * 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
+ * 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
+ * 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_GEOM_HELPER_FUNCTIONS_HH__
 #define _AKANTU_GEOM_HELPER_FUNCTIONS_HH__
 
 #include "aka_common.hh"
 #include "aka_math.hh"
 #include "tree_type_helper.hh"
 
 #include "mesh_geom_common.hh"
 
 namespace akantu {
 
 /// Fuzzy compare of two points
 template <class Point>
 inline bool comparePoints(const Point & a, const Point & b) {
   return Math::are_float_equal(a.x(), b.x()) &&
          Math::are_float_equal(a.y(), b.y()) &&
          Math::are_float_equal(a.z(), b.z());
 }
 
 template <>
 inline bool comparePoints(const cgal::Spherical::Circular_arc_point_3 & a,
                           const cgal::Spherical::Circular_arc_point_3 & b) {
   return Math::are_float_equal(CGAL::to_double(a.x()),
                                CGAL::to_double(b.x())) &&
          Math::are_float_equal(CGAL::to_double(a.y()),
                                CGAL::to_double(b.y())) &&
          Math::are_float_equal(CGAL::to_double(a.z()), CGAL::to_double(b.z()));
 }
 
 /// Fuzzy compare of two segments
 template <class K>
 inline bool compareSegments(const CGAL::Segment_3<K> & a,
                             const CGAL::Segment_3<K> & b) {
   return (comparePoints(a.source(), b.source()) &&
           comparePoints(a.target(), b.target())) ||
          (comparePoints(a.source(), b.target()) &&
           comparePoints(a.target(), b.source()));
 }
 
 /// Compare segment pairs
 inline bool
 compareSegmentPairs(const std::pair<cgal::Cartesian::Segment_3, UInt> & a,
                     const std::pair<cgal::Cartesian::Segment_3, UInt> & b) {
   return compareSegments(a.first, b.first);
 }
 
 /// Pair ordering operator based on first member
 struct segmentPairsLess {
   inline bool
   operator()(const std::pair<cgal::Cartesian::Segment_3, UInt> & a,
              const std::pair<cgal::Cartesian::Segment_3, UInt> & b) {
     return CGAL::compare_lexicographically(a.first.min(), b.first.min()) ||
            CGAL::compare_lexicographically(a.first.max(), b.first.max());
   }
 };
 
 /* -------------------------------------------------------------------------- */
 /* Predicates                                                                 */
 /* -------------------------------------------------------------------------- */
 
 /// Predicate used to determine if two segments are equal
 class IsSameSegment {
 
 public:
   IsSameSegment(const cgal::Cartesian::Segment_3 & segment)
       : segment(segment) {}
 
   bool
   operator()(const std::pair<cgal::Cartesian::Segment_3, UInt> & test_pair) {
     return compareSegments(segment, test_pair.first);
   }
 
 protected:
   const cgal::Cartesian::Segment_3 segment;
 };
 
 } // akantu
 
 #endif // _AKANTU_GEOM_HELPER_FUNCTIONS_HH__
diff --git a/src/geometry/mesh_abstract_intersector.hh b/src/geometry/mesh_abstract_intersector.hh
index 5467a673b..2bf1c1b29 100644
--- a/src/geometry/mesh_abstract_intersector.hh
+++ b/src/geometry/mesh_abstract_intersector.hh
@@ -1,121 +1,121 @@
 /**
  * @file   mesh_abstract_intersector.hh
  *
  * @author Lucas Frerot <lucas.frerot@epfl.ch>
  * @author Clement Roux <clement.roux@epfl.ch>
  * @author Marco Vocialta <marco.vocialta@epfl.ch>
  *
  * @date creation: Wed Apr 29 2015
- * @date last modification: Thu Jan 14 2016
+ * @date last modification: Mon Jun 19 2017
  *
  * @brief  Abstract class for intersection computations
  *
  * @section LICENSE
  *
- * Copyright (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne) Laboratory
- * (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * Copyright (©) 2015-2018 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
- * terms  of the  GNU Lesser  General Public  License as  published by  the Free
+ * 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
+ * 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_MESH_ABSTRACT_INTERSECTOR_HH__
 #define __AKANTU_MESH_ABSTRACT_INTERSECTOR_HH__
 
 #include "aka_common.hh"
 #include "mesh_geom_abstract.hh"
 
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 
 /**
  * @brief Class used to perform intersections on a mesh and construct output
  * data
  */
 template <class Query> class MeshAbstractIntersector : public MeshGeomAbstract {
 
 public:
   /// Construct from mesh
   explicit MeshAbstractIntersector(Mesh & mesh);
 
   /// Destructor
   virtual ~MeshAbstractIntersector();
 
 public:
   /* ------------------------------------------------------------------------ */
   /* Accessors                                                                */
   /* ------------------------------------------------------------------------ */
 public:
   /// get the new_node_per_elem array
   AKANTU_GET_MACRO(NewNodePerElem, *new_node_per_elem, const Array<UInt> &);
   /// get the intersection_points array
   AKANTU_GET_MACRO(IntersectionPoints, intersection_points,
                    const Array<Real> *);
   /// get the nb_seg_by_el UInt
   AKANTU_GET_MACRO(NbSegByEl, nb_seg_by_el, UInt);
 
   /**
    * @brief Compute the intersection with a query object
    *
    * This function needs to be implemented for every subclass. It computes the
    * intersections
    * with the tree of primitives and creates the data for the user.
    *
    * @param query the CGAL primitive of the query object
    */
   virtual void computeIntersectionQuery(const Query & query) = 0;
 
   /// Compute intersection points between the mesh primitives (segments) and a
   /// query (surface in 3D or a curve in 2D), double intersection points for the
   /// same primitives are not considered. A maximum intersection node per
   /// element is set : 2 in 2D and 4 in 3D
   virtual void computeMeshQueryIntersectionPoint(const Query & query,
                                                  UInt nb_old_nodes) = 0;
 
   /// Compute intersection between the mesh and a list of queries
   virtual void
   computeIntersectionQueryList(const std::list<Query> & query_list);
 
   /// Compute intersection points between the mesh and a list of queries
   virtual void
   computeMeshQueryListIntersectionPoint(const std::list<Query> & query_list,
                                         UInt nb_old_nodes);
 
   /// Compute whatever result is needed from the user (should be move to the
   /// appropriate specific classe for genericity)
   virtual void
   buildResultFromQueryList(const std::list<Query> & query_list) = 0;
 
 protected:
   /// new node per element (column 0: number of new nodes, then odd is the
   /// intersection node number and even the ID of the intersected segment)
   Array<UInt> * new_node_per_elem;
 
   /// intersection output: new intersection points
   /// (computeMeshQueryListIntersectionPoint)
   Array<Real> * intersection_points;
 
   /// number of segment in a considered element of the templated type of element
   /// specialized intersector
   const UInt nb_seg_by_el;
 };
 
 } // akantu
 
 #include "mesh_abstract_intersector_tmpl.hh"
 
 #endif // __AKANTU_MESH_ABSTRACT_INTERSECTOR_HH__
diff --git a/src/geometry/mesh_abstract_intersector_tmpl.hh b/src/geometry/mesh_abstract_intersector_tmpl.hh
index 8ed2a1da4..ccd833882 100644
--- a/src/geometry/mesh_abstract_intersector_tmpl.hh
+++ b/src/geometry/mesh_abstract_intersector_tmpl.hh
@@ -1,83 +1,83 @@
 /**
  * @file   mesh_abstract_intersector_tmpl.hh
  *
  * @author Lucas Frerot <lucas.frerot@epfl.ch>
  * @author Clement Roux <clement.roux@epfl.ch>
  * @author Marco Vocialta <marco.vocialta@epfl.ch>
  *
  * @date creation: Wed Apr 29 2015
- * @date last modification: Thu Jan 14 2016
+ * @date last modification: Mon Jun 19 2017
  *
  * @brief  General class for intersection computations
  *
  * @section LICENSE
  *
- * Copyright (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne) Laboratory
- * (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * Copyright (©) 2015-2018 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
- * terms  of the  GNU Lesser  General Public  License as  published by  the Free
+ * 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
+ * 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_MESH_ABSTRACT_INTERSECTOR_TMPL_HH__
 #define __AKANTU_MESH_ABSTRACT_INTERSECTOR_TMPL_HH__
 
 #include "aka_common.hh"
 #include "mesh_abstract_intersector.hh"
 
 namespace akantu {
 
 template <class Query>
 MeshAbstractIntersector<Query>::MeshAbstractIntersector(Mesh & mesh)
     : MeshGeomAbstract(mesh), new_node_per_elem(NULL),
       intersection_points(NULL), nb_seg_by_el(0) {}
 
 template <class Query>
 MeshAbstractIntersector<Query>::~MeshAbstractIntersector() {}
 
 template <class Query>
 void MeshAbstractIntersector<Query>::computeIntersectionQueryList(
     const std::list<Query> & query_list) {
   AKANTU_DEBUG_IN();
 
   typename std::list<Query>::const_iterator query_it = query_list.begin(),
                                             query_end = query_list.end();
 
   for (; query_it != query_end; ++query_it) {
     computeIntersectionQuery(*query_it);
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 template <class Query>
 void MeshAbstractIntersector<Query>::computeMeshQueryListIntersectionPoint(
     const std::list<Query> & query_list, UInt nb_old_nodes) {
   AKANTU_DEBUG_IN();
 
   typename std::list<Query>::const_iterator query_it = query_list.begin(),
                                             query_end = query_list.end();
 
   for (; query_it != query_end; ++query_it) {
     computeMeshQueryIntersectionPoint(*query_it, nb_old_nodes);
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 } // akantu
 
 #endif // __AKANTU_MESH_ABSTRACT_INTERSECTOR_TMPL_HH__
diff --git a/src/geometry/mesh_geom_abstract.hh b/src/geometry/mesh_geom_abstract.hh
index 8805f7050..530924b48 100644
--- a/src/geometry/mesh_geom_abstract.hh
+++ b/src/geometry/mesh_geom_abstract.hh
@@ -1,65 +1,65 @@
 /**
  * @file   mesh_geom_abstract.hh
  *
  * @author Lucas Frerot <lucas.frerot@epfl.ch>
  * @author Marco Vocialta <marco.vocialta@epfl.ch>
  *
  * @date creation: Fri Jan 04 2013
- * @date last modification: Thu Jan 14 2016
+ * @date last modification: Mon Jun 19 2017
  *
  * @brief  Class for constructing the CGAL primitives of a mesh
  *
  * @section LICENSE
  *
- * Copyright  (©)  2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de Lausanne)
+ * 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
+ * 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
+ * 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_MESH_GEOM_ABSTRACT_HH__
 #define __AKANTU_MESH_GEOM_ABSTRACT_HH__
 
 #include "aka_common.hh"
 #include "mesh.hh"
 
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 
 /// Abstract class for mesh geometry operations
 class MeshGeomAbstract {
 
 public:
   /// Construct from mesh
   explicit MeshGeomAbstract(Mesh & mesh) : mesh(mesh){};
 
   /// Destructor
   virtual ~MeshGeomAbstract(){};
 
 public:
   /// Construct geometric data for computational geometry algorithms
   virtual void constructData(GhostType ghost_type = _not_ghost) = 0;
 
 protected:
   /// Mesh used to construct the primitives
   Mesh & mesh;
 };
 
 } // akantu
 
 #endif // __AKANTU_MESH_GEOM_ABSTRACT_HH__
diff --git a/src/geometry/mesh_geom_common.hh b/src/geometry/mesh_geom_common.hh
index ccc6f8d8b..528e965a8 100644
--- a/src/geometry/mesh_geom_common.hh
+++ b/src/geometry/mesh_geom_common.hh
@@ -1,57 +1,57 @@
 /**
  * @file   mesh_geom_common.hh
  *
  * @author Lucas Frerot <lucas.frerot@epfl.ch>
  * @author Clement Roux <clement.roux@epfl.ch>
  *
  * @date creation: Fri Jan 04 2013
- * @date last modification: Thu Jan 14 2016
+ * @date last modification: Wed Jan 31 2018
  *
  * @brief  Common file for MeshGeom module
  *
  * @section LICENSE
  *
- * Copyright  (©)  2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de Lausanne)
+ * 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
+ * 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
+ * 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_MESH_GEOM_COMMON_HH__
 #define __AKANTU_MESH_GEOM_COMMON_HH__
 
 #include "aka_common.hh"
 
 #include <CGAL/MP_Float.h>
 #include <CGAL/Quotient.h>
 
 #include <CGAL/Algebraic_kernel_for_spheres_2_3.h>
 #include <CGAL/Cartesian.h>
 #include <CGAL/Simple_cartesian.h>
 #include <CGAL/Spherical_kernel_3.h>
 
 namespace akantu {
 
 namespace cgal {
   using Cartesian = CGAL::Simple_cartesian<Real>;
 
   using Spherical = CGAL::Spherical_kernel_3<
       CGAL::Simple_cartesian<CGAL::Quotient<CGAL::MP_Float>>,
       CGAL::Algebraic_kernel_for_spheres_2_3<CGAL::Quotient<CGAL::MP_Float>>>;
 } // cgal
 
 } // akantu
 
 #endif // __AKANTU_MESH_GEOM_COMMON_HH__
diff --git a/src/geometry/mesh_geom_factory.hh b/src/geometry/mesh_geom_factory.hh
index 68f1b927b..1b31ea553 100644
--- a/src/geometry/mesh_geom_factory.hh
+++ b/src/geometry/mesh_geom_factory.hh
@@ -1,107 +1,107 @@
 /**
  * @file   mesh_geom_factory.hh
  *
  * @author Lucas Frerot <lucas.frerot@epfl.ch>
  * @author Marco Vocialta <marco.vocialta@epfl.ch>
  *
  * @date creation: Fri Feb 27 2015
- * @date last modification: Thu Jan 14 2016
+ * @date last modification: Mon Jun 19 2017
  *
  * @brief  Class for constructing the CGAL primitives of a mesh
  *
  * @section LICENSE
  *
- * Copyright (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne) Laboratory
- * (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * Copyright (©) 2015-2018 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
- * terms  of the  GNU Lesser  General Public  License as  published by  the Free
+ * 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
+ * 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_MESH_GEOM_FACTORY_HH__
 #define __AKANTU_MESH_GEOM_FACTORY_HH__
 
 #include "aka_common.hh"
 #include "geom_helper_functions.hh"
 #include "mesh.hh"
 #include "mesh_geom_abstract.hh"
 #include "tree_type_helper.hh"
 
 #include <algorithm>
 
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 
 /**
  * @brief Class used to construct AABB tree for intersection computations
  *
  * This class constructs a CGAL AABB tree of one type of element in a mesh
  * for fast intersection computations.
  */
 template <UInt dim, ElementType el_type, class Primitive, class Kernel>
 class MeshGeomFactory : public MeshGeomAbstract {
 
 public:
   /// Construct from mesh
   explicit MeshGeomFactory(Mesh & mesh);
 
   /// Desctructor
   virtual ~MeshGeomFactory();
 
 public:
   /// Construct AABB tree for fast intersection computing
   virtual void constructData(GhostType ghost_type = _not_ghost);
 
   /**
    * @brief Construct a primitive and add it to a list of primitives
    *
    * This function needs to be specialized for every type that is wished to be
    * supported.
    * @param node_coordinates coordinates of the nodes making up the element
    * @param id element number
    * @param list the primitive list (not used inside MeshGeomFactory)
    */
   inline void addPrimitive(
       const Matrix<Real> & node_coordinates, UInt id,
       typename TreeTypeHelper<Primitive, Kernel>::container_type & list);
 
   inline void addPrimitive(const Matrix<Real> & node_coordinates, UInt id);
 
   /// Getter for the AABB tree
   const typename TreeTypeHelper<Primitive, Kernel>::tree & getTree() const {
     return *data_tree;
   }
 
   /// Getter for primitive list
   const typename TreeTypeHelper<Primitive, Kernel>::container_type &
   getPrimitiveList() const {
     return primitive_list;
   }
 
 protected:
   /// AABB data tree
   typename TreeTypeHelper<Primitive, Kernel>::tree * data_tree;
 
   /// Primitive list
   typename TreeTypeHelper<Primitive, Kernel>::container_type primitive_list;
 };
 
 } // akantu
 
 #include "mesh_geom_factory_tmpl.hh"
 
 #endif // __AKANTU_MESH_GEOM_FACTORY_HH__
diff --git a/src/geometry/mesh_geom_factory_tmpl.hh b/src/geometry/mesh_geom_factory_tmpl.hh
index 5caf3048b..a7028a652 100644
--- a/src/geometry/mesh_geom_factory_tmpl.hh
+++ b/src/geometry/mesh_geom_factory_tmpl.hh
@@ -1,271 +1,271 @@
 /**
  * @file   mesh_geom_factory_tmpl.hh
  *
  * @author Lucas Frerot <lucas.frerot@epfl.ch>
  * @author Clement Roux <clement.roux@epfl.ch>
  * @author Marco Vocialta <marco.vocialta@epfl.ch>
  *
  * @date creation: Fri Feb 27 2015
- * @date last modification: Thu Jan 14 2016
+ * @date last modification: Wed Jan 31 2018
  *
  * @brief  Class for constructing the CGAL primitives of a mesh
  *
  * @section LICENSE
  *
- * Copyright (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne) Laboratory
- * (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * Copyright (©) 2015-2018 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
- * terms  of the  GNU Lesser  General Public  License as  published by  the Free
+ * 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
+ * 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_MESH_GEOM_FACTORY_TMPL_HH__
 #define __AKANTU_MESH_GEOM_FACTORY_TMPL_HH__
 
 /* -------------------------------------------------------------------------- */
 
 #include "aka_common.hh"
 #include "mesh_geom_common.hh"
 #include "mesh_geom_factory.hh"
 
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 
 template <UInt dim, ElementType type, class Primitive, class Kernel>
 MeshGeomFactory<dim, type, Primitive, Kernel>::MeshGeomFactory(Mesh & mesh)
     : MeshGeomAbstract(mesh), data_tree(NULL), primitive_list() {}
 
 template <UInt dim, ElementType type, class Primitive, class Kernel>
 MeshGeomFactory<dim, type, Primitive, Kernel>::~MeshGeomFactory() {
   delete data_tree;
 }
 
 /**
  * This function loops over the elements of `type` in the mesh and creates the
  * AABB tree of geometrical primitves (`data_tree`).
  */
 template <UInt dim, ElementType type, class Primitive, class Kernel>
 void MeshGeomFactory<dim, type, Primitive, Kernel>::constructData(
     GhostType ghost_type) {
   AKANTU_DEBUG_IN();
 
   primitive_list.clear();
   UInt nb_nodes_per_element = mesh.getNbNodesPerElement(type);
 
   const Array<UInt> & connectivity = mesh.getConnectivity(type, ghost_type);
   const Array<Real> & nodes = mesh.getNodes();
 
   UInt el_index = 0;
   Array<UInt>::const_vector_iterator it =
       connectivity.begin(nb_nodes_per_element);
   Array<UInt>::const_vector_iterator end =
       connectivity.end(nb_nodes_per_element);
 
   Matrix<Real> node_coordinates(dim, nb_nodes_per_element);
 
   // This loop builds the list of primitives
   for (; it != end; ++it, ++el_index) {
     const Vector<UInt> & el_connectivity = *it;
 
     for (UInt i = 0; i < nb_nodes_per_element; i++)
       for (UInt j = 0; j < dim; j++)
         node_coordinates(j, i) = nodes(el_connectivity(i), j);
 
     // the unique elemental id assigned to the primitive is the
     // linearized element index over ghost type
     addPrimitive(node_coordinates, el_index);
   }
 
   delete data_tree;
 
   // This condition allows the use of the mesh geom module
   // even if types are not compatible with AABB tree algorithm
   if (TreeTypeHelper<Primitive, Kernel>::is_valid)
     data_tree = new typename TreeTypeHelper<Primitive, Kernel>::tree(
         primitive_list.begin(), primitive_list.end());
 
   AKANTU_DEBUG_OUT();
 }
 
 template <UInt dim, ElementType type, class Primitive, class Kernel>
 void MeshGeomFactory<dim, type, Primitive, Kernel>::addPrimitive(
     const Matrix<Real> & node_coordinates, UInt id) {
   this->addPrimitive(node_coordinates, id, this->primitive_list);
 }
 
 // (2D, _triangle_3) decomposed into Triangle<cgal::Cartesian>
 template <>
 inline void
 MeshGeomFactory<2, _triangle_3, Triangle<cgal::Cartesian>, cgal::Cartesian>::
     addPrimitive(const Matrix<Real> & node_coordinates, UInt id,
                  TreeTypeHelper<Triangle<cgal::Cartesian>,
                                 cgal::Cartesian>::container_type & list) {
 
   TreeTypeHelper<Triangle<cgal::Cartesian>, cgal::Cartesian>::point_type a(
       node_coordinates(0, 0), node_coordinates(1, 0), 0.),
       b(node_coordinates(0, 1), node_coordinates(1, 1), 0.),
       c(node_coordinates(0, 2), node_coordinates(1, 2), 0.);
 
   Triangle<cgal::Cartesian> t(a, b, c);
   t.setId(id);
   list.push_back(t);
 }
 
 // (2D, _triangle_6) decomposed into Triangle<cgal::Cartesian>
 template <>
 inline void
 MeshGeomFactory<2, _triangle_6, Triangle<cgal::Cartesian>, cgal::Cartesian>::
     addPrimitive(const Matrix<Real> & node_coordinates, UInt id,
                  TreeTypeHelper<Triangle<cgal::Cartesian>,
                                 cgal::Cartesian>::container_type & list) {
 
   TreeTypeHelper<Triangle<cgal::Cartesian>, cgal::Cartesian>::point_type a(
       node_coordinates(0, 0), node_coordinates(1, 0), 0.),
       b(node_coordinates(0, 1), node_coordinates(1, 1), 0.),
       c(node_coordinates(0, 2), node_coordinates(1, 2), 0.);
 
   Triangle<cgal::Cartesian> t(a, b, c);
   t.setId(id);
   list.push_back(t);
 }
 
 // (2D, _triangle_3) decomposed into Line_arc<cgal::Spherical>
 template <>
 inline void
 MeshGeomFactory<2, _triangle_3, Line_arc<cgal::Spherical>, cgal::Spherical>::
     addPrimitive(const Matrix<Real> & node_coordinates, UInt id,
                  TreeTypeHelper<Line_arc<cgal::Spherical>,
                                 cgal::Spherical>::container_type & list) {
 
   TreeTypeHelper<Line_arc<cgal::Spherical>, cgal::Spherical>::point_type a(
       node_coordinates(0, 0), node_coordinates(1, 0), 0.),
       b(node_coordinates(0, 1), node_coordinates(1, 1), 0.),
       c(node_coordinates(0, 2), node_coordinates(1, 2), 0.);
 
   /*std::cout << "elem " << id << " node 1 : x_node=" << node_coordinates(0, 0)
         << ", x_arc_node=" << a.x() << ", y_node=" << node_coordinates(1, 0)
         << ", y_arc_node=" << a.y() << std::endl ;
   std::cout << "elem " << id << " node 2 : x_node=" << node_coordinates(0, 1)
         << ", x_arc_node=" << b.x() << ", y_node=" << node_coordinates(1, 1)
         << ", y_arc_node=" << b.y() << std::endl ;
   std::cout << "elem " << id << " node 2 : x_node=" << node_coordinates(0, 2)
         << ", x_arc_node=" << c.x() << ", y_node=" << node_coordinates(1, 2)
         << ", y_arc_node=" << c.y() << std::endl ;*/
 
   CGAL::Line_3<cgal::Spherical> l1(a, b), l2(b, c), l3(c, a);
   Line_arc<cgal::Spherical> s1(l1, a, b), s2(l2, b, c), s3(l3, c, a);
 
   s1.setId(id);
   s1.setSegId(0);
   s2.setId(id);
   s2.setSegId(1);
   s3.setId(id);
   s3.setSegId(2);
 
   list.push_back(s1);
   list.push_back(s2);
   list.push_back(s3);
 }
 
 #if defined(AKANTU_IGFEM)
 
 // (2D, _igfem_triangle_4) decomposed into Line_arc<cgal::Spherical>
 template <>
 inline void MeshGeomFactory<2, _igfem_triangle_4, Line_arc<cgal::Spherical>,
                             cgal::Spherical>::
     addPrimitive(const Matrix<Real> & node_coordinates, UInt id,
                  TreeTypeHelper<Line_arc<cgal::Spherical>,
                                 cgal::Spherical>::container_type & list) {
 
   TreeTypeHelper<Line_arc<cgal::Spherical>, cgal::Spherical>::point_type a(
       node_coordinates(0, 0), node_coordinates(1, 0), 0.),
       b(node_coordinates(0, 1), node_coordinates(1, 1), 0.),
       c(node_coordinates(0, 2), node_coordinates(1, 2), 0.);
 
   CGAL::Line_3<cgal::Spherical> l1(a, b), l2(b, c), l3(c, a);
   Line_arc<cgal::Spherical> s1(l1, a, b), s2(l2, b, c), s3(l3, c, a);
 
   s1.setId(id);
   s1.setSegId(0);
   s2.setId(id);
   s2.setSegId(1);
   s3.setId(id);
   s3.setSegId(2);
 
   list.push_back(s1);
   list.push_back(s2);
   list.push_back(s3);
 }
 
 // (2D, _igfem_triangle_4) decomposed into Line_arc<cgal::Spherical>
 template <>
 inline void MeshGeomFactory<2, _igfem_triangle_5, Line_arc<cgal::Spherical>,
                             cgal::Spherical>::
     addPrimitive(const Matrix<Real> & node_coordinates, UInt id,
                  TreeTypeHelper<Line_arc<cgal::Spherical>,
                                 cgal::Spherical>::container_type & list) {
 
   TreeTypeHelper<Line_arc<cgal::Spherical>, cgal::Spherical>::point_type a(
       node_coordinates(0, 0), node_coordinates(1, 0), 0.),
       b(node_coordinates(0, 1), node_coordinates(1, 1), 0.),
       c(node_coordinates(0, 2), node_coordinates(1, 2), 0.);
 
   CGAL::Line_3<cgal::Spherical> l1(a, b), l2(b, c), l3(c, a);
   Line_arc<cgal::Spherical> s1(l1, a, b), s2(l2, b, c), s3(l3, c, a);
 
   s1.setId(id);
   s1.setSegId(0);
   s2.setId(id);
   s2.setSegId(1);
   s3.setId(id);
   s3.setSegId(2);
 
   list.push_back(s1);
   list.push_back(s2);
   list.push_back(s3);
 }
 
 #endif
 
 // (3D, _tetrahedron_4) decomposed into Triangle<cgal::Cartesian>
 template <>
 inline void
 MeshGeomFactory<3, _tetrahedron_4, Triangle<cgal::Cartesian>, cgal::Cartesian>::
     addPrimitive(const Matrix<Real> & node_coordinates, UInt id,
                  TreeTypeHelper<Triangle<cgal::Cartesian>,
                                 cgal::Cartesian>::container_type & list) {
 
   TreeTypeHelper<Triangle<cgal::Cartesian>, cgal::Cartesian>::point_type a(
       node_coordinates(0, 0), node_coordinates(1, 0), node_coordinates(2, 0)),
       b(node_coordinates(0, 1), node_coordinates(1, 1), node_coordinates(2, 1)),
       c(node_coordinates(0, 2), node_coordinates(1, 2), node_coordinates(2, 2)),
       d(node_coordinates(0, 3), node_coordinates(1, 3), node_coordinates(2, 3));
 
   Triangle<cgal::Cartesian> t1(a, b, c), t2(b, c, d), t3(c, d, a), t4(d, a, b);
 
   t1.setId(id);
   t2.setId(id);
   t3.setId(id);
   t4.setId(id);
 
   list.push_back(t1);
   list.push_back(t2);
   list.push_back(t3);
   list.push_back(t4);
 }
 
 } // akantu
 
 #endif // __AKANTU_MESH_GEOM_FACTORY_TMPL_HH__
diff --git a/src/geometry/mesh_geom_intersector.hh b/src/geometry/mesh_geom_intersector.hh
index d8552c6f3..a0082b077 100644
--- a/src/geometry/mesh_geom_intersector.hh
+++ b/src/geometry/mesh_geom_intersector.hh
@@ -1,74 +1,74 @@
 /**
  * @file   mesh_geom_intersector.hh
  *
  * @author Lucas Frerot <lucas.frerot@epfl.ch>
  * @author Clement Roux <clement.roux@epfl.ch>
  * @author Marco Vocialta <marco.vocialta@epfl.ch>
  *
  * @date creation: Wed Apr 29 2015
- * @date last modification: Thu Jan 14 2016
+ * @date last modification: Mon Jun 19 2017
  *
  * @brief  General class for intersection computations
  *
  * @section LICENSE
  *
- * Copyright (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne) Laboratory
- * (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * Copyright (©) 2015-2018 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
- * terms  of the  GNU Lesser  General Public  License as  published by  the Free
+ * 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
+ * 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_MESH_GEOM_INTERSECTOR_HH__
 #define __AKANTU_MESH_GEOM_INTERSECTOR_HH__
 
 #include "aka_common.hh"
 #include "mesh_abstract_intersector.hh"
 #include "mesh_geom_factory.hh"
 
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 
 /**
  * @brief Class used to perform intersections on a mesh and construct output
  * data
  */
 template <UInt dim, ElementType type, class Primitive, class Query,
           class Kernel>
 class MeshGeomIntersector : public MeshAbstractIntersector<Query> {
 
 public:
   /// Construct from mesh
   explicit MeshGeomIntersector(Mesh & mesh);
 
   /// Destructor
   virtual ~MeshGeomIntersector();
 
 public:
   /// Construct the primitive tree object
   virtual void constructData(GhostType ghost_type = _not_ghost);
 
 protected:
   /// Factory object containing the primitive tree
   MeshGeomFactory<dim, type, Primitive, Kernel> factory;
 };
 
 } // akantu
 
 #include "mesh_geom_intersector_tmpl.hh"
 
 #endif // __AKANTU_MESH_GEOM_INTERSECTOR_HH__
diff --git a/src/geometry/mesh_geom_intersector_tmpl.hh b/src/geometry/mesh_geom_intersector_tmpl.hh
index 0e2ab5bb9..7bedae20d 100644
--- a/src/geometry/mesh_geom_intersector_tmpl.hh
+++ b/src/geometry/mesh_geom_intersector_tmpl.hh
@@ -1,64 +1,64 @@
 /**
  * @file   mesh_geom_intersector_tmpl.hh
  *
  * @author Lucas Frerot <lucas.frerot@epfl.ch>
  *
  * @date creation: Wed Apr 29 2015
- * @date last modification: Thu Jan 14 2016
+ * @date last modification: Mon Jun 19 2017
  *
  * @brief  General class for intersection computations
  *
  * @section LICENSE
  *
- * Copyright (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne) Laboratory
- * (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * Copyright (©) 2015-2018 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
- * terms  of the  GNU Lesser  General Public  License as  published by  the Free
+ * 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
+ * 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_MESH_GEOM_INTERSECTOR_TMPL_HH__
 #define __AKANTU_MESH_GEOM_INTERSECTOR_TMPL_HH__
 
 #include "aka_common.hh"
 #include "mesh_geom_intersector.hh"
 
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 
 template <UInt dim, ElementType type, class Primitive, class Query,
           class Kernel>
 MeshGeomIntersector<dim, type, Primitive, Query, Kernel>::MeshGeomIntersector(
     Mesh & mesh)
     : MeshAbstractIntersector<Query>(mesh), factory(mesh) {}
 
 template <UInt dim, ElementType type, class Primitive, class Query,
           class Kernel>
 MeshGeomIntersector<dim, type, Primitive, Query,
                     Kernel>::~MeshGeomIntersector() {}
 
 template <UInt dim, ElementType type, class Primitive, class Query,
           class Kernel>
 void MeshGeomIntersector<dim, type, Primitive, Query, Kernel>::constructData(
     GhostType ghost_type) {
   this->intersection_points->resize(0);
   factory.constructData(ghost_type);
 }
 
 } // akantu
 
 #endif // __AKANTU_MESH_GEOM_INTERSECTOR_TMPL_HH__
diff --git a/src/geometry/mesh_segment_intersector.hh b/src/geometry/mesh_segment_intersector.hh
index 6e7c38e2d..b6691c10b 100644
--- a/src/geometry/mesh_segment_intersector.hh
+++ b/src/geometry/mesh_segment_intersector.hh
@@ -1,109 +1,109 @@
 /**
  * @file   mesh_segment_intersector.hh
  *
  * @author Lucas Frerot <lucas.frerot@epfl.ch>
  * @author Clement Roux <clement.roux@epfl.ch>
  * @author Marco Vocialta <marco.vocialta@epfl.ch>
  *
  * @date creation: Wed Apr 29 2015
- * @date last modification: Thu Jan 14 2016
+ * @date last modification: Wed Jan 31 2018
  *
  * @brief  Computation of mesh intersection with segments
  *
  * @section LICENSE
  *
- * Copyright (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne) Laboratory
- * (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * Copyright (©) 2015-2018 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
- * terms  of the  GNU Lesser  General Public  License as  published by  the Free
+ * 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
+ * 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_MESH_SEGMENT_INTERSECTOR_HH__
 #define __AKANTU_MESH_SEGMENT_INTERSECTOR_HH__
 
 #include "aka_common.hh"
 #include "mesh_geom_intersector.hh"
 
 #include "mesh_geom_common.hh"
 
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 
 template <UInt dim, ElementType type>
 class MeshSegmentIntersector
     : public MeshGeomIntersector<dim, type, Triangle<cgal::Cartesian>,
                                  cgal::Cartesian::Segment_3, cgal::Cartesian> {
   using K = cgal::Cartesian;
   /// Parent class type
   typedef MeshGeomIntersector<dim, type, Triangle<K>, K::Segment_3, K>
       parent_type;
 
   /// Result of intersection function type
   typedef typename IntersectionTypeHelper<TreeTypeHelper<Triangle<K>, K>,
                                           K::Segment_3>::intersection_type
       result_type;
 
   /// Pair of segments and element id
   typedef std::pair<K::Segment_3, UInt> pair_type;
 
 public:
   /// Construct from mesh
   explicit MeshSegmentIntersector(Mesh & mesh, Mesh & result_mesh);
 
   /// Destructor
   virtual ~MeshSegmentIntersector();
 
 public:
   /**
    * @brief Computes the intersection of the mesh with a segment
    *
    * @param query the segment to compute the intersections with the mesh
    */
   virtual void computeIntersectionQuery(const K::Segment_3 & query);
 
   /// Compute intersection points between the mesh and a query
   virtual void computeMeshQueryIntersectionPoint(const K::Segment_3 & query,
                                                  UInt nb_old_nodes);
 
   /// Compute the embedded mesh
   virtual void
   buildResultFromQueryList(const std::list<K::Segment_3> & query_list);
 
   void setPhysicalName(const std::string & other) {
     current_physical_name = other;
   }
 
 protected:
   /// Compute segments from intersection list
   void computeSegments(const std::list<result_type> & intersections,
                        std::set<pair_type, segmentPairsLess> & segments,
                        const K::Segment_3 & query);
 
 protected:
   /// Result mesh
   Mesh & result_mesh;
 
   /// Physical name of the current batch of queries
   std::string current_physical_name;
 };
 
 } // akantu
 
 #include "mesh_segment_intersector_tmpl.hh"
 
 #endif // __AKANTU_MESH_SEGMENT_INTERSECTOR_HH__
diff --git a/src/geometry/mesh_segment_intersector_tmpl.hh b/src/geometry/mesh_segment_intersector_tmpl.hh
index 92538a104..80f75640f 100644
--- a/src/geometry/mesh_segment_intersector_tmpl.hh
+++ b/src/geometry/mesh_segment_intersector_tmpl.hh
@@ -1,283 +1,283 @@
 /**
  * @file   mesh_segment_intersector_tmpl.hh
  *
  * @author Lucas Frerot <lucas.frerot@epfl.ch>
  * @author Clement Roux <clement.roux@epfl.ch>
  * @author Marco Vocialta <marco.vocialta@epfl.ch>
  *
  * @date creation: Wed Apr 29 2015
- * @date last modification: Thu Jan 14 2016
+ * @date last modification: Tue Feb 20 2018
  *
  * @brief  Computation of mesh intersection with segments
  *
  * @section LICENSE
  *
- * Copyright (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne) Laboratory
- * (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * Copyright (©) 2015-2018 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
- * terms  of the  GNU Lesser  General Public  License as  published by  the Free
+ * 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
+ * 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_MESH_SEGMENT_INTERSECTOR_TMPL_HH__
 #define __AKANTU_MESH_SEGMENT_INTERSECTOR_TMPL_HH__
 
 #include "aka_common.hh"
 #include "mesh_geom_common.hh"
 #include "tree_type_helper.hh"
 
 namespace akantu {
 
 template <UInt dim, ElementType type>
 MeshSegmentIntersector<dim, type>::MeshSegmentIntersector(Mesh & mesh,
                                                           Mesh & result_mesh)
     : parent_type(mesh), result_mesh(result_mesh), current_physical_name() {
   this->intersection_points = new Array<Real>(0, dim);
   this->constructData();
 }
 
 template <UInt dim, ElementType type>
 MeshSegmentIntersector<dim, type>::~MeshSegmentIntersector() {}
 
 template <UInt dim, ElementType type>
 void MeshSegmentIntersector<dim, type>::computeIntersectionQuery(
     const K::Segment_3 & query) {
   AKANTU_DEBUG_IN();
 
   result_mesh.addConnectivityType(_segment_2, _not_ghost);
   result_mesh.addConnectivityType(_segment_2, _ghost);
 
   std::list<result_type> result_list;
   std::set<std::pair<K::Segment_3, UInt>, segmentPairsLess> segment_set;
 
   this->factory.getTree().all_intersections(query,
                                             std::back_inserter(result_list));
   this->computeSegments(result_list, segment_set, query);
 
   // Arrays for storing nodes and connectivity
   Array<Real> & nodes = result_mesh.getNodes();
   Array<UInt> & connectivity = result_mesh.getConnectivity(_segment_2);
 
   // Arrays for storing associated element and physical name
   bool valid_elemental_data = true;
   Array<Element> * associated_element = NULL;
   Array<std::string> * associated_physical_name = NULL;
 
   try {
     associated_element =
         &result_mesh.getData<Element>("associated_element", _segment_2);
     associated_physical_name =
         &result_mesh.getData<std::string>("physical_names", _segment_2);
   } catch (debug::Exception & e) {
     valid_elemental_data = false;
   }
 
   std::set<pair_type, segmentPairsLess>::iterator it = segment_set.begin(),
                                                   end = segment_set.end();
 
   // Loop over the segment pairs
   for (; it != end; ++it) {
     if (!it->first.is_degenerate()) {
       Vector<UInt> segment_connectivity(2);
       segment_connectivity(0) = result_mesh.getNbNodes();
       segment_connectivity(1) = result_mesh.getNbNodes() + 1;
       connectivity.push_back(segment_connectivity);
 
       // Copy nodes
       Vector<Real> source(dim), target(dim);
       for (UInt j = 0; j < dim; j++) {
         source(j) = it->first.source()[j];
         target(j) = it->first.target()[j];
       }
 
       nodes.push_back(source);
       nodes.push_back(target);
 
       // Copy associated element info
       if (valid_elemental_data) {
         associated_element->push_back(Element{type, it->second, _not_ghost});
         associated_physical_name->push_back(current_physical_name);
       }
     }
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 template <UInt dim, ElementType type>
 void MeshSegmentIntersector<dim, type>::computeMeshQueryIntersectionPoint(
     const K::Segment_3 & /*query*/, UInt /*nb_old_nodes*/) {
   AKANTU_ERROR("The method: computeMeshQueryIntersectionPoint has not "
                "been implemented in class MeshSegmentIntersector!");
 }
 
 template <UInt dim, ElementType type>
 void MeshSegmentIntersector<dim, type>::buildResultFromQueryList(
     const std::list<K::Segment_3> & query_list) {
   AKANTU_DEBUG_IN();
 
   this->computeIntersectionQueryList(query_list);
 
   AKANTU_DEBUG_OUT();
 }
 
 template <UInt dim, ElementType type>
 void MeshSegmentIntersector<dim, type>::computeSegments(
     const std::list<result_type> & intersections,
     std::set<pair_type, segmentPairsLess> & segments,
     const K::Segment_3 & query) {
   AKANTU_DEBUG_IN();
 
   /*
    * Number of intersections = 0 means
    *
    * - query is completely outside mesh
    * - query is completely inside primitive
    *
    * We try to determine the case and still construct the segment list
    */
   if (intersections.size() == 0) {
     // We look at all the primitives intersected by two rays
     // If there is one primitive in common, then query is inside
     // that primitive
     K::Ray_3 ray1(query.source(), query.target());
     K::Ray_3 ray2(query.target(), query.source());
 
     std::set<UInt> ray1_results, ray2_results;
 
     this->factory.getTree().all_intersected_primitives(
         ray1, std::inserter(ray1_results, ray1_results.begin()));
     this->factory.getTree().all_intersected_primitives(
         ray2, std::inserter(ray2_results, ray2_results.begin()));
 
     bool inside_primitive = false;
     UInt primitive_id = 0;
 
     std::set<UInt>::iterator ray2_it = ray2_results.begin(),
                              ray2_end = ray2_results.end();
 
     // Test if first list contains an element of second list
     for (; ray2_it != ray2_end && !inside_primitive; ++ray2_it) {
       if (ray1_results.find(*ray2_it) != ray1_results.end()) {
         inside_primitive = true;
         primitive_id = *ray2_it;
       }
     }
 
     if (inside_primitive) {
       segments.insert(std::make_pair(query, primitive_id));
     }
   }
 
   else {
     typename std::list<result_type>::const_iterator it = intersections.begin(),
                                                     end = intersections.end();
 
     for (; it != end; ++it) {
       UInt el = (*it)->second;
 
       // Result of intersection is a segment
       if (const K::Segment_3 * segment =
               boost::get<K::Segment_3>(&((*it)->first))) {
         // Check if the segment was alread created
         segments.insert(std::make_pair(*segment, el));
       }
 
       // Result of intersection is a point
       else if (const K::Point_3 * point =
                    boost::get<K::Point_3>(&((*it)->first))) {
         // We only want to treat points differently if we're in 3D with Tetra4
         // elements This should be optimized by compilator
         if (dim == 3 && type == _tetrahedron_4) {
           UInt nb_nodes_per_element = Mesh::getNbNodesPerElement(type);
           TreeTypeHelper<Triangle<K>, K>::container_type facets;
 
           const Array<Real> & nodes = this->mesh.getNodes();
           Array<UInt>::const_vector_iterator connectivity_vec =
               this->mesh.getConnectivity(type).begin(nb_nodes_per_element);
 
           const Vector<UInt> & el_connectivity = connectivity_vec[el];
 
           Matrix<Real> node_coordinates(dim, nb_nodes_per_element);
           for (UInt i = 0; i < nb_nodes_per_element; i++)
             for (UInt j = 0; j < dim; j++)
               node_coordinates(j, i) = nodes(el_connectivity(i), j);
 
           this->factory.addPrimitive(node_coordinates, el, facets);
 
           // Local tree
           TreeTypeHelper<Triangle<K>, K>::tree * local_tree =
               new TreeTypeHelper<Triangle<K>, K>::tree(facets.begin(),
                                                        facets.end());
 
           // Compute local intersections (with current element)
           std::list<result_type> local_intersections;
           local_tree->all_intersections(
               query, std::back_inserter(local_intersections));
 
           bool out_point_found = false;
           typename std::list<result_type>::const_iterator
               local_it = local_intersections.begin(),
               local_end = local_intersections.end();
 
           for (; local_it != local_end; ++local_it) {
             if (const K::Point_3 * local_point =
                     boost::get<K::Point_3>(&((*local_it)->first))) {
               if (!comparePoints(*point, *local_point)) {
                 K::Segment_3 seg(*point, *local_point);
                 segments.insert(std::make_pair(seg, el));
                 out_point_found = true;
               }
             }
           }
 
           if (!out_point_found) {
             TreeTypeHelper<Triangle<K>, K>::point_type a(
                 node_coordinates(0, 0), node_coordinates(1, 0),
                 node_coordinates(2, 0)),
                 b(node_coordinates(0, 1), node_coordinates(1, 1),
                   node_coordinates(2, 1)),
                 c(node_coordinates(0, 2), node_coordinates(1, 2),
                   node_coordinates(2, 2)),
                 d(node_coordinates(0, 3), node_coordinates(1, 3),
                   node_coordinates(2, 3));
             K::Tetrahedron_3 tetra(a, b, c, d);
             const K::Point_3 * inside_point = NULL;
             if (tetra.has_on_bounded_side(query.source()) &&
                 !tetra.has_on_boundary(query.source()))
               inside_point = &query.source();
             else if (tetra.has_on_bounded_side(query.target()) &&
                      !tetra.has_on_boundary(query.target()))
               inside_point = &query.target();
 
             if (inside_point) {
               K::Segment_3 seg(*inside_point, *point);
               segments.insert(std::make_pair(seg, el));
             }
           }
 
           delete local_tree;
         }
       }
     }
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 } // namespace akantu
 
 #endif // __AKANTU_MESH_SEGMENT_INTERSECTOR_TMPL_HH__
diff --git a/src/geometry/mesh_sphere_intersector.hh b/src/geometry/mesh_sphere_intersector.hh
index 46c5e9f69..4066d67c4 100644
--- a/src/geometry/mesh_sphere_intersector.hh
+++ b/src/geometry/mesh_sphere_intersector.hh
@@ -1,119 +1,119 @@
 /**
  * @file   mesh_sphere_intersector.hh
  *
  * @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
  * @author Lucas Frerot <lucas.frerot@epfl.ch>
  * @author Clement Roux <clement.roux@epfl.ch>
  * @author Marco Vocialta <marco.vocialta@epfl.ch>
  *
  * @date creation: Tue Jun 23 2015
- * @date last modification: Thu Jan 14 2016
+ * @date last modification: Tue Feb 20 2018
  *
  * @brief  Computation of mesh intersection with sphere(s)
  *
  * @section LICENSE
  *
- * Copyright (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne) Laboratory
- * (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * Copyright (©) 2015-2018 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
- * terms  of the  GNU Lesser  General Public  License as  published by  the Free
+ * 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
+ * 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_MESH_SPHERE_INTERSECTOR_HH__
 #define __AKANTU_MESH_SPHERE_INTERSECTOR_HH__
 
 #include "aka_common.hh"
 #include "mesh_geom_intersector.hh"
 
 #include "mesh_geom_common.hh"
 
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 
 template <UInt dim, ElementType type>
 class MeshSphereIntersector
     : public MeshGeomIntersector<dim, type, Line_arc<cgal::Spherical>,
                                  cgal::Spherical::Sphere_3, cgal::Spherical> {
   using SK = cgal::Spherical;
   using K = cgal::Cartesian;
 
   /// Parent class type
   typedef MeshGeomIntersector<dim, type, Line_arc<SK>, SK::Sphere_3, SK>
       parent_type;
 
   /// Result of intersection function type
   typedef typename IntersectionTypeHelper<TreeTypeHelper<Triangle<K>, K>,
                                           K::Segment_3>::intersection_type
       result_type;
 
   /// Pair of intersection points and element id
   typedef std::pair<SK::Circular_arc_point_3, UInt> pair_type;
 
 public:
   /// Construct from mesh
   explicit MeshSphereIntersector(Mesh & mesh);
 
   /// Destructor
   virtual ~MeshSphereIntersector();
 
 public:
   /// Construct the primitive tree object
   virtual void constructData(GhostType ghost_type = _not_ghost);
 
   /**
    * @brief Computes the intersection of the mesh with a sphere
    *
    * @param query (sphere) to compute the intersections with the mesh
    */
   virtual void computeIntersectionQuery(const SK::Sphere_3 & /*query*/) {
     AKANTU_ERROR("This function is not implemented for spheres (It was "
                  "to generic and has been replaced by "
                  "computeMeshQueryIntersectionPoint");
   }
 
   /// Compute intersection points between the mesh primitives (segments) and a
   /// query (surface in 3D or a curve in 2D), double intersection points for the
   /// same primitives are not considered. A maximum is set to the number of
   /// intersection nodes per element: 2 in 2D and 4 in 3D
   virtual void computeMeshQueryIntersectionPoint(const SK::Sphere_3 & query,
                                                  UInt nb_old_nodes);
 
   /// Build the IGFEM mesh
   virtual void
   buildResultFromQueryList(const std::list<SK::Sphere_3> & /*query*/) {
     AKANTU_ERROR("This function is no longer implemented to split "
                  "geometrical operations and dedicated result "
                  "construction");
   }
 
   /// Set the tolerance
   void setToleranceIntersectionOnNode(UInt tol) {
     this->tol_intersection_on_node = tol;
   }
 
 protected:
   /// tolerance for which the intersection is considered on the mesh node
   /// (relative to the segment lenght)
   Real tol_intersection_on_node;
 };
 
 } // akantu
 
 #include "mesh_sphere_intersector_tmpl.hh"
 
 #endif // __AKANTU_MESH_SPHERE_INTERSECTOR_HH__
diff --git a/src/geometry/mesh_sphere_intersector_tmpl.hh b/src/geometry/mesh_sphere_intersector_tmpl.hh
index 818132a63..d47d652ef 100644
--- a/src/geometry/mesh_sphere_intersector_tmpl.hh
+++ b/src/geometry/mesh_sphere_intersector_tmpl.hh
@@ -1,215 +1,215 @@
 /**
  * @file   mesh_sphere_intersector_tmpl.hh
  *
  * @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
  * @author Lucas Frerot <lucas.frerot@epfl.ch>
  * @author Clement Roux <clement.roux@epfl.ch>
  * @author Marco Vocialta <marco.vocialta@epfl.ch>
  *
  * @date creation: Tue Jun 23 2015
- * @date last modification: Thu Jan 14 2016
+ * @date last modification: Tue Feb 20 2018
  *
  * @brief  Computation of mesh intersection with spheres
  *
  * @section LICENSE
  *
- * Copyright (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne) Laboratory
- * (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * Copyright (©) 2015-2018 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
- * terms  of the  GNU Lesser  General Public  License as  published by  the Free
+ * 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
+ * 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_MESH_SPHERE_INTERSECTOR_TMPL_HH__
 #define __AKANTU_MESH_SPHERE_INTERSECTOR_TMPL_HH__
 
 #include "aka_common.hh"
 #include "mesh_geom_common.hh"
 #include "mesh_sphere_intersector.hh"
 #include "tree_type_helper.hh"
 
 namespace akantu {
 
 template <UInt dim, ElementType type>
 MeshSphereIntersector<dim, type>::MeshSphereIntersector(Mesh & mesh)
     : parent_type(mesh), tol_intersection_on_node(1e-10) {
 #if defined(AKANTU_IGFEM)
   if ((type == _triangle_3) || (type == _igfem_triangle_4) ||
       (type == _igfem_triangle_5)) {
     const_cast<UInt &>(this->nb_seg_by_el) = 3;
   } else {
     AKANTU_ERROR("Not ready for mesh type " << type);
   }
 #else
   if ((type != _triangle_3))
     AKANTU_ERROR("Not ready for mesh type " << type);
 #endif
 
   // initialize the intersection pointsss array with the spatial dimension
   this->intersection_points = new Array<Real>(0, dim);
   //  A maximum is set to the number of intersection nodes per element to limit
   //  the size of new_node_per_elem: 2 in 2D and 4 in 3D
   this->new_node_per_elem = new Array<UInt>(0, 1 + 4 * (dim - 1));
 }
 
 template <UInt dim, ElementType type>
 MeshSphereIntersector<dim, type>::~MeshSphereIntersector() {
   delete this->new_node_per_elem;
   delete this->intersection_points;
 }
 
 template <UInt dim, ElementType type>
 void MeshSphereIntersector<dim, type>::constructData(GhostType ghost_type) {
 
   this->new_node_per_elem->resize(this->mesh.getNbElement(type, ghost_type));
   this->new_node_per_elem->clear();
 
   MeshGeomIntersector<dim, type, Line_arc<SK>, SK::Sphere_3, SK>::constructData(
       ghost_type);
 }
 
 template <UInt dim, ElementType type>
 void MeshSphereIntersector<dim, type>::computeMeshQueryIntersectionPoint(
     const SK::Sphere_3 & query, UInt nb_old_nodes) {
   /// function to replace computeIntersectionQuery in a more generic geometry
   /// module version
   // The newNodeEvent is not send from this method who only compute the
   // intersection points
   AKANTU_DEBUG_IN();
 
   Array<Real> & nodes = this->mesh.getNodes();
   UInt nb_node = nodes.size() + this->intersection_points->size();
 
   // Tolerance for proximity checks should be defined by user
   Real global_tolerance = Math::getTolerance();
   Math::setTolerance(tol_intersection_on_node);
   typedef boost::variant<pair_type> sk_inter_res;
 
   TreeTypeHelper<Line_arc<cgal::Spherical>, cgal::Spherical>::const_iterator
       it = this->factory.getPrimitiveList().begin(),
       end = this->factory.getPrimitiveList().end();
 
   for (; it != end; ++it) { // loop on the primitives (segments)
     std::list<sk_inter_res> s_results;
     CGAL::intersection(*it, query, std::back_inserter(s_results));
 
     if (s_results.size() == 1) { // just one point
       if (pair_type * pair = boost::get<pair_type>(&s_results.front())) {
         if (pair->second == 1) { // not a point tangent to the sphere
           // the intersection point written as a vector
           Vector<Real> new_node(dim, 0.0);
           cgal::Cartesian::Point_3 point(CGAL::to_double(pair->first.x()),
                                          CGAL::to_double(pair->first.y()),
                                          CGAL::to_double(pair->first.z()));
           for (UInt i = 0; i < dim; i++) {
             new_node(i) = point[i];
           }
 
           /// boolean to decide wheter intersection point is on a standard node
           /// of the mesh or not
           bool is_on_mesh = false;
           /// boolean to decide if this intersection point has been already
           /// computed for a neighbor element
           bool is_new = true;
 
           /// check if intersection point has already been computed
           UInt n = nb_old_nodes;
 
           // check if we already compute this intersection and add it as a node
           // for a neighboor element of another type
           auto existing_node = nodes.begin(dim);
 
           for (; n < nodes.size(); ++n) { // loop on the nodes from nb_old_nodes
             if (Math::are_vector_equal(dim, new_node.storage(),
                                        existing_node[n].storage())) {
               is_new = false;
               break;
             }
           }
           if (is_new) {
             auto intersection_points_it = this->intersection_points->begin(dim);
             auto intersection_points_end = this->intersection_points->end(dim);
             for (; intersection_points_it != intersection_points_end;
                  ++intersection_points_it, ++n) {
               if (Math::are_vector_equal(dim, new_node.storage(),
                                          intersection_points_it->storage())) {
                 is_new = false;
                 break;
               }
             }
           }
 
           // get the initial and final points of the primitive (segment) and
           // write them as vectors
           cgal::Cartesian::Point_3 source_cgal(
               CGAL::to_double(it->source().x()),
               CGAL::to_double(it->source().y()),
               CGAL::to_double(it->source().z()));
           cgal::Cartesian::Point_3 target_cgal(
               CGAL::to_double(it->target().x()),
               CGAL::to_double(it->target().y()),
               CGAL::to_double(it->target().z()));
           Vector<Real> source(dim), target(dim);
           for (UInt i = 0; i < dim; i++) {
             source(i) = source_cgal[i];
             target(i) = target_cgal[i];
           }
 
           // Check if we are close from a node of the primitive (segment)
           if (Math::are_vector_equal(dim, source.storage(),
                                      new_node.storage()) ||
               Math::are_vector_equal(dim, target.storage(),
                                      new_node.storage())) {
             is_on_mesh = true;
             is_new = false;
           }
 
           if (is_new) { // if the intersection point is a new one add it to the
                         // list
             this->intersection_points->push_back(new_node);
             nb_node++;
           }
 
           // deduce the element id
           UInt element_id = it->id();
 
           // fill the new_node_per_elem array
           if (!is_on_mesh) { // if the node is not on a mesh node
             UInt & nb_new_nodes_per_el =
                 (*this->new_node_per_elem)(element_id, 0);
             nb_new_nodes_per_el += 1;
             AKANTU_DEBUG_ASSERT(
                 2 * nb_new_nodes_per_el <
                     this->new_node_per_elem->getNbComponent(),
                 "You might have to interface crossing the same material");
             (*this->new_node_per_elem)(element_id,
                                        (2 * nb_new_nodes_per_el) - 1) = n;
             (*this->new_node_per_elem)(element_id, 2 * nb_new_nodes_per_el) =
                 it->segId();
           }
         }
       }
     }
   }
 
   Math::setTolerance(global_tolerance);
 
   AKANTU_DEBUG_OUT();
 }
 
 } // akantu
 
 #endif // __AKANTU_MESH_SPHERE_INTERSECTOR_TMPL_HH__
diff --git a/src/geometry/tree_type_helper.hh b/src/geometry/tree_type_helper.hh
index d43bdf549..f0cf08c21 100644
--- a/src/geometry/tree_type_helper.hh
+++ b/src/geometry/tree_type_helper.hh
@@ -1,109 +1,109 @@
 /**
  * @file   tree_type_helper.hh
  *
  * @author Lucas Frerot <lucas.frerot@epfl.ch>
  *
  * @date creation: Fri Jan 04 2013
- * @date last modification: Thu Jan 14 2016
+ * @date last modification: Thu Feb 01 2018
  *
  * @brief  Converts element types of a mesh to CGAL primitive types
  *
  * @section LICENSE
  *
- * Copyright  (©)  2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de Lausanne)
+ * 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
+ * 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
+ * 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_TREE_TYPE_HELPER_HH__
 #define __AKANTU_TREE_TYPE_HELPER_HH__
 
 #include "aka_common.hh"
 
 #include "line_arc.hh"
 #include "tetrahedron.hh"
 #include "triangle.hh"
 
 #include "aabb_primitive.hh"
 
 #include "mesh_geom_common.hh"
 #include <CGAL/AABB_traits.h>
 #include <CGAL/AABB_tree.h>
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 
 /// Replacement class for algorithm that can't use the AABB tree types
 template <typename iterator> struct VoidTree {
   VoidTree(const iterator & /*begin*/, const iterator & /*end*/) {}
 };
 
 /// Helper class used to ease the use of CGAL AABB tree algorithm
 template <class Primitive, class Kernel> struct TreeTypeHelper {
   static const bool is_valid = false;
 
   typedef Primitive primitive_type;
   typedef typename std::list<primitive_type> container_type;
   typedef typename container_type::iterator iterator;
   typedef typename container_type::const_iterator const_iterator;
   typedef typename CGAL::Point_3<Kernel> point_type;
   typedef VoidTree<iterator> tree;
 };
 
 /// Helper class used to ease the use of intersections
 template <class TTHelper, class Query> struct IntersectionTypeHelper;
 
 /**
  * Macro used to specialize TreeTypeHelper
  * @param my_primitive associated primitive type
  * @param my_query query_type
  * @param my_kernel kernel type
  */
 #define TREE_TYPE_HELPER_MACRO(my_primitive, my_query, my_kernel)              \
   template <> struct TreeTypeHelper<my_primitive<my_kernel>, my_kernel> {      \
     static const bool is_valid = true;                                         \
     typedef my_primitive<my_kernel> primitive_type;                            \
     typedef my_primitive##_primitive aabb_primitive_type;                      \
     typedef CGAL::Point_3<my_kernel> point_type;                               \
                                                                                \
     typedef std::list<primitive_type> container_type;                          \
     typedef container_type::iterator iterator;                                 \
     typedef CGAL::AABB_traits<my_kernel, aabb_primitive_type>                  \
         aabb_traits_type;                                                      \
     typedef CGAL::AABB_tree<aabb_traits_type> tree;                            \
     typedef tree::Primitive_id id_type;                                        \
   };                                                                           \
                                                                                \
   template <>                                                                  \
   struct IntersectionTypeHelper<                                               \
       TreeTypeHelper<my_primitive<my_kernel>, my_kernel>, my_query> {          \
     typedef boost::optional<TreeTypeHelper<                                    \
         my_primitive<my_kernel>,                                               \
         my_kernel>::tree::Intersection_and_primitive_id<my_query>::Type>       \
         intersection_type;                                                     \
   }
 
 TREE_TYPE_HELPER_MACRO(Triangle, cgal::Cartesian::Segment_3, cgal::Cartesian);
 // TREE_TYPE_HELPER_MACRO(Line_arc, cgal::Spherical::Sphere_3, cgal::Spherical);
 
 #undef TREE_TYPE_HELPER_MACRO
 
 } // akantu
 
 #endif // __AKANTU_TREE_TYPE_HELPER_HH__
diff --git a/src/io/dumper/dumpable.cc b/src/io/dumper/dumpable.cc
index 04997c49c..e35791864 100644
--- a/src/io/dumper/dumpable.cc
+++ b/src/io/dumper/dumpable.cc
@@ -1,285 +1,285 @@
 /**
  * @file   dumpable.cc
  *
  * @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Wed Nov 13 2013
- * @date last modification: Thu Jan 21 2016
+ * @date last modification: Tue Feb 20 2018
  *
  * @brief  Implementation of the dumpable interface
  *
  * @section LICENSE
  *
- * Copyright  (©)  2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de Lausanne)
+ * 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
+ * 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
+ * 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 "dumpable.hh"
 /* -------------------------------------------------------------------------- */
 
 #ifdef AKANTU_USE_IOHELPER
 
 #include <io_helper.hh>
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 Dumpable::Dumpable() : default_dumper("") {}
 
 /* -------------------------------------------------------------------------- */
 Dumpable::~Dumpable() {
 
   auto it = dumpers.begin();
   auto end = dumpers.end();
 
   for (; it != end; ++it) {
     delete it->second;
   }
 }
 
 /* -------------------------------------------------------------------------- */
 void Dumpable::registerExternalDumper(DumperIOHelper & dumper,
                                       const std::string & dumper_name,
                                       const bool is_default) {
   this->dumpers[dumper_name] = &dumper;
   if (is_default)
     this->default_dumper = dumper_name;
 }
 
 /* -------------------------------------------------------------------------- */
 void Dumpable::addDumpMesh(const Mesh & mesh, UInt spatial_dimension,
                            const GhostType & ghost_type,
                            const ElementKind & element_kind) {
 
   this->addDumpMeshToDumper(this->default_dumper, mesh, spatial_dimension,
                             ghost_type, element_kind);
 }
 
 /* -------------------------------------------------------------------------- */
 void Dumpable::addDumpMeshToDumper(const std::string & dumper_name,
                                    const Mesh & mesh, UInt spatial_dimension,
                                    const GhostType & ghost_type,
                                    const ElementKind & element_kind) {
 
   DumperIOHelper & dumper = this->getDumper(dumper_name);
   dumper.registerMesh(mesh, spatial_dimension, ghost_type, element_kind);
 }
 
 /* -------------------------------------------------------------------------- */
 void Dumpable::addDumpFilteredMesh(
     const Mesh & mesh, const ElementTypeMapArray<UInt> & elements_filter,
     const Array<UInt> & nodes_filter, UInt spatial_dimension,
     const GhostType & ghost_type, const ElementKind & element_kind) {
   this->addDumpFilteredMeshToDumper(this->default_dumper, mesh, elements_filter,
                                     nodes_filter, spatial_dimension, ghost_type,
                                     element_kind);
 }
 
 /* -------------------------------------------------------------------------- */
 void Dumpable::addDumpFilteredMeshToDumper(
     const std::string & dumper_name, const Mesh & mesh,
     const ElementTypeMapArray<UInt> & elements_filter,
     const Array<UInt> & nodes_filter, UInt spatial_dimension,
     const GhostType & ghost_type, const ElementKind & element_kind) {
 
   DumperIOHelper & dumper = this->getDumper(dumper_name);
   dumper.registerFilteredMesh(mesh, elements_filter, nodes_filter,
                               spatial_dimension, ghost_type, element_kind);
 }
 
 /* -------------------------------------------------------------------------- */
 void Dumpable::addDumpField(const std::string & field_id) {
   this->addDumpFieldToDumper(this->default_dumper, field_id);
 }
 
 /* -------------------------------------------------------------------------- */
 void Dumpable::addDumpFieldToDumper(__attribute__((unused))
                                     const std::string & dumper_name,
                                     __attribute__((unused))
                                     const std::string & field_id) {
   AKANTU_TO_IMPLEMENT();
 }
 
 /* -------------------------------------------------------------------------- */
 void Dumpable::addDumpFieldExternal(const std::string & field_id,
                                     dumper::Field * field) {
   this->addDumpFieldExternalToDumper(this->default_dumper, field_id, field);
 }
 
 /* -------------------------------------------------------------------------- */
 void Dumpable::addDumpFieldExternalToDumper(const std::string & dumper_name,
                                             const std::string & field_id,
                                             dumper::Field * field) {
   DumperIOHelper & dumper = this->getDumper(dumper_name);
   dumper.registerField(field_id, field);
 }
 
 /* -------------------------------------------------------------------------- */
 
 void Dumpable::removeDumpField(const std::string & field_id) {
   this->removeDumpFieldFromDumper(this->default_dumper, field_id);
 }
 
 /* -------------------------------------------------------------------------- */
 void Dumpable::removeDumpFieldFromDumper(const std::string & dumper_name,
                                          const std::string & field_id) {
   DumperIOHelper & dumper = this->getDumper(dumper_name);
   dumper.unRegisterField(field_id);
 }
 
 /* -------------------------------------------------------------------------- */
 void Dumpable::addDumpFieldVector(const std::string & field_id) {
   this->addDumpFieldVectorToDumper(this->default_dumper, field_id);
 }
 
 /* -------------------------------------------------------------------------- */
 void Dumpable::addDumpFieldVectorToDumper(__attribute__((unused))
                                           const std::string & dumper_name,
                                           __attribute__((unused))
                                           const std::string & field_id) {
   AKANTU_TO_IMPLEMENT();
 }
 
 /* -------------------------------------------------------------------------- */
 void Dumpable::addDumpFieldTensor(const std::string & field_id) {
   this->addDumpFieldTensorToDumper(this->default_dumper, field_id);
 }
 
 /* -------------------------------------------------------------------------- */
 void Dumpable::addDumpFieldTensorToDumper(__attribute__((unused))
                                           const std::string & dumper_name,
                                           __attribute__((unused))
                                           const std::string & field_id) {
   AKANTU_TO_IMPLEMENT();
 }
 
 /* -------------------------------------------------------------------------- */
 void Dumpable::setDirectory(const std::string & directory) {
   this->setDirectoryToDumper(this->default_dumper, directory);
 }
 
 /* -------------------------------------------------------------------------- */
 void Dumpable::setDirectoryToDumper(const std::string & dumper_name,
                                     const std::string & directory) {
   DumperIOHelper & dumper = this->getDumper(dumper_name);
   dumper.setDirectory(directory);
 }
 
 /* -------------------------------------------------------------------------- */
 void Dumpable::setBaseName(const std::string & basename) {
   this->setBaseNameToDumper(this->default_dumper, basename);
 }
 
 /* -------------------------------------------------------------------------- */
 void Dumpable::setBaseNameToDumper(const std::string & dumper_name,
                                    const std::string & basename) {
   DumperIOHelper & dumper = this->getDumper(dumper_name);
   dumper.setBaseName(basename);
 }
 
 /* -------------------------------------------------------------------------- */
 void Dumpable::setTimeStepToDumper(Real time_step) {
   this->setTimeStepToDumper(this->default_dumper, time_step);
 }
 
 /* -------------------------------------------------------------------------- */
 void Dumpable::setTimeStepToDumper(const std::string & dumper_name,
                                    Real time_step) {
   DumperIOHelper & dumper = this->getDumper(dumper_name);
   dumper.setTimeStep(time_step);
 }
 
 /* -------------------------------------------------------------------------- */
 
 void Dumpable::setTextModeToDumper(const std::string & dumper_name) {
   DumperIOHelper & dumper = this->getDumper(dumper_name);
   dumper.getDumper().setMode(iohelper::TEXT);
 }
 
 /* -------------------------------------------------------------------------- */
 void Dumpable::setTextModeToDumper() {
   DumperIOHelper & dumper = this->getDumper(this->default_dumper);
   dumper.getDumper().setMode(iohelper::TEXT);
 }
 
 /* -------------------------------------------------------------------------- */
 
 void Dumpable::dump(const std::string & dumper_name) {
   DumperIOHelper & dumper = this->getDumper(dumper_name);
   dumper.dump();
 }
 
 /* -------------------------------------------------------------------------- */
 void Dumpable::dump() { this->dump(this->default_dumper); }
 
 /* -------------------------------------------------------------------------- */
 void Dumpable::dump(const std::string & dumper_name, UInt step) {
   DumperIOHelper & dumper = this->getDumper(dumper_name);
   dumper.dump(step);
 }
 
 /* -------------------------------------------------------------------------- */
 void Dumpable::dump(UInt step) { this->dump(this->default_dumper, step); }
 
 /* -------------------------------------------------------------------------- */
 void Dumpable::dump(const std::string & dumper_name, Real time, UInt step) {
   DumperIOHelper & dumper = this->getDumper(dumper_name);
   dumper.dump(time, step);
 }
 
 /* -------------------------------------------------------------------------- */
 void Dumpable::dump(Real time, UInt step) {
   this->dump(this->default_dumper, time, step);
 }
 
 /* -------------------------------------------------------------------------- */
 void Dumpable::internalAddDumpFieldToDumper(const std::string & dumper_name,
                                             const std::string & field_id,
                                             dumper::Field * field) {
   DumperIOHelper & dumper = this->getDumper(dumper_name);
   dumper.registerField(field_id, field);
 }
 
 /* -------------------------------------------------------------------------- */
 DumperIOHelper & Dumpable::getDumper() {
   return this->getDumper(this->default_dumper);
 }
 
 /* -------------------------------------------------------------------------- */
 DumperIOHelper & Dumpable::getDumper(const std::string & dumper_name) {
 
   auto it = this->dumpers.find(dumper_name);
   auto end = this->dumpers.end();
 
   if (it == end)
     AKANTU_EXCEPTION("Dumper " << dumper_name
                                << "has not been registered, yet.");
 
   return *(it->second);
 }
 
 /* -------------------------------------------------------------------------- */
 
 std::string Dumpable::getDefaultDumperName() const {
   return this->default_dumper;
 }
 
 } // akantu
 
 #endif
diff --git a/src/io/dumper/dumpable.hh b/src/io/dumper/dumpable.hh
index 985e3b9f7..3ef6f269e 100644
--- a/src/io/dumper/dumpable.hh
+++ b/src/io/dumper/dumpable.hh
@@ -1,48 +1,47 @@
 /**
  * @file   dumpable.hh
  *
  * @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
  * @author David Simon Kammer <david.kammer@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Fri Oct 26 2012
- * @date last modification: Tue Jan 06 2015
+ * @date last modification: Wed Feb 03 2016
  *
  * @brief  Interface for object who wants to dump themselves
  *
  * @section LICENSE
  *
- * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
- * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
- * Solides)
+ * 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
+ * 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
+ * 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 "element_type_map.hh"
 /* -------------------------------------------------------------------------- */
 
 #ifndef __AKANTU_DUMPABLE_HH__
 #define __AKANTU_DUMPABLE_HH__
 
 #ifdef AKANTU_USE_IOHELPER
 #include "dumpable_iohelper.hh"
 #else
 #include "dumpable_dummy.hh"
 #endif // AKANTU_USE_IOHELPER
 
 #endif /* __AKANTU_DUMPABLE_HH__ */
diff --git a/src/io/dumper/dumpable_dummy.hh b/src/io/dumper/dumpable_dummy.hh
index 0b9fb4694..eb9420dfd 100644
--- a/src/io/dumper/dumpable_dummy.hh
+++ b/src/io/dumper/dumpable_dummy.hh
@@ -1,265 +1,264 @@
 /**
  * @file   dumpable_dummy.hh
  *
  * @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
  * @author David Simon Kammer <david.kammer@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Fri Oct 26 2012
- * @date last modification: Fri Aug 21 2015
+ * @date last modification: Tue Feb 20 2018
  *
  * @brief  Interface for object who wants to dump themselves
  *
  * @section LICENSE
  *
- * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
- * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
- * Solides)
+ * 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
+ * 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
+ * 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_DUMPABLE_DUMMY_HH__
 #define __AKANTU_DUMPABLE_DUMMY_HH__
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 #pragma GCC diagnostic push
 #pragma GCC diagnostic ignored "-Wunused"
 
 namespace dumper {
   class Field;
 }
 
 class DumperIOHelper;
 class Mesh;
 
 /* -------------------------------------------------------------------------- */
 class Dumpable {
   /* ------------------------------------------------------------------------ */
   /* Constructors/Destructors                                                 */
   /* ------------------------------------------------------------------------ */
 public:
   Dumpable(){};
   virtual ~Dumpable(){};
 
   /* ------------------------------------------------------------------------ */
   /* Methods                                                                  */
   /* ------------------------------------------------------------------------ */
 public:
   template <class T>
   inline void registerDumper(const std::string & dumper_name,
                              const std::string & file_name = "",
                              const bool is_default = false) {}
 
   void registerExternalDumper(DumperIOHelper * dumper,
                               const std::string & dumper_name,
                               const bool is_default = false) {}
 
   void addDumpMesh(const Mesh & mesh, UInt spatial_dimension = _all_dimensions,
                    const GhostType & ghost_type = _not_ghost,
                    const ElementKind & element_kind = _ek_not_defined) {}
 
   void addDumpMeshToDumper(const std::string & dumper_name, const Mesh & mesh,
                            UInt spatial_dimension = _all_dimensions,
                            const GhostType & ghost_type = _not_ghost,
                            const ElementKind & element_kind = _ek_not_defined) {
   }
 
   void addDumpFilteredMesh(const Mesh & mesh,
                            const ElementTypeMapArray<UInt> & elements_filter,
                            const Array<UInt> & nodes_filter,
                            UInt spatial_dimension = _all_dimensions,
                            const GhostType & ghost_type = _not_ghost,
                            const ElementKind & element_kind = _ek_not_defined) {
   }
 
   void addDumpFilteredMeshToDumper(
       const std::string & dumper_name, const Mesh & mesh,
       const ElementTypeMapArray<UInt> & elements_filter,
       const Array<UInt> & nodes_filter,
       UInt spatial_dimension = _all_dimensions,
       const GhostType & ghost_type = _not_ghost,
       const ElementKind & element_kind = _ek_not_defined) {}
 
   virtual void addDumpField(const std::string & field_id) {
     AKANTU_TO_IMPLEMENT();
   }
   virtual void addDumpFieldToDumper(const std::string & dumper_name,
                                     const std::string & field_id) {
     AKANTU_TO_IMPLEMENT();
   }
 
   virtual void addDumpFieldExternal(const std::string & field_id,
                                     dumper::Field * field) {
     AKANTU_DEBUG_WARNING("No dumper activated at compilation, turn on "
                          "AKANTU_USE_IOHELPER in cmake.");
   }
   virtual void addDumpFieldExternalToDumper(const std::string & dumper_name,
                                             const std::string & field_id,
                                             dumper::Field * field) {
     AKANTU_DEBUG_WARNING("No dumper activated at compilation, turn on "
                          "AKANTU_USE_IOHELPER in cmake.");
   }
 
   template <typename T>
   void addDumpFieldExternal(const std::string & field_id,
                             const Array<T> & field) {
     AKANTU_DEBUG_WARNING("No dumper activated at compilation, turn on "
                          "AKANTU_USE_IOHELPER in cmake.");
   }
   template <typename T>
   void addDumpFieldExternalToDumper(const std::string & dumper_name,
                                     const std::string & field_id,
                                     const Array<T> & field) {
     AKANTU_DEBUG_WARNING("No dumper activated at compilation, turn on "
                          "AKANTU_USE_IOHELPER in cmake.");
   }
 
   template <typename T>
   void
   addDumpFieldExternal(const std::string & field_id,
                        const ElementTypeMapArray<T> & field,
                        UInt spatial_dimension = _all_dimensions,
                        const GhostType & ghost_type = _not_ghost,
                        const ElementKind & element_kind = _ek_not_defined) {
     AKANTU_DEBUG_WARNING("No dumper activated at compilation, turn on "
                          "AKANTU_USE_IOHELPER in cmake.");
   }
   template <typename T>
   void addDumpFieldExternalToDumper(
       const std::string & dumper_name, const std::string & field_id,
       const ElementTypeMapArray<T> & field,
       UInt spatial_dimension = _all_dimensions,
       const GhostType & ghost_type = _not_ghost,
       const ElementKind & element_kind = _ek_not_defined) {
     AKANTU_DEBUG_WARNING("No dumper activated at compilation, turn on "
                          "AKANTU_USE_IOHELPER in cmake.");
   }
 
   void removeDumpField(const std::string & field_id) {
     AKANTU_DEBUG_WARNING("No dumper activated at compilation, turn on "
                          "AKANTU_USE_IOHELPER in cmake.");
   }
   void removeDumpFieldFromDumper(const std::string & dumper_name,
                                  const std::string & field_id) {
     AKANTU_DEBUG_WARNING("No dumper activated at compilation, turn on "
                          "AKANTU_USE_IOHELPER in cmake.");
   }
 
   void setDirecory(const std::string & directory) {
     AKANTU_DEBUG_WARNING("No dumper activated at compilation, turn on "
                          "AKANTU_USE_IOHELPER in cmake.");
   }
   void setDirectoryToDumper(const std::string & dumper_name,
                             const std::string & directory) {
     AKANTU_DEBUG_WARNING("No dumper activated at compilation, turn on "
                          "AKANTU_USE_IOHELPER in cmake.");
   }
 
   void setBaseName(const std::string & basename) {
     AKANTU_DEBUG_WARNING("No dumper activated at compilation, turn on "
                          "AKANTU_USE_IOHELPER in cmake.");
   }
   void setBaseNameToDumper(const std::string & dumper_name,
                            const std::string & basename) {
     AKANTU_DEBUG_WARNING("No dumper activated at compilation, turn on "
                          "AKANTU_USE_IOHELPER in cmake.");
   }
 
   void setTextModeToDumper(const std::string & dumper_name) {
     AKANTU_DEBUG_WARNING("No dumper activated at compilation, turn on "
                          "AKANTU_USE_IOHELPER in cmake.");
   }
   void setTextModeToDumper() {
     AKANTU_DEBUG_WARNING("No dumper activated at compilation, turn on "
                          "AKANTU_USE_IOHELPER in cmake.");
   }
 
   void dump() {
     AKANTU_DEBUG_WARNING("No dumper activated at compilation, turn on "
                          "AKANTU_USE_IOHELPER in cmake.");
   }
   void dump(const std::string & dumper_name) {
     AKANTU_DEBUG_WARNING("No dumper activated at compilation, turn on "
                          "AKANTU_USE_IOHELPER in cmake.");
   }
 
   void dump(UInt step) {
     AKANTU_DEBUG_WARNING("No dumper activated at compilation, turn on "
                          "AKANTU_USE_IOHELPER in cmake.");
   }
   void dump(const std::string & dumper_name, UInt step) {
     AKANTU_DEBUG_WARNING("No dumper activated at compilation, turn on "
                          "AKANTU_USE_IOHELPER in cmake.");
   }
 
   void dump(Real current_time, UInt step) {
     AKANTU_DEBUG_WARNING("No dumper activated at compilation, turn on "
                          "AKANTU_USE_IOHELPER in cmake.");
   }
   void dump(const std::string & dumper_name, Real current_time, UInt step) {
     AKANTU_DEBUG_WARNING("No dumper activated at compilation, turn on "
                          "AKANTU_USE_IOHELPER in cmake.");
   }
 
 protected:
   void internalAddDumpFieldToDumper(const std::string & dumper_name,
                                     const std::string & field_id,
                                     dumper::Field * field) {
     AKANTU_DEBUG_WARNING("No dumper activated at compilation, turn on "
                          "AKANTU_USE_IOHELPER in cmake.");
   }
 
 protected:
   /* ------------------------------------------------------------------------ */
   /* Accessors                                                                */
   /* ------------------------------------------------------------------------ */
 public:
   DumperIOHelper & getDumper() {
     AKANTU_ERROR("No dumper activated at compilation, turn on "
                  "AKANTU_USE_IOHELPER in cmake.");
   }
 
   DumperIOHelper & getDumper(const std::string & dumper_name) {
     AKANTU_ERROR("No dumper activated at compilation, turn on "
                  "AKANTU_USE_IOHELPER in cmake.");
   }
 
   template <class T> T & getDumper(const std::string & dumper_name) {
     AKANTU_ERROR("No dumper activated at compilation, turn on "
                  "AKANTU_USE_IOHELPER in cmake.");
   }
 
   std::string getDefaultDumperName() {
     AKANTU_ERROR("No dumper activated at compilation, turn on "
                  "AKANTU_USE_IOHELPER in cmake.");
   }
 
   /* ------------------------------------------------------------------------ */
   /* Class Members                                                            */
   /* ------------------------------------------------------------------------ */
 private:
 };
 
 #pragma GCC diagnostic pop
 
 } // akantu
 
 #endif /* __AKANTU_DUMPABLE_DUMMY_HH__ */
diff --git a/src/io/dumper/dumpable_inline_impl.hh b/src/io/dumper/dumpable_inline_impl.hh
index 638462db5..012b570b4 100644
--- a/src/io/dumper/dumpable_inline_impl.hh
+++ b/src/io/dumper/dumpable_inline_impl.hh
@@ -1,134 +1,134 @@
 /**
  * @file   dumpable_inline_impl.hh
  *
  * @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
  * @author David Simon Kammer <david.kammer@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Wed Nov 13 2013
- * @date last modification: Thu Jan 21 2016
+ * @date last modification: Wed Nov 08 2017
  *
  * @brief  Implementation of the Dumpable class
  *
  * @section LICENSE
  *
- * Copyright  (©)  2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de Lausanne)
+ * 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
+ * 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
+ * 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_DUMPABLE_INLINE_IMPL_HH__
 #define __AKANTU_DUMPABLE_INLINE_IMPL_HH__
 
 /* -------------------------------------------------------------------------- */
 #ifdef AKANTU_USE_IOHELPER
 #include "dumper_elemental_field.hh"
 #include "dumper_nodal_field.hh"
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 template <class T>
 inline void Dumpable::registerDumper(const std::string & dumper_name,
                                      const std::string & file_name,
                                      const bool is_default) {
 
   if (this->dumpers.find(dumper_name) != this->dumpers.end()) {
     AKANTU_DEBUG_INFO("Dumper " + dumper_name + "is already registered.");
   }
 
   std::string name = file_name;
   if (name == "")
     name = dumper_name;
 
   this->dumpers[dumper_name] = new T(name);
 
   if (is_default)
     this->default_dumper = dumper_name;
 }
 
 /* -------------------------------------------------------------------------- */
 template <typename T>
 inline void Dumpable::addDumpFieldExternal(const std::string & field_id,
                                            const Array<T> & field) {
   this->addDumpFieldExternalToDumper<T>(this->default_dumper, field_id, field);
 }
 
 /* -------------------------------------------------------------------------- */
 template <typename T>
 inline void
 Dumpable::addDumpFieldExternalToDumper(const std::string & dumper_name,
                                        const std::string & field_id,
                                        const Array<T> & field) {
   dumper::Field * field_cont = new dumper::NodalField<T>(field);
   DumperIOHelper & dumper = this->getDumper(dumper_name);
   dumper.registerField(field_id, field_cont);
 }
 
 /* -------------------------------------------------------------------------- */
 template <typename T>
 inline void Dumpable::addDumpFieldExternal(const std::string & field_id,
                                            const ElementTypeMapArray<T> & field,
                                            UInt spatial_dimension,
                                            const GhostType & ghost_type,
                                            const ElementKind & element_kind) {
   this->addDumpFieldExternalToDumper(this->default_dumper, field_id, field,
                                      spatial_dimension, ghost_type,
                                      element_kind);
 }
 
 /* -------------------------------------------------------------------------- */
 template <typename T>
 inline void Dumpable::addDumpFieldExternalToDumper(
     const std::string & dumper_name, const std::string & field_id,
     const ElementTypeMapArray<T> & field, UInt spatial_dimension,
     const GhostType & ghost_type, const ElementKind & element_kind) {
 
   dumper::Field * field_cont;
 #if defined(AKANTU_IGFEM)
   if (element_kind == _ek_igfem) {
     field_cont = new dumper::IGFEMElementalField<T>(field, spatial_dimension,
                                                     ghost_type, element_kind);
   } else
 #endif
     field_cont = new dumper::ElementalField<T>(field, spatial_dimension,
                                                ghost_type, element_kind);
   DumperIOHelper & dumper = this->getDumper(dumper_name);
   dumper.registerField(field_id, field_cont);
 }
 
 /* -------------------------------------------------------------------------- */
 template <class T>
 inline T & Dumpable::getDumper(const std::string & dumper_name) {
   DumperIOHelper & dumper = this->getDumper(dumper_name);
 
   try {
     auto & templated_dumper = dynamic_cast<T &>(dumper);
     return templated_dumper;
   } catch (std::bad_cast &) {
     AKANTU_EXCEPTION("Dumper " << dumper_name << " is not of type: "
                                << debug::demangle(typeid(T).name()));
   }
 }
 
 /* -------------------------------------------------------------------------- */
 
 } // akantu
 
 #endif
 
 #endif /* __AKANTU_DUMPABLE_INLINE_IMPL_HH__ */
diff --git a/src/io/dumper/dumpable_iohelper.hh b/src/io/dumper/dumpable_iohelper.hh
index e9252526f..02bacd64f 100644
--- a/src/io/dumper/dumpable_iohelper.hh
+++ b/src/io/dumper/dumpable_iohelper.hh
@@ -1,192 +1,192 @@
 /**
  * @file   dumpable_iohelper.hh
  *
  * @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
  * @author David Simon Kammer <david.kammer@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Tue Jan 06 2015
- * @date last modification: Thu Nov 19 2015
+ * @date last modification: Sun Dec 03 2017
  *
  * @brief  Interface for object who wants to dump themselves
  *
  * @section LICENSE
  *
- * Copyright (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne) Laboratory
- * (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * Copyright (©) 2015-2018 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
- * terms  of the  GNU Lesser  General Public  License as  published by  the Free
+ * 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
+ * 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 "dumper_iohelper.hh"
 /* -------------------------------------------------------------------------- */
 #include <set>
 /* -------------------------------------------------------------------------- */
 #ifndef __AKANTU_DUMPABLE_IOHELPER_HH__
 #define __AKANTU_DUMPABLE_IOHELPER_HH__
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 
 class Dumpable {
   /* ------------------------------------------------------------------------ */
   /* Constructors/Destructors                                                 */
   /* ------------------------------------------------------------------------ */
 public:
   Dumpable();
   virtual ~Dumpable();
 
   /* ------------------------------------------------------------------------ */
   /* Methods                                                                  */
   /* ------------------------------------------------------------------------ */
 public:
   /// create a new dumper (of templated type T) and register it under
   /// dumper_name. file_name is used for construction of T. is default states if
   /// this dumper is the default dumper.
   template <class T>
   inline void registerDumper(const std::string & dumper_name,
                              const std::string & file_name = "",
                              const bool is_default = false);
 
   /// register an externally created dumper
   void registerExternalDumper(DumperIOHelper & dumper,
                               const std::string & dumper_name,
                               const bool is_default = false);
 
   /// register a mesh to the default dumper
   void addDumpMesh(const Mesh & mesh, UInt spatial_dimension = _all_dimensions,
                    const GhostType & ghost_type = _not_ghost,
                    const ElementKind & element_kind = _ek_not_defined);
 
   /// register a mesh to the default identified by its name
   void addDumpMeshToDumper(const std::string & dumper_name, const Mesh & mesh,
                            UInt spatial_dimension = _all_dimensions,
                            const GhostType & ghost_type = _not_ghost,
                            const ElementKind & element_kind = _ek_not_defined);
 
   /// register a filtered mesh as the default dumper
   void addDumpFilteredMesh(const Mesh & mesh,
                            const ElementTypeMapArray<UInt> & elements_filter,
                            const Array<UInt> & nodes_filter,
                            UInt spatial_dimension = _all_dimensions,
                            const GhostType & ghost_type = _not_ghost,
                            const ElementKind & element_kind = _ek_not_defined);
 
   /// register a filtered mesh and provides a name
   void addDumpFilteredMeshToDumper(
       const std::string & dumper_name, const Mesh & mesh,
       const ElementTypeMapArray<UInt> & elements_filter,
       const Array<UInt> & nodes_filter,
       UInt spatial_dimension = _all_dimensions,
       const GhostType & ghost_type = _not_ghost,
       const ElementKind & element_kind = _ek_not_defined);
 
   /// to implement
   virtual void addDumpField(const std::string & field_id);
   /// to implement
   virtual void addDumpFieldToDumper(const std::string & dumper_name,
                                     const std::string & field_id);
   /// add a field
   virtual void addDumpFieldExternal(const std::string & field_id,
                                     dumper::Field * field);
   virtual void addDumpFieldExternalToDumper(const std::string & dumper_name,
                                             const std::string & field_id,
                                             dumper::Field * field);
 
   template <typename T>
   inline void addDumpFieldExternal(const std::string & field_id,
                                    const Array<T> & field);
   template <typename T>
   inline void addDumpFieldExternalToDumper(const std::string & dumper_name,
                                            const std::string & field_id,
                                            const Array<T> & field);
   template <typename T>
   inline void
   addDumpFieldExternal(const std::string & field_id,
                        const ElementTypeMapArray<T> & field,
                        UInt spatial_dimension = _all_dimensions,
                        const GhostType & ghost_type = _not_ghost,
                        const ElementKind & element_kind = _ek_not_defined);
   template <typename T>
   inline void addDumpFieldExternalToDumper(
       const std::string & dumper_name, const std::string & field_id,
       const ElementTypeMapArray<T> & field,
       UInt spatial_dimension = _all_dimensions,
       const GhostType & ghost_type = _not_ghost,
       const ElementKind & element_kind = _ek_not_defined);
 
   void removeDumpField(const std::string & field_id);
   void removeDumpFieldFromDumper(const std::string & dumper_name,
                                  const std::string & field_id);
 
   virtual void addDumpFieldVector(const std::string & field_id);
   virtual void addDumpFieldVectorToDumper(const std::string & dumper_name,
                                           const std::string & field_id);
 
   virtual void addDumpFieldTensor(const std::string & field_id);
   virtual void addDumpFieldTensorToDumper(const std::string & dumper_name,
                                           const std::string & field_id);
 
   void setDirectory(const std::string & directory);
   void setDirectoryToDumper(const std::string & dumper_name,
                             const std::string & directory);
 
   void setBaseName(const std::string & basename);
 
   void setBaseNameToDumper(const std::string & dumper_name,
                            const std::string & basename);
   void setTimeStepToDumper(Real time_step);
   void setTimeStepToDumper(const std::string & dumper_name, Real time_step);
 
   void setTextModeToDumper(const std::string & dumper_name);
   void setTextModeToDumper();
 
   virtual void dump();
   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);
 
 public:
   void internalAddDumpFieldToDumper(const std::string & dumper_name,
                                     const std::string & field_id,
                                     dumper::Field * field);
 
   /* ------------------------------------------------------------------------ */
   /* Accessors                                                                */
   /* ------------------------------------------------------------------------ */
 public:
   DumperIOHelper & getDumper();
   DumperIOHelper & getDumper(const std::string & dumper_name);
 
   template <class T> T & getDumper(const std::string & dumper_name);
   std::string getDefaultDumperName() const;
 
   /* ------------------------------------------------------------------------ */
   /* Class Members                                                            */
   /* ------------------------------------------------------------------------ */
 private:
   using DumperMap = std::map<std::string, DumperIOHelper *>;
   using DumperSet = std::set<std::string>;
 
   DumperMap dumpers;
   std::string default_dumper;
 };
 
 } // akantu
 
 #endif /* __AKANTU_DUMPABLE_IOHELPER_HH__ */
diff --git a/src/io/dumper/dumper_compute.hh b/src/io/dumper/dumper_compute.hh
index 7af59b85c..0989f62b2 100644
--- a/src/io/dumper/dumper_compute.hh
+++ b/src/io/dumper/dumper_compute.hh
@@ -1,274 +1,274 @@
 /**
  * @file   dumper_compute.hh
  *
  * @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
  *
  * @date creation: Tue Sep 02 2014
- * @date last modification: Tue Jan 19 2016
+ * @date last modification: Sun Dec 03 2017
  *
  * @brief  Field that map a function to another field
  *
  * @section LICENSE
  *
- * Copyright  (©)  2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de Lausanne)
+ * 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
+ * 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
+ * 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 <io_helper.hh>
 
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 __BEGIN_AKANTU_DUMPER__
 
 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;
 };
 
 /* -------------------------------------------------------------------------- */
 template <typename SubFieldCompute, typename _return_type>
 class FieldCompute : public Field {
   /* ------------------------------------------------------------------------ */
   /* Typedefs                                                                 */
   /* ------------------------------------------------------------------------ */
 public:
   using sub_iterator = typename SubFieldCompute::iterator;
   using sub_types = typename SubFieldCompute::types;
   using sub_return_type = typename sub_types::return_type;
   using return_type = _return_type;
   using data_type = typename sub_types::data_type;
 
   using types =
       TypeTraits<data_type, return_type, ElementTypeMapArray<data_type>>;
 
   class iterator {
   public:
     iterator(const sub_iterator & it,
              ComputeFunctor<sub_return_type, return_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;
   };
 
   /* ------------------------------------------------------------------------ */
   /* Constructors/Destructors                                                 */
   /* ------------------------------------------------------------------------ */
 public:
   FieldCompute(SubFieldCompute & cont, ComputeFunctorInterface & func)
       : sub_field(cont),
         func(dynamic_cast<ComputeFunctor<sub_return_type, return_type> &>(
             func)) {
     this->checkHomogeneity();
   };
 
   ~FieldCompute() override {
     delete &(this->sub_field);
     delete &(this->func);
   }
 
   void registerToDumper(const std::string & id,
                         iohelper::Dumper & dumper) override {
     dumper.addElemDataField(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>();
   }
 
   /// 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 ElementTypeMap<UInt> & old_nb_components =
         this->sub_field.getNbComponents(dim, ghost_type, kind);
 
     ElementTypeMap<UInt>::type_iterator tit =
         old_nb_components.firstType(dim, ghost_type, kind);
     ElementTypeMap<UInt>::type_iterator end =
         old_nb_components.lastType(dim, ghost_type, kind);
 
     while (tit != end) {
       UInt nb_comp = old_nb_components(*tit, ghost_type);
       nb_components(*tit, ghost_type) = func.getNbComponent(nb_comp);
       ++tit;
     }
     return nb_components;
   };
 
   /// for connection to a FieldCompute
   inline Field * connect(FieldComputeProxy & proxy) override;
 
   /// for connection to a FieldCompute
   ComputeFunctorInterface * connect(HomogenizerProxy & proxy) override;
 
   /* ------------------------------------------------------------------------ */
   /* Class Members                                                            */
   /* ------------------------------------------------------------------------ */
 public:
   SubFieldCompute & sub_field;
   ComputeFunctor<sub_return_type, return_type> & func;
 };
 
 /* -------------------------------------------------------------------------- */
 
 /* -------------------------------------------------------------------------- */
 
 class FieldComputeProxy {
   /* ------------------------------------------------------------------------ */
   /* Constructors/Destructors                                                 */
   /* ------------------------------------------------------------------------ */
 public:
   FieldComputeProxy(ComputeFunctorInterface & func) : func(func){};
 
   inline static Field * createFieldCompute(Field * field,
                                            ComputeFunctorInterface & func) {
     /// that looks fishy an object passed as a ref and destroyed at their end of
     /// the function
     FieldComputeProxy compute_proxy(func);
     return field->connect(compute_proxy);
   }
 
   template <typename T> Field * connectToField(T * ptr) {
     if (dynamic_cast<ComputeFunctorOutput<Vector<Real>> *>(&func)) {
       return this->connectToFunctor<Vector<Real>>(ptr);
     } else if (dynamic_cast<ComputeFunctorOutput<Vector<UInt>> *>(&func)) {
       return this->connectToFunctor<Vector<UInt>>(ptr);
     }
 
     else if (dynamic_cast<ComputeFunctorOutput<Matrix<UInt>> *>(&func)) {
       return this->connectToFunctor<Matrix<UInt>>(ptr);
     }
 
     else if (dynamic_cast<ComputeFunctorOutput<Matrix<Real>> *>(&func)) {
       return this->connectToFunctor<Matrix<Real>>(ptr);
     }
 
     else
       throw;
   }
 
   template <typename output, typename T> Field * connectToFunctor(T * ptr) {
     auto * functor_ptr = new FieldCompute<T, output>(*ptr, func);
     return functor_ptr;
   }
 
   template <typename output, typename SubFieldCompute, typename return_type1,
             typename return_type2>
   Field *
   connectToFunctor(__attribute__((unused))
                    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>
   Field * connectToFunctor(
       __attribute__((unused)) 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                                                            */
   /* ------------------------------------------------------------------------ */
 public:
   ComputeFunctorInterface & func;
 };
 
 /* -------------------------------------------------------------------------- */
 /// for connection to a FieldCompute
 template <typename SubFieldCompute, typename return_type>
 inline Field *
 FieldCompute<SubFieldCompute, return_type>::connect(FieldComputeProxy & proxy) {
   return proxy.connectToField(this);
 }
 
 /* -------------------------------------------------------------------------- */
 __END_AKANTU_DUMPER__
 } // akantu
 
 #endif /* __AKANTU_DUMPER_COMPUTE_HH__ */
diff --git a/src/io/dumper/dumper_element_iterator.hh b/src/io/dumper/dumper_element_iterator.hh
index 24319d083..9710b7d7c 100644
--- a/src/io/dumper/dumper_element_iterator.hh
+++ b/src/io/dumper/dumper_element_iterator.hh
@@ -1,178 +1,178 @@
 /**
  * @file   dumper_element_iterator.hh
  *
  * @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Tue Sep 02 2014
- * @date last modification: Fri May 15 2015
+ * @date last modification: Sun Dec 03 2017
  *
  * @brief  Iterators for elemental fields
  *
  * @section LICENSE
  *
- * Copyright  (©)  2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de Lausanne)
+ * 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
+ * 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
+ * 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_ELEMENT_ITERATOR_HH__
 #define __AKANTU_DUMPER_ELEMENT_ITERATOR_HH__
 /* -------------------------------------------------------------------------- */
 #include "element.hh"
 /* -------------------------------------------------------------------------- */
 namespace akantu {
 __BEGIN_AKANTU_DUMPER__
 /* -------------------------------------------------------------------------- */
 
 template <class types, template <class> class final_iterator>
 class element_iterator {
   /* ------------------------------------------------------------------------ */
   /* Typedefs                                                                 */
   /* ------------------------------------------------------------------------ */
 public:
   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 iterator = final_iterator<types>;
 
 public:
   /* ------------------------------------------------------------------------ */
   /* Constructors/Destructors                                                 */
   /* ------------------------------------------------------------------------ */
 
   element_iterator(const field_type & field,
                    const typename field_type::type_iterator & t_it,
                    const typename field_type::type_iterator & t_it_end,
                    const array_iterator & array_it,
                    const array_iterator & array_it_end,
                    const GhostType ghost_type = _not_ghost)
       : field(field), tit(t_it), tit_end(t_it_end), array_it(array_it),
         array_it_end(array_it_end), ghost_type(ghost_type) {}
 
   /* ------------------------------------------------------------------------ */
   /* Methods                                                                  */
   /* ------------------------------------------------------------------------ */
 
 public:
   bool operator!=(const iterator & it) const {
     return (ghost_type != it.ghost_type) ||
            (tit != it.tit || (array_it != it.array_it));
   }
 
   iterator & operator++() {
     ++array_it;
     while (array_it == array_it_end && tit != tit_end) {
       ++tit;
       if (tit != tit_end) {
 
         const array_type & vect = field(*tit, ghost_type);
         UInt _nb_data_per_elem = getNbDataPerElem(*tit);
         UInt nb_component = vect.getNbComponent();
         UInt size = (vect.size() * nb_component) / _nb_data_per_elem;
 
         array_it = vect.begin_reinterpret(_nb_data_per_elem, size);
         array_it_end = vect.end_reinterpret(_nb_data_per_elem, size);
       }
     }
     return *(static_cast<iterator *>(this));
   };
 
   ElementType getType() { return *tit; }
 
   UInt element_type() { return getIOHelperType(*tit); }
 
   Element getCurrentElement() {
     return Element{*tit, array_it.getCurrentIndex(), _not_ghost};
   }
 
   UInt getNbDataPerElem(const ElementType & type) const {
     if (!nb_data_per_elem.exists(type, ghost_type))
       return field(type, ghost_type).getNbComponent();
 
     return nb_data_per_elem(type, ghost_type);
   }
 
   void setNbDataPerElem(const ElementTypeMap<UInt> & nb_data) {
     this->nb_data_per_elem = nb_data;
   }
 
   /* ------------------------------------------------------------------------ */
   /* Class Members                                                            */
   /* ------------------------------------------------------------------------ */
 
 protected:
   /// the field to iterate on
   const field_type & field;
   /// field iterator
   typename field_type::type_iterator tit;
   /// field iterator end
   typename field_type::type_iterator tit_end;
   /// array iterator
   array_iterator array_it;
   /// internal iterator end
   array_iterator array_it_end;
   /// ghost type identification
   const GhostType ghost_type;
   /// number of data per element
   ElementTypeMap<UInt> nb_data_per_elem;
 };
 
 /* -------------------------------------------------------------------------- */
 template <typename types>
 class elemental_field_iterator
     : public element_iterator<types, elemental_field_iterator> {
 public:
   /* ------------------------------------------------------------------------ */
   /* Typedefs                                                                 */
   /* ------------------------------------------------------------------------ */
 
   using parent =
       element_iterator<types, ::akantu::dumper::elemental_field_iterator>;
   using it_type = typename types::it_type;
   using return_type = typename types::return_type;
   using field_type = typename types::field_type;
   using array_iterator = typename types::array_iterator;
 
 public:
   /* ------------------------------------------------------------------------ */
   /* Constructors/Destructors                                                 */
   /* ------------------------------------------------------------------------ */
 
   elemental_field_iterator(const field_type & field,
                            const typename field_type::type_iterator & t_it,
                            const typename field_type::type_iterator & t_it_end,
                            const array_iterator & array_it,
                            const array_iterator & array_it_end,
                            const GhostType ghost_type = _not_ghost)
       : parent(field, t_it, t_it_end, array_it, array_it_end, ghost_type) {}
 
   /* ------------------------------------------------------------------------ */
   /* Methods                                                                  */
   /* ------------------------------------------------------------------------ */
 
   return_type operator*() { return *this->array_it; }
 
 private:
 };
 
 /* -------------------------------------------------------------------------- */
 __END_AKANTU_DUMPER__
 } // akantu
 /* -------------------------------------------------------------------------- */
 
 #endif /* __AKANTU_DUMPER_ELEMENT_ITERATOR_HH__ */
diff --git a/src/io/dumper/dumper_element_partition.hh b/src/io/dumper/dumper_element_partition.hh
index 3718e35e2..4885ebe09 100644
--- a/src/io/dumper/dumper_element_partition.hh
+++ b/src/io/dumper/dumper_element_partition.hh
@@ -1,118 +1,118 @@
 /**
  * @file   dumper_element_partition.hh
  *
  * @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Tue Sep 02 2014
- * @date last modification: Tue Jul 14 2015
+ * @date last modification: Sun Dec 03 2017
  *
  * @brief  ElementPartition field
  *
  * @section LICENSE
  *
- * Copyright  (©)  2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de Lausanne)
+ * 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
+ * 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
+ * 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/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 namespace akantu {
 __BEGIN_AKANTU_DUMPER__
 #ifdef AKANTU_IGFEM
 #include "dumper_igfem_element_partition.hh"
 #endif
 /* -------------------------------------------------------------------------- */
 template <class types>
 class element_partition_field_iterator
     : public element_iterator<types, element_partition_field_iterator> {
 
   /* ------------------------------------------------------------------------ */
   /* Typedefs                                                                 */
   /* ------------------------------------------------------------------------ */
 public:
   using parent =
       element_iterator<types, dumper::element_partition_field_iterator>;
   using return_type =
       typename SingleType<unsigned int, Vector, true>::return_type;
   using array_iterator = typename types::array_iterator;
   using field_type = typename types::field_type;
 
   /* ------------------------------------------------------------------------ */
   /* Constructors/Destructors                                                 */
   /* ------------------------------------------------------------------------ */
 public:
   element_partition_field_iterator(
       const field_type & field, const typename field_type::type_iterator & t_it,
       const typename field_type::type_iterator & t_it_end,
       const array_iterator & array_it, const array_iterator & array_it_end,
       const GhostType ghost_type = _not_ghost)
       : parent(field, t_it, t_it_end, array_it, array_it_end, ghost_type) {
     prank = Communicator::getStaticCommunicator().whoAmI();
   }
 
   /* ------------------------------------------------------------------------ */
   /* Methods                                                                  */
   /* ------------------------------------------------------------------------ */
 public:
   return_type operator*() { return return_type(1, prank); }
 
   /* ------------------------------------------------------------------------ */
   /* Class Members                                                            */
   /* ------------------------------------------------------------------------ */
 protected:
   UInt prank;
 };
 
 /* -------------------------------------------------------------------------- */
 template <bool filtered = false>
 class ElementPartitionField
     : public GenericElementalField<SingleType<UInt, Vector, filtered>,
                                    element_partition_field_iterator> {
 public:
   /* ------------------------------------------------------------------------ */
   /* Typedefs                                                                 */
   /* ------------------------------------------------------------------------ */
 
   using types = SingleType<UInt, Vector, filtered>;
   using iterator = element_partition_field_iterator<types>;
   using parent = GenericElementalField<types, element_partition_field_iterator>;
   using field_type = typename types::field_type;
 
 public:
   /* ------------------------------------------------------------------------ */
   /* Constructors/Destructors                                                 */
   /* ------------------------------------------------------------------------ */
 
   ElementPartitionField(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) {
     this->homogeneous = true;
   }
 
   /* ------------------------------------------------------------------------ */
   /* Methods                                                                  */
   /* ------------------------------------------------------------------------ */
 
   UInt getDim() override { return 1; }
 };
 
 /* -------------------------------------------------------------------------- */
 
 __END_AKANTU_DUMPER__
 } // akantu
diff --git a/src/io/dumper/dumper_elemental_field.hh b/src/io/dumper/dumper_elemental_field.hh
index c62bf7b6c..3caf94b40 100644
--- a/src/io/dumper/dumper_elemental_field.hh
+++ b/src/io/dumper/dumper_elemental_field.hh
@@ -1,77 +1,76 @@
 /**
  * @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: Mon Aug 17 2015
+ * @date last modification: Sun Dec 03 2017
  *
  * @brief  description of elemental fields
  *
  * @section LICENSE
  *
- * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
- * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
- * Solides)
+ * 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
+ * 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
+ * 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 {
 __BEGIN_AKANTU_DUMPER__
 /* -------------------------------------------------------------------------- */
 
 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>;
 
   /* ------------------------------------------------------------------------ */
   /* 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) {}
 };
 
 /* -------------------------------------------------------------------------- */
 
 __END_AKANTU_DUMPER__
 } // akantu
 
 #endif /* __AKANTU_DUMPER_ELEMENTAL_FIELD_HH__ */
diff --git a/src/io/dumper/dumper_field.hh b/src/io/dumper/dumper_field.hh
index 66544d73e..ebe765ce8 100644
--- a/src/io/dumper/dumper_field.hh
+++ b/src/io/dumper/dumper_field.hh
@@ -1,137 +1,137 @@
 /**
  * @file   dumper_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: Tue Jan 19 2016
+ * @date last modification: Tue Feb 20 2018
  *
  * @brief  Common interface for fields
  *
  * @section LICENSE
  *
- * Copyright  (©)  2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de Lausanne)
+ * 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
+ * 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
+ * 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_FIELD_HH__
 #define __AKANTU_DUMPER_FIELD_HH__
 /* -------------------------------------------------------------------------- */
 #include "dumper_iohelper.hh"
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 __BEGIN_AKANTU_DUMPER__
 /* -------------------------------------------------------------------------- */
 class FieldComputeProxy;
 class FieldComputeBaseInterface;
 class ComputeFunctorInterface;
 class HomogenizerProxy;
 /* -------------------------------------------------------------------------- */
 
 /// Field interface
 class Field {
   /* ------------------------------------------------------------------------ */
   /* Constructors/Destructors                                                 */
   /* ------------------------------------------------------------------------ */
 public:
   Field() = default;
   virtual ~Field() = default;
 
   /* ------------------------------------------------------------------------ */
   /* Methods                                                                  */
   /* ------------------------------------------------------------------------ */
 public:
 #ifdef AKANTU_USE_IOHELPER
   /// register this to the provided dumper
   virtual void registerToDumper(const std::string & id,
                                 iohelper::Dumper & dumper) = 0;
 #endif
 
   /// set the number of data per item (used for elements fields at the moment)
   virtual void setNbData(__attribute__((unused)) UInt nb_data) {
     AKANTU_TO_IMPLEMENT();
   };
 
   /// set the number of data per elem (used for elements fields at the moment)
   virtual void setNbDataPerElem(__attribute__((unused))
                                 const ElementTypeMap<UInt> & nb_data) {
     AKANTU_TO_IMPLEMENT();
   };
 
   /// set the number of data per elem (used for elements fields at the moment)
   virtual void setNbDataPerElem(__attribute__((unused)) UInt nb_data) {
     AKANTU_TO_IMPLEMENT();
   };
 
   /// get the number of components of the hosted field
   virtual ElementTypeMap<UInt>
   getNbComponents(__attribute__((unused)) UInt dim = _all_dimensions,
                   __attribute__((unused)) GhostType ghost_type = _not_ghost,
                   __attribute__((unused)) ElementKind kind = _ek_not_defined) {
     throw;
   };
 
   /// for connection to a FieldCompute
   inline virtual Field * connect(__attribute__((unused))
                                  FieldComputeProxy & proxy) {
     throw;
   };
 
   /// for connection to a FieldCompute
   inline virtual ComputeFunctorInterface * connect(__attribute__((unused))
                                                    HomogenizerProxy & proxy) {
     throw;
   };
 
   /// check if the same quantity of data for all element types
   virtual void checkHomogeneity() = 0;
 
   /// return the dumper name
   std::string getGroupName() { return group_name; };
 
   /// return the id of the field
   std::string getID() { return field_id; };
 
   /* ------------------------------------------------------------------------ */
   /* Accessors                                                                */
   /* ------------------------------------------------------------------------ */
 public:
   /// return the flag to know if the field is homogeneous/contiguous
   virtual bool isHomogeneous() { return homogeneous; }
 
   /* ------------------------------------------------------------------------ */
   /* Class Members                                                            */
   /* ------------------------------------------------------------------------ */
 protected:
   /// the flag to know if it is homogeneous
   bool homogeneous{false};
 
   /// the name of the group it was associated to
   std::string group_name;
 
   /// the name of the dumper it was associated to
   std::string field_id;
 };
 
 /* -------------------------------------------------------------------------- */
 
 __END_AKANTU_DUMPER__
 } // akantu
 
 #endif /* __AKANTU_DUMPER_FIELD_HH__ */
diff --git a/src/io/dumper/dumper_filtered_connectivity.hh b/src/io/dumper/dumper_filtered_connectivity.hh
index 1dfe20e0d..bfda0e792 100644
--- a/src/io/dumper/dumper_filtered_connectivity.hh
+++ b/src/io/dumper/dumper_filtered_connectivity.hh
@@ -1,152 +1,152 @@
 /**
  * @file   dumper_filtered_connectivity.hh
  *
  * @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Tue Sep 02 2014
- * @date last modification: Mon Aug 17 2015
+ * @date last modification: Wed Nov 08 2017
  *
  * @brief  FilteredConnectivities field
  *
  * @section LICENSE
  *
- * Copyright  (©)  2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de Lausanne)
+ * 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
+ * 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
+ * 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 "dumper_generic_elemental_field.hh"
 /* -------------------------------------------------------------------------- */
 namespace akantu {
 __BEGIN_AKANTU_DUMPER__
 /* -------------------------------------------------------------------------- */
 
 template <class types>
 class filtered_connectivity_field_iterator
     : public element_iterator<types, filtered_connectivity_field_iterator> {
   /* ------------------------------------------------------------------------ */
   /* Typedefs                                                                 */
   /* ------------------------------------------------------------------------ */
 public:
   typedef element_iterator<types, dumper::filtered_connectivity_field_iterator>
       parent;
   using return_type = typename types::return_type;
   using field_type = typename types::field_type;
   using array_iterator = typename types::array_iterator;
 
   /* ------------------------------------------------------------------------ */
   /* Constructors/Destructors                                                 */
   /* ------------------------------------------------------------------------ */
 public:
   filtered_connectivity_field_iterator(
       const field_type & field, const typename field_type::type_iterator & t_it,
       const typename field_type::type_iterator & t_it_end,
       const array_iterator & array_it, const array_iterator & array_it_end,
       const GhostType ghost_type = _not_ghost)
       : parent(field, t_it, t_it_end, array_it, array_it_end, ghost_type) {}
 
   /* ------------------------------------------------------------------------ */
   /* Methods                                                                  */
   /* ------------------------------------------------------------------------ */
 public:
   return_type operator*() {
     const Vector<UInt> & old_connect = *this->array_it;
     Vector<UInt> new_connect(old_connect.size());
     Array<UInt>::const_iterator<UInt> nodes_begin = nodal_filter->begin();
     Array<UInt>::const_iterator<UInt> nodes_end = nodal_filter->end();
     for (UInt i(0); i < old_connect.size(); ++i) {
       Array<UInt>::const_iterator<UInt> new_id =
           std::find(nodes_begin, nodes_end, old_connect(i));
       if (new_id == nodes_end)
         AKANTU_EXCEPTION("Node not found in the filter!");
       new_connect(i) = new_id - nodes_begin;
     }
     return new_connect;
   }
 
   void setNodalFilter(const Array<UInt> & new_nodal_filter) {
     nodal_filter = &new_nodal_filter;
   }
 
   /* ------------------------------------------------------------------------ */
   /* Class Members                                                            */
   /* ------------------------------------------------------------------------ */
 private:
   const Array<UInt> * nodal_filter;
 };
 
 /* -------------------------------------------------------------------------- */
 
 class FilteredConnectivityField
     : public GenericElementalField<SingleType<UInt, Vector, true>,
                                    filtered_connectivity_field_iterator> {
   /* ------------------------------------------------------------------------ */
   /* Typedefs                                                                 */
   /* ------------------------------------------------------------------------ */
 public:
   typedef SingleType<UInt, Vector, true> types;
   using iterator = filtered_connectivity_field_iterator<types>;
   using field_type = types::field_type;
   typedef GenericElementalField<types, filtered_connectivity_field_iterator>
       parent;
 
   /* ------------------------------------------------------------------------ */
   /* Constructors/Destructors                                                 */
   /* ------------------------------------------------------------------------ */
 public:
   FilteredConnectivityField(const field_type & field,
                             const Array<UInt> & nodal_filter,
                             UInt spatial_dimension = _all_dimensions,
                             GhostType ghost_type = _not_ghost,
                             ElementKind element_kind = _ek_not_defined)
       : parent(field, spatial_dimension, ghost_type, element_kind),
         nodal_filter(nodal_filter) {}
 
   ~FilteredConnectivityField() override {
     // since the field is created in registerFilteredMesh it is destroyed here
     delete const_cast<field_type *>(&this->field);
   }
 
   /* ------------------------------------------------------------------------ */
   /* Methods                                                                  */
   /* ------------------------------------------------------------------------ */
 public:
   iterator begin() override {
     iterator it = parent::begin();
     it.setNodalFilter(nodal_filter);
     return it;
   }
 
   iterator end() override {
     iterator it = parent::end();
     it.setNodalFilter(nodal_filter);
     return it;
   }
 
   /* ------------------------------------------------------------------------ */
   /* Class Members                                                            */
   /* ------------------------------------------------------------------------ */
 private:
   const Array<UInt> & nodal_filter;
 };
 
 /* -------------------------------------------------------------------------- */
 
 __END_AKANTU_DUMPER__
 } // akantu
 
 /* -------------------------------------------------------------------------- */
diff --git a/src/io/dumper/dumper_generic_elemental_field.hh b/src/io/dumper/dumper_generic_elemental_field.hh
index bf532fb86..f616aa8b7 100644
--- a/src/io/dumper/dumper_generic_elemental_field.hh
+++ b/src/io/dumper/dumper_generic_elemental_field.hh
@@ -1,225 +1,225 @@
 /**
  * @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: Tue Jan 19 2016
+ * @date last modification: Wed Nov 08 2017
  *
  * @brief  Generic interface for elemental fields
  *
  * @section LICENSE
  *
- * Copyright  (©)  2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de Lausanne)
+ * 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
+ * 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
+ * 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 {
 __BEGIN_AKANTU_DUMPER__
 /* -------------------------------------------------------------------------- */
 
 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>;
 
   /* ------------------------------------------------------------------------ */
   /* 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(const ElementType & type,
                         const 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 Field * connect(FieldComputeProxy & proxy) override {
     return proxy.connectToField(this);
   }
 
   /// for connection to a Homogenizer
   inline ComputeFunctorInterface * connect(HomogenizerProxy & proxy) override {
     return proxy.connectToField(this);
   };
 
   virtual iterator begin() {
     field_type_iterator tit;
     field_type_iterator end;
 
     /// type iterators on the elemental field
     tit = this->field.firstType(this->spatial_dimension, this->ghost_type,
                                 this->element_kind);
     end = this->field.lastType(this->spatial_dimension, this->ghost_type,
                                this->element_kind);
 
     /// skip all types without data
     ElementType type = *tit;
     for (; tit != end && this->field(*tit, this->ghost_type).size() == 0;
          ++tit) {
     }
 
     type = *tit;
 
     if (tit == end)
       return this->end();
 
     /// getting information for the field of the given type
     const array_type & vect = this->field(type, this->ghost_type);
     UInt nb_data_per_elem = this->getNbDataPerElem(type);
     UInt nb_component = vect.getNbComponent();
     UInt size = (vect.size() * nb_component) / nb_data_per_elem;
 
     /// define element-wise iterator
     array_iterator it = vect.begin_reinterpret(nb_data_per_elem, size);
     array_iterator it_end = vect.end_reinterpret(nb_data_per_elem, size);
     /// 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() {
     field_type_iterator tit;
     field_type_iterator end;
 
     tit = this->field.firstType(this->spatial_dimension, this->ghost_type,
                                 this->element_kind);
     end = this->field.lastType(this->spatial_dimension, this->ghost_type,
                                this->element_kind);
 
     ElementType type = *tit;
     for (; tit != end; ++tit)
       type = *tit;
 
     const array_type & vect = this->field(type, this->ghost_type);
     UInt nb_data = this->getNbDataPerElem(type);
     UInt nb_component = vect.getNbComponent();
     UInt size = (vect.size() * nb_component) / nb_data;
     array_iterator it = vect.end_reinterpret(nb_data, size);
 
     iterator 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) {
       field_type_iterator tit = this->field.firstType(
           this->spatial_dimension, this->ghost_type, this->element_kind);
       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;
 };
 
 /* -------------------------------------------------------------------------- */
 #include "dumper_generic_elemental_field_tmpl.hh"
 /* -------------------------------------------------------------------------- */
 
 __END_AKANTU_DUMPER__
 } // akantu
 
 #endif /* __AKANTU_DUMPER_GENERIC_ELEMENTAL_FIELD_HH__ */
diff --git a/src/io/dumper/dumper_generic_elemental_field_tmpl.hh b/src/io/dumper/dumper_generic_elemental_field_tmpl.hh
index 80b6a524a..f22b9be0f 100644
--- a/src/io/dumper/dumper_generic_elemental_field_tmpl.hh
+++ b/src/io/dumper/dumper_generic_elemental_field_tmpl.hh
@@ -1,69 +1,69 @@
 /**
  * @file   dumper_generic_elemental_field_tmpl.hh
  *
  * @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Tue Sep 02 2014
- * @date last modification: Sun Oct 19 2014
+ * @date last modification: Wed Nov 08 2017
  *
  * @brief  Implementation of the template functions of the ElementalField
  *
  * @section LICENSE
  *
- * Copyright  (©)  2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de Lausanne)
+ * 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
+ * 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
+ * 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/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 
 template <class types, template <class> class iterator>
 void GenericElementalField<types, iterator>::checkHomogeneity() {
   using field_type_iterator = typename field_type::type_iterator;
   using array_type = typename field_type::array_type;
 
   field_type_iterator tit;
   field_type_iterator end;
 
   tit = field.firstType(spatial_dimension, ghost_type, element_kind);
   end = field.lastType(spatial_dimension, ghost_type, element_kind);
 
   this->nb_total_element = 0;
   UInt nb_comp = 0;
 
   bool homogen = true;
   if (tit != end) {
     nb_comp = this->field(*tit, ghost_type).getNbComponent();
     for (; tit != end; ++tit) {
       const array_type & vect = this->field(*tit, ghost_type);
       UInt nb_element = vect.size();
       UInt nb_comp_cur = vect.getNbComponent();
       if (homogen && nb_comp != nb_comp_cur)
         homogen = false;
       this->nb_total_element += nb_element;
 
       //      this->nb_data_per_elem(*tit,this->ghost_type) = nb_comp_cur;
     }
 
     if (!homogen)
       nb_comp = 0;
   }
 
   this->homogeneous = homogen;
 }
 
 /* -------------------------------------------------------------------------- */
diff --git a/src/io/dumper/dumper_homogenizing_field.hh b/src/io/dumper/dumper_homogenizing_field.hh
index ba39b1986..c95bf75bb 100644
--- a/src/io/dumper/dumper_homogenizing_field.hh
+++ b/src/io/dumper/dumper_homogenizing_field.hh
@@ -1,216 +1,216 @@
 /**
  * @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: Tue Jul 14 2015
+ * @date last modification: Wed Nov 08 2017
  *
  * @brief  description of field homogenizing field
  *
  * @section LICENSE
  *
- * Copyright  (©)  2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de Lausanne)
+ * 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
+ * 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
+ * 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 {
 __BEGIN_AKANTU_DUMPER__
 
 /* -------------------------------------------------------------------------- */
 
 template <typename type>
 inline type typeConverter(const type & input,
                           __attribute__((unused))
                           Vector<typename type::value_type> & res,
                           __attribute__((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 Vector<type> typeConverter(__attribute__((unused))
                                   const Vector<type> & input,
                                   __attribute__((unused)) Vector<type> & res,
                                   __attribute__((unused)) UInt nb_data) {
 
   return res;
 }
 
 /* -------------------------------------------------------------------------- */
 
 template <typename type>
 class AvgHomogenizingFunctor : public ComputeFunctor<type, type> {
 
   /* ------------------------------------------------------------------------ */
   /* Typedefs                                                                 */
   /* ------------------------------------------------------------------------ */
 
   using value_type = typename type::value_type;
 
   /* ------------------------------------------------------------------------ */
   /* Constructors/Destructors                                                 */
   /* ------------------------------------------------------------------------ */
 
 public:
   AvgHomogenizingFunctor(ElementTypeMap<UInt> & nb_datas) {
 
     ElementTypeMap<UInt>::type_iterator tit = nb_datas.firstType();
     ElementTypeMap<UInt>::type_iterator end = nb_datas.lastType();
 
     nb_data = nb_datas(*tit);
 
     for (; tit != end; ++tit)
       if (nb_data != nb_datas(*tit))
         throw;
   }
 
   /* ------------------------------------------------------------------------ */
   /* Methods                                                                  */
   /* ------------------------------------------------------------------------ */
 
   type func(const type & d, Element /*global_index*/) override {
     Vector<value_type> res(this->nb_data);
 
     if (d.size() % this->nb_data)
       throw;
     UInt nb_to_average = d.size() / this->nb_data;
 
     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);
   };
 
   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 ComputeFunctorInterface * createHomogenizer(Field & field);
 
   template <typename T>
   inline 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 ret_type>
   inline ComputeFunctorInterface *
   instantiateHomogenizer(ElementTypeMap<UInt> & nb_components);
 };
 
 /* -------------------------------------------------------------------------- */
 
 template <typename ret_type>
 inline ComputeFunctorInterface *
 HomogenizerProxy::instantiateHomogenizer(ElementTypeMap<UInt> & nb_components) {
 
   using Homogenizer = dumper::AvgHomogenizingFunctor<ret_type>;
   auto * foo = new Homogenizer(nb_components);
   return foo;
 }
 
 template <>
 inline ComputeFunctorInterface *
 HomogenizerProxy::instantiateHomogenizer<Vector<iohelper::ElemType>>(
     __attribute__((unused)) ElementTypeMap<UInt> & nb_components) {
   throw;
   return nullptr;
 }
 
 /* -------------------------------------------------------------------------- */
 
 /// for connection to a FieldCompute
 template <typename SubFieldCompute, typename return_type>
 inline ComputeFunctorInterface *
 FieldCompute<SubFieldCompute, return_type>::connect(HomogenizerProxy & proxy) {
 
   return proxy.connectToField(this);
 }
 /* -------------------------------------------------------------------------- */
 
 inline ComputeFunctorInterface *
 HomogenizerProxy::createHomogenizer(Field & field) {
 
   HomogenizerProxy homogenizer_proxy;
   return field.connect(homogenizer_proxy);
 }
 
 /* -------------------------------------------------------------------------- */
 
 // inline ComputeFunctorInterface & createHomogenizer(Field & field){
 
 //   HomogenizerProxy::createHomogenizer(field);
 //   throw;
 //   ComputeFunctorInterface * ptr = NULL;
 //   return *ptr;
 // }
 
 // /* --------------------------------------------------------------------------
 // */
 
 __END_AKANTU_DUMPER__
 } // 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 26924dda3..c9410ace0 100644
--- a/src/io/dumper/dumper_internal_material_field.hh
+++ b/src/io/dumper/dumper_internal_material_field.hh
@@ -1,73 +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: Thu Sep 17 2015
+ * @date last modification: Wed Nov 08 2017
  *
  * @brief  description of material internal field
  *
  * @section LICENSE
  *
- * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
- * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
- * Solides)
+ * 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
+ * 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
+ * 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 {
 __BEGIN_AKANTU_DUMPER__
 /* -------------------------------------------------------------------------- */
 
 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;
 
   /* ------------------------------------------------------------------------ */
   /* 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) {}
 };
 
 __END_AKANTU_DUMPER__
 } // akantu
 
 #endif /* __AKANTU_DUMPER_INTERNAL_MATERIAL_FIELD_HH__ */
diff --git a/src/io/dumper/dumper_iohelper.cc b/src/io/dumper/dumper_iohelper.cc
index ce23d1089..d4c9443c0 100644
--- a/src/io/dumper/dumper_iohelper.cc
+++ b/src/io/dumper/dumper_iohelper.cc
@@ -1,318 +1,317 @@
 /**
  * @file   dumper_iohelper.cc
  *
  * @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
  * @author Dana Christen <dana.christen@epfl.ch>
  * @author David Simon Kammer <david.kammer@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Fri Oct 26 2012
- * @date last modification: Thu Sep 17 2015
+ * @date last modification: Tue Feb 20 2018
  *
  * @brief  implementation of DumperIOHelper
  *
  * @section LICENSE
  *
- * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
- * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
- * Solides)
+ * 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
+ * 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
+ * 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 <io_helper.hh>
 
 #include "dumper_elemental_field.hh"
 #include "dumper_filtered_connectivity.hh"
 #include "dumper_iohelper.hh"
 #include "dumper_nodal_field.hh"
 #include "dumper_variable.hh"
 #include "mesh.hh"
 #if defined(AKANTU_IGFEM)
 #include "dumper_igfem_connectivity.hh"
 #endif
 /* -------------------------------------------------------------------------- */
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 DumperIOHelper::DumperIOHelper() = default;
 
 /* -------------------------------------------------------------------------- */
 DumperIOHelper::~DumperIOHelper() {
   for (auto it = fields.begin(); it != fields.end(); ++it) {
     delete it->second;
   }
 
   delete dumper;
 }
 
 /* -------------------------------------------------------------------------- */
 void DumperIOHelper::setParallelContext(bool is_parallel) {
   UInt whoami = Communicator::getStaticCommunicator().whoAmI();
   UInt nb_proc = Communicator::getStaticCommunicator().getNbProc();
 
   if (is_parallel)
     dumper->setParallelContext(whoami, nb_proc);
   else
     dumper->setParallelContext(0, 1);
 }
 
 /* -------------------------------------------------------------------------- */
 void DumperIOHelper::setDirectory(const std::string & directory) {
   this->directory = directory;
   dumper->setPrefix(directory);
 }
 
 /* -------------------------------------------------------------------------- */
 void DumperIOHelper::setBaseName(const std::string & basename) {
   filename = basename;
 }
 
 /* -------------------------------------------------------------------------- */
 void DumperIOHelper::setTimeStep(Real time_step) {
   if (!time_activated)
     this->dumper->activateTimeDescFiles(time_step);
   else
     this->dumper->setTimeStep(time_step);
 }
 
 /* -------------------------------------------------------------------------- */
 void DumperIOHelper::dump() {
   try {
     dumper->dump(filename, count);
   } catch (iohelper::IOHelperException & e) {
     AKANTU_ERROR(
         "I was not able to dump your data with a Dumper: " << e.what());
   }
 
   ++count;
 }
 
 /* -------------------------------------------------------------------------- */
 void DumperIOHelper::dump(UInt step) {
   this->count = step;
   this->dump();
 }
 
 /* -------------------------------------------------------------------------- */
 void DumperIOHelper::dump(Real current_time, UInt step) {
   this->dumper->setCurrentTime(current_time);
   this->dump(step);
 }
 
 /* -------------------------------------------------------------------------- */
 void DumperIOHelper::registerMesh(const Mesh & mesh, UInt spatial_dimension,
                                   const GhostType & ghost_type,
                                   const ElementKind & element_kind) {
 
 #if defined(AKANTU_IGFEM)
   if (element_kind == _ek_igfem) {
     registerField("connectivities",
                   new dumper::IGFEMConnectivityField(
                       mesh.getConnectivities(), spatial_dimension, ghost_type));
   } else
 #endif
 
     registerField("connectivities",
                   new dumper::ElementalField<UInt>(mesh.getConnectivities(),
                                                    spatial_dimension,
                                                    ghost_type, element_kind));
 
   registerField("positions", new dumper::NodalField<Real>(mesh.getNodes()));
 }
 
 /* -------------------------------------------------------------------------- */
 void DumperIOHelper::registerFilteredMesh(
     const Mesh & mesh, const ElementTypeMapArray<UInt> & elements_filter,
     const Array<UInt> & nodes_filter, UInt spatial_dimension,
     const GhostType & ghost_type, const ElementKind & element_kind) {
   auto * f_connectivities = new ElementTypeMapArrayFilter<UInt>(
       mesh.getConnectivities(), elements_filter);
 
   this->registerField("connectivities",
                       new dumper::FilteredConnectivityField(
                           *f_connectivities, nodes_filter, spatial_dimension,
                           ghost_type, element_kind));
 
   this->registerField("positions", new dumper::NodalField<Real, true>(
                                        mesh.getNodes(), 0, 0, &nodes_filter));
 }
 
 /* -------------------------------------------------------------------------- */
 void DumperIOHelper::registerField(const std::string & field_id,
                                    dumper::Field * field) {
   auto it = fields.find(field_id);
   if (it != fields.end()) {
     AKANTU_DEBUG_WARNING(
         "The field "
         << field_id << " is already registered in this Dumper. Field ignored.");
     return;
   }
 
   fields[field_id] = field;
   field->registerToDumper(field_id, *dumper);
 }
 
 /* -------------------------------------------------------------------------- */
 void DumperIOHelper::unRegisterField(const std::string & field_id) {
   auto it = fields.find(field_id);
   if (it == fields.end()) {
     AKANTU_DEBUG_WARNING(
         "The field " << field_id
                      << " is not registered in this Dumper. Nothing to do.");
     return;
   }
 
   delete it->second;
   fields.erase(it);
 }
 
 /* -------------------------------------------------------------------------- */
 void DumperIOHelper::registerVariable(const std::string & variable_id,
                                       dumper::VariableBase * variable) {
   auto it = variables.find(variable_id);
 
   if (it != variables.end()) {
     AKANTU_DEBUG_WARNING(
         "The Variable "
         << variable_id
         << " is already registered in this Dumper. Variable ignored.");
     return;
   }
 
   variables[variable_id] = variable;
   variable->registerToDumper(variable_id, *dumper);
 }
 
 /* -------------------------------------------------------------------------- */
 void DumperIOHelper::unRegisterVariable(const std::string & variable_id) {
   auto it = variables.find(variable_id);
 
   if (it == variables.end()) {
     AKANTU_DEBUG_WARNING(
         "The variable " << variable_id
                         << " is not registered in this Dumper. Nothing to do.");
     return;
   }
 
   delete it->second;
   variables.erase(it);
 }
 
 /* -------------------------------------------------------------------------- */
 template <ElementType type> iohelper::ElemType getIOHelperType() {
   AKANTU_TO_IMPLEMENT();
   return iohelper::MAX_ELEM_TYPE;
 }
 
 template <> iohelper::ElemType getIOHelperType<_point_1>() {
   return iohelper::POINT_SET;
 }
 template <> iohelper::ElemType getIOHelperType<_segment_2>() {
   return iohelper::LINE1;
 }
 template <> iohelper::ElemType getIOHelperType<_segment_3>() {
   return iohelper::LINE2;
 }
 
 template <> iohelper::ElemType getIOHelperType<_triangle_3>() {
   return iohelper::TRIANGLE1;
 }
 template <> iohelper::ElemType getIOHelperType<_triangle_6>() {
   return iohelper::TRIANGLE2;
 }
 
 template <> iohelper::ElemType getIOHelperType<_quadrangle_4>() {
   return iohelper::QUAD1;
 }
 template <> iohelper::ElemType getIOHelperType<_quadrangle_8>() {
   return iohelper::QUAD2;
 }
 
 template <> iohelper::ElemType getIOHelperType<_tetrahedron_4>() {
   return iohelper::TETRA1;
 }
 template <> iohelper::ElemType getIOHelperType<_tetrahedron_10>() {
   return iohelper::TETRA2;
 }
 
 template <> iohelper::ElemType getIOHelperType<_hexahedron_8>() {
   return iohelper::HEX1;
 }
 template <> iohelper::ElemType getIOHelperType<_hexahedron_20>() {
   return iohelper::HEX2;
 }
 
 template <> iohelper::ElemType getIOHelperType<_pentahedron_6>() {
   return iohelper::PRISM1;
 }
 template <> iohelper::ElemType getIOHelperType<_pentahedron_15>() {
   return iohelper::PRISM2;
 }
 
 #if defined(AKANTU_COHESIVE_ELEMENT)
 template <> iohelper::ElemType getIOHelperType<_cohesive_1d_2>() {
   return iohelper::COH1D2;
 }
 
 template <> iohelper::ElemType getIOHelperType<_cohesive_2d_4>() {
   return iohelper::COH2D4;
 }
 template <> iohelper::ElemType getIOHelperType<_cohesive_2d_6>() {
   return iohelper::COH2D6;
 }
 
 template <> iohelper::ElemType getIOHelperType<_cohesive_3d_6>() {
   return iohelper::COH3D6;
 }
 template <> iohelper::ElemType getIOHelperType<_cohesive_3d_12>() {
   return iohelper::COH3D12;
 }
 
 template <> iohelper::ElemType getIOHelperType<_cohesive_3d_8>() {
   return iohelper::COH3D8;
 }
 // template <>
 // iohelper::ElemType getIOHelperType<_cohesive_3d_16>() { return
 // iohelper::COH3D16; }
 #endif
 
 #if defined(AKANTU_STRUCTURAL_MECHANICS)
 template <> iohelper::ElemType getIOHelperType<_bernoulli_beam_2>() {
   return iohelper::BEAM2;
 }
 template <> iohelper::ElemType getIOHelperType<_bernoulli_beam_3>() {
   return iohelper::BEAM3;
 }
 #endif
 
 /* -------------------------------------------------------------------------- */
 UInt getIOHelperType(ElementType type) {
   UInt ioh_type = iohelper::MAX_ELEM_TYPE;
 #define GET_IOHELPER_TYPE(type) ioh_type = getIOHelperType<type>();
 
   AKANTU_BOOST_ALL_ELEMENT_SWITCH(GET_IOHELPER_TYPE);
 #undef GET_IOHELPER_TYPE
   return ioh_type;
 }
 
 /* -------------------------------------------------------------------------- */
 
 } // akantu
 
 namespace iohelper {
 template <> DataType getDataType<akantu::NodeType>() { return _int; }
 }
diff --git a/src/io/dumper/dumper_iohelper.hh b/src/io/dumper/dumper_iohelper.hh
index 862e79e98..f824215bd 100644
--- a/src/io/dumper/dumper_iohelper.hh
+++ b/src/io/dumper/dumper_iohelper.hh
@@ -1,159 +1,158 @@
 /**
  * @file   dumper_iohelper.hh
  *
  * @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
  * @author Dana Christen <dana.christen@epfl.ch>
  * @author David Simon Kammer <david.kammer@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Fri Oct 26 2012
- * @date last modification: Tue Jan 19 2016
+ * @date last modification: Sun Dec 03 2017
  *
  * @brief  Define the akantu dumper interface for IOhelper dumpers
  *
  * @section LICENSE
  *
- * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
- * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
- * Solides)
+ * 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
+ * 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
+ * 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_array.hh"
 #include "aka_common.hh"
 #include "aka_types.hh"
 #include "element_type_map.hh"
 
 /* -------------------------------------------------------------------------- */
 
 #ifndef __AKANTU_DUMPER_IOHELPER_HH__
 #define __AKANTU_DUMPER_IOHELPER_HH__
 /* -------------------------------------------------------------------------- */
 
 namespace iohelper {
 class Dumper;
 }
 
 namespace akantu {
 
 UInt getIOHelperType(ElementType type);
 
 namespace dumper {
   class Field;
   class VariableBase;
 }
 
 class Mesh;
 
 class DumperIOHelper {
   /* ------------------------------------------------------------------------ */
   /* Constructors/Destructors                                                 */
   /* ------------------------------------------------------------------------ */
 public:
   DumperIOHelper();
   virtual ~DumperIOHelper();
 
   /* ------------------------------------------------------------------------ */
   /* Methods                                                                  */
   /* ------------------------------------------------------------------------ */
 public:
   /// register a given Mesh for the current dumper
   virtual void registerMesh(const Mesh & mesh,
                             UInt spatial_dimension = _all_dimensions,
                             const GhostType & ghost_type = _not_ghost,
                             const ElementKind & element_kind = _ek_not_defined);
 
   /// register a filtered Mesh (provided filter lists) for the current dumper
   virtual void
   registerFilteredMesh(const Mesh & mesh,
                        const ElementTypeMapArray<UInt> & elements_filter,
                        const Array<UInt> & nodes_filter,
                        UInt spatial_dimension = _all_dimensions,
                        const GhostType & ghost_type = _not_ghost,
                        const ElementKind & element_kind = _ek_not_defined);
 
   /// register a Field object identified by name and provided by pointer
   void registerField(const std::string & field_id, dumper::Field * field);
   /// remove the Field identified by name from managed fields
   void unRegisterField(const std::string & field_id);
   /// register a VariableBase object identified by name and provided by pointer
   void registerVariable(const std::string & variable_id,
                         dumper::VariableBase * variable);
   /// remove a VariableBase identified by name from managed fields
   void unRegisterVariable(const std::string & variable_id);
 
   /// request dump: this calls IOHelper dump routine
   virtual void dump();
   /// request dump: this first set the current step and then calls IOHelper dump
   /// routine
   virtual void dump(UInt step);
   /// request dump: this first set the current step and current time and then
   /// calls IOHelper dump routine
   virtual void dump(Real current_time, UInt step);
   /// set the parallel context for IOHeper
   virtual void setParallelContext(bool is_parallel);
   /// set the directory where to generate the dumped files
   virtual void setDirectory(const std::string & directory);
   /// set the base name (needed by most IOHelper dumpers)
   virtual void setBaseName(const std::string & basename);
 
   /* ------------------------------------------------------------------------ */
   /* Accessors                                                                */
   /* ------------------------------------------------------------------------ */
 public:
   /// direct access to the iohelper::Dumper object
   AKANTU_GET_MACRO(Dumper, *dumper, iohelper::Dumper &)
 
   /// set the timestep of the iohelper::Dumper
   void setTimeStep(Real time_step);
 
 public:
   /* ------------------------------------------------------------------------ */
   /* Variable wrapper */
   template <typename T, bool is_scal = std::is_arithmetic<T>::value>
   class Variable;
 
   /* ------------------------------------------------------------------------ */
   /* Class Members                                                            */
   /* ------------------------------------------------------------------------ */
 protected:
   /// internal iohelper::Dumper
   iohelper::Dumper * dumper;
 
   using Fields = std::map<std::string, dumper::Field *>;
   using Variables = std::map<std::string, dumper::VariableBase *>;
 
   /// list of registered fields to dump
   Fields fields;
   Variables variables;
 
   /// dump counter
   UInt count{0};
 
   /// directory name
   std::string directory;
 
   /// filename prefix
   std::string filename;
 
   /// is time tracking activated in the dumper
   bool time_activated{false};
 };
 
 } // akantu
 
 #endif /* __AKANTU_DUMPER_IOHELPER_HH__ */
diff --git a/src/io/dumper/dumper_iohelper_paraview.cc b/src/io/dumper/dumper_iohelper_paraview.cc
index 4527586fa..fb8531321 100644
--- a/src/io/dumper/dumper_iohelper_paraview.cc
+++ b/src/io/dumper/dumper_iohelper_paraview.cc
@@ -1,67 +1,66 @@
 /**
- * @file   dumper_paraview.cc
+ * @file   dumper_iohelper_paraview.cc
  *
  * @author David Simon Kammer <david.kammer@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Sun Sep 26 2010
- * @date last modification: Sun Oct 19 2014
+ * @date last modification: Mon Jan 22 2018
  *
  * @brief  implementations of DumperParaview
  *
  * @section LICENSE
  *
- * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
- * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
- * Solides)
+ * 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
+ * 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
+ * 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 "dumper_iohelper_paraview.hh"
 #include "communicator.hh"
 /* -------------------------------------------------------------------------- */
 #include <fstream>
 #include <io_helper.hh>
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 
 DumperParaview::DumperParaview(const std::string & filename,
                                const std::string & directory, bool parallel)
     : DumperIOHelper() {
   iohelper::DumperParaview * dumper_para = new iohelper::DumperParaview();
   dumper = dumper_para;
   setBaseName(filename);
 
   this->setParallelContext(parallel);
 
   dumper_para->setMode(iohelper::BASE64);
   dumper_para->setPrefix(directory);
   dumper_para->init();
 }
 
 /* -------------------------------------------------------------------------- */
 DumperParaview::~DumperParaview() = default;
 
 /* -------------------------------------------------------------------------- */
 void DumperParaview::setBaseName(const std::string & basename) {
   DumperIOHelper::setBaseName(basename);
   static_cast<iohelper::DumperParaview *>(dumper)->setVTUSubDirectory(filename +
                                                                       "-VTU");
 }
 
 } // namespace akantu
diff --git a/src/io/dumper/dumper_iohelper_paraview.hh b/src/io/dumper/dumper_iohelper_paraview.hh
index eac1bf120..312045070 100644
--- a/src/io/dumper/dumper_iohelper_paraview.hh
+++ b/src/io/dumper/dumper_iohelper_paraview.hh
@@ -1,72 +1,71 @@
 /**
- * @file   dumper_paraview.hh
+ * @file   dumper_iohelper_paraview.hh
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Fri Jun 18 2010
- * @date last modification: Sun Oct 19 2014
+ * @date last modification: Mon Jan 22 2018
  *
  * @brief  Dumper Paraview using IOHelper
  *
  * @section LICENSE
  *
- * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
- * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
- * Solides)
+ * 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
+ * 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
+ * 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_PARAVIEW_HH__
 #define __AKANTU_DUMPER_PARAVIEW_HH__
 
 #include "dumper_iohelper.hh"
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 
 class DumperParaview : public DumperIOHelper {
   /* ------------------------------------------------------------------------ */
   /* Constructors/Destructors                                                 */
   /* ------------------------------------------------------------------------ */
 public:
   DumperParaview(const std::string & filename,
                  const std::string & directory = "./paraview",
                  bool parallel = true);
   ~DumperParaview() override;
 
   /* ------------------------------------------------------------------------ */
   /* Methods                                                                  */
   /* ------------------------------------------------------------------------ */
 public:
   // void dump();
 
   /* ------------------------------------------------------------------------ */
   /* Accessors                                                                */
   /* ------------------------------------------------------------------------ */
 public:
   void setBaseName(const std::string & basename) override;
 
   /* ------------------------------------------------------------------------ */
   /* Class Members                                                            */
   /* ------------------------------------------------------------------------ */
 private:
 };
 
 } // akantu
 
 #endif /* __AKANTU_DUMPER_PARAVIEW_HH__ */
diff --git a/src/io/dumper/dumper_material_padders.hh b/src/io/dumper/dumper_material_padders.hh
index df66fb2cf..5c5501f53 100644
--- a/src/io/dumper/dumper_material_padders.hh
+++ b/src/io/dumper/dumper_material_padders.hh
@@ -1,289 +1,289 @@
 /**
  * @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: Fri Mar 27 2015
+ * @date last modification: Wed Nov 29 2017
  *
  * @brief  Material padders for plane stress/ plane strain
  *
  * @section LICENSE
  *
- * Copyright  (©)  2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de Lausanne)
+ * 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
+ * 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
+ * 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 {
 __BEGIN_AKANTU_DUMPER__
 /* -------------------------------------------------------------------------- */
 class MaterialFunctor {
   /* ------------------------------------------------------------------------ */
   /* Constructors/Destructors                                                 */
   /* ------------------------------------------------------------------------ */
 public:
   MaterialFunctor(const SolidMechanicsModel & model)
       : model(model), material_index(model.getMaterialByElement()),
         nb_data_per_element("nb_data_per_element", model.getID(),
                             model.getMemoryID()),
         spatial_dimension(model.getSpatialDimension()) {}
 
   /* ------------------------------------------------------------------------ */
   /* 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(Element global_index) {
     return global_index.type;
   }
 
 protected:
   /* ------------------------------------------------------------------------ */
   /* 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::gradUToGreenStrain<2>(grad_u, strain);
         else
           Material::gradUToEpsilon<2>(grad_u, strain);
       } else if (spatial_dimension == 3) {
         if (green_strain)
           Material::gradUToGreenStrain<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::gradUToGreenStrain<2>(grad_u, strain);
         else
           Material::gradUToEpsilon<2>(grad_u, strain);
       } else if (spatial_dimension == 3) {
         if (green_strain)
           Material::gradUToGreenStrain<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(); };
 };
 
 /* -------------------------------------------------------------------------- */
 
 __END_AKANTU_DUMPER__
 } // 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 bda109fb0..1b3430204 100644
--- a/src/io/dumper/dumper_nodal_field.hh
+++ b/src/io/dumper/dumper_nodal_field.hh
@@ -1,249 +1,248 @@
 /**
  * @file   dumper_nodal_field.hh
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Fri Oct 26 2012
- * @date last modification: Tue Jan 06 2015
+ * @date last modification: Wed Nov 08 2017
  *
  * @brief  Description of nodal fields
  *
  * @section LICENSE
  *
- * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
- * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
- * Solides)
+ * 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
+ * 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
+ * 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 {
 __BEGIN_AKANTU_DUMPER__
 
 // 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 dumper::Field {
 public:
   /* ------------------------------------------------------------------------ */
   /* Typedefs                                                                 */
   /* ------------------------------------------------------------------------ */
 
   /// 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;
   };
 
   /* ------------------------------------------------------------------------ */
   /* Constructors/Destructors                                                 */
   /* ------------------------------------------------------------------------ */
 
   NodalField(const Container & field, UInt n = 0, UInt stride = 0,
              __attribute__((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;
     }
   }
 
   /* ------------------------------------------------------------------------ */
   /* 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;
     else
       return n;
   }
 
   void setPadding(UInt padding) { this->padding = padding; }
 
   UInt size() { return field.size(); }
 
   iohelper::DataType getDataType() { return iohelper::getDataType<T>(); }
 
   /* ------------------------------------------------------------------------ */
   /* Class Members                                                            */
   /* ------------------------------------------------------------------------ */
 
 private:
   const Container & field;
   UInt n, stride;
   UInt padding;
 };
 
 /* -------------------------------------------------------------------------- */
 template <typename T, class Container, class Filter>
 class NodalField<T, true, Container, Filter> : public dumper::Field {
 
   /* ------------------------------------------------------------------------ */
   /* Typedefs                                                                 */
   /* ------------------------------------------------------------------------ */
 
 public:
   class iterator : public iohelper::iterator<T, iterator, Vector<T>> {
 
   public:
     iterator(T * const vect, UInt _offset, UInt _n, UInt _stride,
              const UInt * filter)
         :
 
           internal_it(vect),
           offset(_offset), n(_n), stride(_stride), filter(filter) {}
 
     bool operator!=(const iterator & it) const override {
       return filter != it.filter;
     }
 
     iterator & operator++() override {
       ++filter;
       return *this;
     }
 
     Vector<T> operator*() override {
       return Vector<T>(internal_it + *(filter)*offset + stride, n);
     }
 
   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;
     }
   }
 
   /* ------------------------------------------------------------------------ */
   /* 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,
                     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;
     else
       return n;
   }
 
   void setPadding(UInt padding) { this->padding = padding; }
 
   UInt size() { return filter->size(); }
 
   iohelper::DataType getDataType() { return iohelper::getDataType<T>(); }
 
   /* ------------------------------------------------------------------------ */
   /* Class Members                                                            */
   /* ------------------------------------------------------------------------ */
 
 private:
   const Container & field;
   UInt n, stride;
   const Filter * filter;
 
   UInt padding;
 };
 
 __END_AKANTU_DUMPER__
 } // akantu
 /* -------------------------------------------------------------------------- */
 #endif /* __AKANTU_DUMPER_NODAL_FIELD_HH__ */
diff --git a/src/io/dumper/dumper_padding_helper.hh b/src/io/dumper/dumper_padding_helper.hh
index 5a9f75fc4..5875ebe35 100644
--- a/src/io/dumper/dumper_padding_helper.hh
+++ b/src/io/dumper/dumper_padding_helper.hh
@@ -1,132 +1,132 @@
 /**
  * @file   dumper_padding_helper.hh
  *
  * @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Tue Sep 02 2014
- * @date last modification: Sun Oct 19 2014
+ * @date last modification: Mon Jun 19 2017
  *
  * @brief  Padding helper for field iterators
  *
  * @section LICENSE
  *
- * Copyright  (©)  2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de Lausanne)
+ * 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
+ * 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
+ * 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_PADDING_HELPER_HH__
 #define __AKANTU_DUMPER_PADDING_HELPER_HH__
 /* -------------------------------------------------------------------------- */
 #include "dumper_compute.hh"
 /* -------------------------------------------------------------------------- */
 namespace akantu {
 __BEGIN_AKANTU_DUMPER__
 /* -------------------------------------------------------------------------- */
 
 class PadderInterface {
 
   /* ------------------------------------------------------------------------ */
   /* Constructors/Destructors                                                 */
   /* ------------------------------------------------------------------------ */
 
 public:
   PadderInterface() {
     padding_m = 0;
     padding_n = 0;
   }
 
   /* ------------------------------------------------------------------------ */
   /* Methods                                                                  */
   /* ------------------------------------------------------------------------ */
 
 public:
   void setPadding(UInt m, UInt n = 0) {
     padding_m = m;
     padding_n = n;
   }
 
   virtual UInt getPaddedDim(UInt nb_data) { return nb_data; }
 
   /* ------------------------------------------------------------------------ */
   /* Class Members                                                            */
   /* ------------------------------------------------------------------------ */
 
 public:
   /// padding informations
   UInt padding_n, padding_m;
 };
 
 /* -------------------------------------------------------------------------- */
 
 template <class input_type, class output_type>
 class PadderGeneric : public ComputeFunctor<input_type, output_type>,
                       public PadderInterface {
 
   /* ------------------------------------------------------------------------ */
   /* Constructors/Destructors                                                 */
   /* ------------------------------------------------------------------------ */
 
 public:
   PadderGeneric() : PadderInterface() {}
 
   /* ------------------------------------------------------------------------ */
   /* Methods                                                                  */
   /* ------------------------------------------------------------------------ */
 
 public:
   inline output_type pad(const input_type & in,
                          __attribute__((unused)) UInt nb_data) {
     return in; // trick due to the fact that IOHelper padds the vectors (avoid a
                // copy of data)
   }
 };
 /* -------------------------------------------------------------------------- */
 
 template <class T>
 class PadderGeneric<Vector<T>, Matrix<T>>
     : public ComputeFunctor<Vector<T>, Matrix<T>>, public PadderInterface {
 
   /* ------------------------------------------------------------------------ */
   /* Constructors/Destructors                                                 */
   /* ------------------------------------------------------------------------ */
 
 public:
   inline Matrix<T> pad(const Vector<T> & _in, UInt nrows, UInt ncols,
                        UInt nb_data) {
     Matrix<T> in(_in.storage(), nrows, ncols);
 
     if (padding_m <= nrows && padding_n * nb_data <= ncols)
       return in;
     else {
       Matrix<T> ret(padding_m, padding_n * nb_data);
       UInt nb_cols_per_data = in.cols() / nb_data;
       for (UInt d = 0; d < nb_data; ++d)
         for (UInt i = 0; i < in.rows(); ++i)
           for (UInt j = 0; j < nb_cols_per_data; ++j)
             ret(i, j + d * padding_n) = in(i, j + d * nb_cols_per_data);
       return ret;
     }
   }
 };
 
 /* -------------------------------------------------------------------------- */
 
 } // akantu
 __END_AKANTU_DUMPER__
 
 #endif /* __AKANTU_DUMPER_PADDING_HELPER_HH__ */
diff --git a/src/io/dumper/dumper_quadrature_point_iterator.hh b/src/io/dumper/dumper_quadrature_point_iterator.hh
index 52156376f..dc970f2e2 100644
--- a/src/io/dumper/dumper_quadrature_point_iterator.hh
+++ b/src/io/dumper/dumper_quadrature_point_iterator.hh
@@ -1,74 +1,74 @@
 /**
  * @file   dumper_quadrature_point_iterator.hh
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
- * @date creation: Tue Sep 02 2014
- * @date last modification: Thu Sep 17 2015
+ * @date creation: Fri Jun 18 2010
+ * @date last modification: Wed Nov 08 2017
  *
  * @brief  Description of quadrature point iterator
  *
  * @section LICENSE
  *
- * Copyright  (©)  2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de Lausanne)
+ * 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
+ * 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
+ * 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_QUADRATURE_POINT_ITERATOR_HH__
 #define __AKANTU_DUMPER_QUADRATURE_POINT_ITERATOR_HH__
 
 /* -------------------------------------------------------------------------- */
 #include "dumper_elemental_field.hh"
 
 namespace akantu {
 __BEGIN_AKANTU_DUMPER__
 
 /* -------------------------------------------------------------------------- */
 template <typename types>
 class quadrature_point_iterator
     : public element_iterator<types, quadrature_point_iterator> {
   /* ------------------------------------------------------------------------ */
   /* Typedefs                                                                 */
   /* ------------------------------------------------------------------------ */
 public:
   using parent = element_iterator<types, dumper::quadrature_point_iterator>;
   using data_type = typename types::data_type;
   using return_type = typename types::return_type;
   using field_type = typename types::field_type;
   using array_iterator = typename types::array_iterator;
 
   /* ------------------------------------------------------------------------ */
   /* Constructors/Destructors                                                 */
   /* ------------------------------------------------------------------------ */
 public:
   quadrature_point_iterator(const field_type & field,
                             const typename field_type::type_iterator & t_it,
                             const typename field_type::type_iterator & t_it_end,
                             const array_iterator & array_it,
                             const array_iterator & array_it_end,
                             const GhostType ghost_type = _not_ghost)
       : parent(field, t_it, t_it_end, array_it, array_it_end, ghost_type) {}
 
   return_type operator*() { return *this->array_it; }
 };
 
 /* -------------------------------------------------------------------------- */
 
 __END_AKANTU_DUMPER__
 } // namespace akantu
 
 #endif /* __AKANTU_DUMPER_QUADRATURE_POINT_ITERATOR_HH__ */
diff --git a/src/io/dumper/dumper_text.cc b/src/io/dumper/dumper_text.cc
index ece87f179..acd6603e4 100644
--- a/src/io/dumper/dumper_text.cc
+++ b/src/io/dumper/dumper_text.cc
@@ -1,113 +1,112 @@
 /**
  * @file   dumper_text.cc
  *
  * @author David Simon Kammer <david.kammer@epfl.ch>
  *
  * @date creation: Fri Jun 18 2010
- * @date last modification: Sun Oct 19 2014
+ * @date last modification: Tue Nov 07 2017
  *
  * @brief  implementation of text dumper
  *
  * @section LICENSE
  *
- * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
- * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
- * Solides)
+ * 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
+ * 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
+ * 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 "dumper_text.hh"
 #include "communicator.hh"
 #include "dumper_nodal_field.hh"
 #include "mesh.hh"
 #include <io_helper.hh>
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 DumperText::DumperText(const std::string & basename,
                        iohelper::TextDumpMode mode, bool parallel)
     : DumperIOHelper() {
   AKANTU_DEBUG_IN();
 
   iohelper::DumperText * dumper_text = new iohelper::DumperText(mode);
   this->dumper = dumper_text;
   this->setBaseName(basename);
 
   this->setParallelContext(parallel);
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void DumperText::registerMesh(const Mesh & mesh,
                               __attribute__((unused)) UInt spatial_dimension,
                               __attribute__((unused))
                               const GhostType & ghost_type,
                               __attribute__((unused))
                               const ElementKind & element_kind) {
 
   registerField("position", new dumper::NodalField<Real>(mesh.getNodes()));
 
   // in parallel we need node type
   UInt nb_proc = mesh.getCommunicator().getNbProc();
   if (nb_proc > 1) {
     registerField("nodes_type",
                   new dumper::NodalField<NodeType>(mesh.getNodesType()));
   }
 }
 
 /* -------------------------------------------------------------------------- */
 void DumperText::registerFilteredMesh(
     const Mesh & mesh,
     __attribute__((unused)) const ElementTypeMapArray<UInt> & elements_filter,
     const Array<UInt> & nodes_filter,
     __attribute__((unused)) UInt spatial_dimension,
     __attribute__((unused)) const GhostType & ghost_type,
     __attribute__((unused)) const ElementKind & element_kind) {
 
   registerField("position", new dumper::NodalField<Real, true>(
                                 mesh.getNodes(), 0, 0, &nodes_filter));
 
   // in parallel we need node type
   UInt nb_proc = mesh.getCommunicator().getNbProc();
   if (nb_proc > 1) {
     registerField("nodes_type", new dumper::NodalField<NodeType, true>(
                                     mesh.getNodesType(), 0, 0, &nodes_filter));
   }
 }
 
 /* -------------------------------------------------------------------------- */
 void DumperText::setBaseName(const std::string & basename) {
   AKANTU_DEBUG_IN();
 
   DumperIOHelper::setBaseName(basename);
   static_cast<iohelper::DumperText *>(this->dumper)
       ->setDataSubDirectory(this->filename + "-DataFiles");
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void DumperText::setPrecision(UInt prec) {
   AKANTU_DEBUG_IN();
 
   static_cast<iohelper::DumperText *>(this->dumper)->setPrecision(prec);
 
   AKANTU_DEBUG_OUT();
 }
 
 } // akantu
diff --git a/src/io/dumper/dumper_text.hh b/src/io/dumper/dumper_text.hh
index d8e253b31..e7d1ce990 100644
--- a/src/io/dumper/dumper_text.hh
+++ b/src/io/dumper/dumper_text.hh
@@ -1,88 +1,87 @@
 /**
  * @file   dumper_text.hh
  *
  * @author David Simon Kammer <david.kammer@epfl.ch>
  *
  * @date creation: Fri Jun 18 2010
- * @date last modification: Sun Oct 19 2014
+ * @date last modification: Wed Nov 08 2017
  *
  * @brief  to dump into a text file
  *
  * @section LICENSE
  *
- * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
- * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
- * Solides)
+ * 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
+ * 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
+ * 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 "dumper_iohelper.hh"
 /* -------------------------------------------------------------------------- */
 #ifndef __AKANTU_DUMPER_TEXT_HH__
 #define __AKANTU_DUMPER_TEXT_HH__
 /* -------------------------------------------------------------------------- */
 #include <io_helper.hh>
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 
 class DumperText : public DumperIOHelper {
   /* ------------------------------------------------------------------------ */
   /* Constructors/Destructors                                                 */
   /* ------------------------------------------------------------------------ */
 public:
   DumperText(const std::string & basename = "dumper_text",
              iohelper::TextDumpMode mode = iohelper::_tdm_space,
              bool parallel = true);
   ~DumperText() override = default;
 
   /* ------------------------------------------------------------------------ */
   /* Methods                                                                  */
   /* ------------------------------------------------------------------------ */
 public:
   void
   registerMesh(const Mesh & mesh, UInt spatial_dimension = _all_dimensions,
                const GhostType & ghost_type = _not_ghost,
                const ElementKind & element_kind = _ek_not_defined) override;
 
   void registerFilteredMesh(
       const Mesh & mesh, const ElementTypeMapArray<UInt> & elements_filter,
       const Array<UInt> & nodes_filter,
       UInt spatial_dimension = _all_dimensions,
       const GhostType & ghost_type = _not_ghost,
       const ElementKind & element_kind = _ek_not_defined) override;
 
   void setBaseName(const std::string & basename) override;
 
 private:
   void registerNodeTypeField();
 
   /* ------------------------------------------------------------------------ */
   /* Accessors                                                                */
   /* ------------------------------------------------------------------------ */
 public:
   void setPrecision(UInt prec);
 
   /* ------------------------------------------------------------------------ */
   /* Class Members                                                            */
   /* ------------------------------------------------------------------------ */
 private:
 };
 
 } // akantu
 
 #endif /* __AKANTU_DUMPER_TEXT_HH__ */
diff --git a/src/io/dumper/dumper_type_traits.hh b/src/io/dumper/dumper_type_traits.hh
index e2f8edf3c..c7f688a8a 100644
--- a/src/io/dumper/dumper_type_traits.hh
+++ b/src/io/dumper/dumper_type_traits.hh
@@ -1,90 +1,90 @@
 /**
  * @file   dumper_type_traits.hh
  *
  * @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
  *
  * @date creation: Tue Sep 02 2014
- * @date last modification: Mon Sep 21 2015
+ * @date last modification: Wed Nov 08 2017
  *
  * @brief  Type traits for field properties
  *
  * @section LICENSE
  *
- * Copyright  (©)  2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de Lausanne)
+ * 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
+ * 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
+ * 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 {
 __BEGIN_AKANTU_DUMPER__
 /* -------------------------------------------------------------------------- */
 
 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>> {};
 /* -------------------------------------------------------------------------- */
 __END_AKANTU_DUMPER__
 } // akantu
 
 /* -------------------------------------------------------------------------- */
 
 #endif /* __AKANTU_DUMPER_TYPE_TRAITS_HH__ */
diff --git a/src/io/dumper/dumper_variable.hh b/src/io/dumper/dumper_variable.hh
index 5d322273b..7ff1228b6 100644
--- a/src/io/dumper/dumper_variable.hh
+++ b/src/io/dumper/dumper_variable.hh
@@ -1,119 +1,120 @@
 /**
  * @file   dumper_variable.hh
  *
  * @author David Simon Kammer <david.kammer@epfl.ch>
  *
  * @date creation: Tue Jun 04 2013
- * @date last modification: Sun Oct 19 2014
+ * @date last modification: Wed Nov 08 2017
  *
  * @brief  template of variable
  *
  * @section LICENSE
  *
- * Copyright  (©)  2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de Lausanne)
+ * 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
+ * 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
+ * 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 <type_traits>
 
 /* -------------------------------------------------------------------------- */
 #ifndef __AKANTU_DUMPER_IOHELPER_TMPL_VARIABLE_HH__
 #define __AKANTU_DUMPER_IOHELPER_TMPL_VARIABLE_HH__
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 namespace dumper {
   /* --------------------------------------------------------------------------
    */
 
   /// Variable interface
   class VariableBase {
   public:
     VariableBase() = default;
     virtual ~VariableBase() = default;
     virtual void registerToDumper(const std::string & id,
                                   iohelper::Dumper & dumper) = 0;
   };
 
   /* --------------------------------------------------------------------------
    */
 
   template <typename T, bool is_scal = std::is_arithmetic<T>::value>
   class Variable : public VariableBase {
   public:
     Variable(const T & t) : vari(t) {}
 
     void registerToDumper(const std::string & id,
                           iohelper::Dumper & dumper) override {
       dumper.addVariable(id, *this);
     }
 
     const T & operator[](UInt i) const { return vari[i]; }
 
     UInt getDim() { return vari.size(); }
     iohelper::DataType getDataType() { return iohelper::getDataType<T>(); }
 
   protected:
     const T & vari;
   };
 
   /* --------------------------------------------------------------------------
    */
   template <typename T> class Variable<Vector<T>, false> : public VariableBase {
   public:
     Variable(const Vector<T> & t) : vari(t) {}
 
     void registerToDumper(const std::string & id,
                           iohelper::Dumper & dumper) override {
       dumper.addVariable(id, *this);
     }
 
     const T & operator[](UInt i) const { return vari[i]; }
 
     UInt getDim() { return vari.size(); }
     iohelper::DataType getDataType() { return iohelper::getDataType<T>(); }
 
   protected:
     const Vector<T> & vari;
   };
 
   /* --------------------------------------------------------------------------
    */
 
   template <typename T> class Variable<T, true> : public VariableBase {
   public:
     Variable(const T & t) : vari(t) {}
 
     void registerToDumper(const std::string & id,
                           iohelper::Dumper & dumper) override {
       dumper.addVariable(id, *this);
     }
 
     const T & operator[](__attribute__((unused)) UInt i) const { return vari; }
 
     UInt getDim() { return 1; }
     iohelper::DataType getDataType() { return iohelper::getDataType<T>(); }
 
   protected:
     const T & vari;
   };
 
 } // namespace dumper
 } // namespace akantu
 
 #endif /* __AKANTU_DUMPER_IOHELPER_TMPL_VARIABLE_HH__ */
diff --git a/src/io/mesh_io.cc b/src/io/mesh_io.cc
index cdc56a716..23e96bb8a 100644
--- a/src/io/mesh_io.cc
+++ b/src/io/mesh_io.cc
@@ -1,148 +1,147 @@
 /**
  * @file   mesh_io.cc
  *
  * @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Fri Jun 18 2010
- * @date last modification: Mon Jun 01 2015
+ * @date last modification: Thu Feb 01 2018
  *
  * @brief  common part for all mesh io classes
  *
  * @section LICENSE
  *
- * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
- * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
- * Solides)
+ * 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
+ * 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
+ * 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 "mesh_io.hh"
 #include "aka_common.hh"
 #include "aka_iterators.hh"
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 MeshIO::MeshIO() {
   canReadSurface = false;
   canReadExtendedData = false;
 }
 
 /* -------------------------------------------------------------------------- */
 MeshIO::~MeshIO() = default;
 
 /* -------------------------------------------------------------------------- */
 std::unique_ptr<MeshIO> MeshIO::getMeshIO(const std::string & filename,
                                           const MeshIOType & type) {
   MeshIOType t = type;
   if (type == _miot_auto) {
     std::string::size_type idx = filename.rfind('.');
     std::string ext;
     if (idx != std::string::npos) {
       ext = filename.substr(idx + 1);
     }
 
     if (ext == "msh") {
       t = _miot_gmsh;
     } else if (ext == "diana") {
       t = _miot_diana;
     } else if (ext == "inp") {
       t = _miot_abaqus;
     } else
       AKANTU_EXCEPTION("Cannot guess the type of file of "
                        << filename << " (ext " << ext << "). "
                        << "Please provide the MeshIOType to the read function");
   }
 
   switch (t) {
   case _miot_gmsh:
     return std::make_unique<MeshIOMSH>();
 #if defined(AKANTU_STRUCTURAL_MECHANICS)
   case _miot_gmsh_struct:
     return std::make_unique<MeshIOMSHStruct>();
 #endif
   case _miot_diana:
     return std::make_unique<MeshIODiana>();
   case _miot_abaqus:
     return std::make_unique<MeshIOAbaqus>();
   default:
     return nullptr;
   }
 }
 
 /* -------------------------------------------------------------------------- */
 void MeshIO::read(const std::string & filename, Mesh & mesh,
                   const MeshIOType & type) {
   std::unique_ptr<MeshIO> mesh_io = getMeshIO(filename, type);
   mesh_io->read(filename, mesh);
 }
 
 /* -------------------------------------------------------------------------- */
 void MeshIO::write(const std::string & filename, Mesh & mesh,
                    const MeshIOType & type) {
   std::unique_ptr<MeshIO> mesh_io = getMeshIO(filename, type);
   mesh_io->write(filename, mesh);
 }
 
 /* -------------------------------------------------------------------------- */
 void MeshIO::constructPhysicalNames(const std::string & tag_name, Mesh & mesh) {
   if (!phys_name_map.empty()) {
     for (Mesh::type_iterator type_it = mesh.firstType();
          type_it != mesh.lastType(); ++type_it) {
 
       auto & name_vec =
           mesh.getDataPointer<std::string>("physical_names", *type_it);
 
       const auto & tags_vec = mesh.getData<UInt>(tag_name, *type_it);
 
       for (auto pair : zip(tags_vec, name_vec)) {
         auto tag = std::get<0>(pair);
         auto & name = std::get<1>(pair);
         auto map_it = phys_name_map.find(tag);
 
         if (map_it == phys_name_map.end()) {
           std::stringstream sstm;
           sstm << tag;
 
           name = sstm.str();
         } else {
           name = map_it->second;
         }
       }
     }
   }
 }
 
 /* -------------------------------------------------------------------------- */
 void MeshIO::printself(std::ostream & stream, int indent) const {
   std::string space;
   for (Int i = 0; i < indent; i++, space += AKANTU_INDENT)
     ;
 
   if (phys_name_map.size()) {
     stream << space << "Physical map:" << std::endl;
     for (auto & pair : phys_name_map) {
       stream << space << pair.first << ": " << pair.second << std::endl;
     }
   }
 }
 
 /* -------------------------------------------------------------------------- */
 
 } // namespace akantu
diff --git a/src/io/mesh_io.hh b/src/io/mesh_io.hh
index 5e4860613..5ff6aa2f8 100644
--- a/src/io/mesh_io.hh
+++ b/src/io/mesh_io.hh
@@ -1,118 +1,117 @@
 /**
  * @file   mesh_io.hh
  *
  * @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Fri Jun 18 2010
- * @date last modification: Mon Jun 01 2015
+ * @date last modification: Wed Aug 09 2017
  *
  * @brief  interface of a mesh io class, reader and writer
  *
  * @section LICENSE
  *
- * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
- * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
- * Solides)
+ * 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
+ * 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
+ * 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_MESH_IO_HH__
 #define __AKANTU_MESH_IO_HH__
 
 /* -------------------------------------------------------------------------- */
 #include "aka_common.hh"
 #include "mesh.hh"
 #include "mesh_accessor.hh"
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 
 class MeshIO {
   /* ------------------------------------------------------------------------ */
   /* Constructors/Destructors                                                 */
   /* ------------------------------------------------------------------------ */
 public:
   MeshIO();
 
   virtual ~MeshIO();
 
   /* ------------------------------------------------------------------------ */
   /* Methods                                                                  */
   /* ------------------------------------------------------------------------ */
 public:
   void read(const std::string & filename, Mesh & mesh, const MeshIOType & type);
   void write(const std::string & filename, Mesh & mesh,
              const MeshIOType & type);
 
   /// read a mesh from the file
   virtual void read(__attribute__((unused)) const std::string & filename,
                     __attribute__((unused)) Mesh & mesh) {}
 
   /// write a mesh to a file
   virtual void write(__attribute__((unused)) const std::string & filename,
                      __attribute__((unused)) const Mesh & mesh) {}
 
   /// function to request the manual construction of the physical names maps
   virtual void constructPhysicalNames(const std::string & tag_name,
                                       Mesh & mesh);
 
   /// method to permit to be printed to a generic stream
   virtual void printself(std::ostream & stream, int indent = 0) const;
 
   /// static contruction of a meshio object
   static std::unique_ptr<MeshIO> getMeshIO(const std::string & filename,
                                            const MeshIOType & type);
 
   /* ------------------------------------------------------------------------ */
   /* Accessors                                                                */
   /* ------------------------------------------------------------------------ */
 public:
   std::map<UInt, std::string> & getPhysicalNameMap() { return phys_name_map; }
 
   /* ------------------------------------------------------------------------ */
   /* Class Members                                                            */
   /* ------------------------------------------------------------------------ */
 protected:
   bool canReadSurface;
 
   bool canReadExtendedData;
 
   /// correspondance between a tag and physical names (if applicable)
   std::map<UInt, std::string> phys_name_map;
 };
 
 /* -------------------------------------------------------------------------- */
 
 inline std::ostream & operator<<(std::ostream & stream, const MeshIO & _this) {
   _this.printself(stream);
   return stream;
 }
 
 /* -------------------------------------------------------------------------- */
 
 } // namespace akantu
 
 #include "mesh_io_abaqus.hh"
 #include "mesh_io_diana.hh"
 #include "mesh_io_msh.hh"
 
 #if defined(AKANTU_STRUCTURAL_MECHANICS)
 #include "mesh_io_msh_struct.hh"
 #endif
 
 #endif /* __AKANTU_MESH_IO_HH__ */
diff --git a/src/io/mesh_io/mesh_io_abaqus.cc b/src/io/mesh_io/mesh_io_abaqus.cc
index a9f7714b4..fd16133b7 100644
--- a/src/io/mesh_io/mesh_io_abaqus.cc
+++ b/src/io/mesh_io/mesh_io_abaqus.cc
@@ -1,475 +1,475 @@
 /**
  * @file   mesh_io_abaqus.cc
  *
  * @author Daniel Pino Muñoz <daniel.pinomunoz@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Fri Jan 04 2013
- * @date last modification: Fri Dec 11 2015
+ * @date last modification: Tue Feb 20 2018
  *
  * @brief  read a mesh from an abaqus input file
  *
  * @section LICENSE
  *
- * Copyright  (©)  2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de Lausanne)
+ * 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
+ * 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
+ * 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/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 // std library header files
 #include <fstream>
 
 // akantu header files
 #include "mesh.hh"
 #include "mesh_io_abaqus.hh"
 #include "mesh_utils.hh"
 
 #include "element_group.hh"
 #include "node_group.hh"
 
 #if defined(__INTEL_COMPILER)
 //#pragma warning ( disable : 383 )
 #elif defined(__clang__) // test clang to be sure that when we test for gnu it
 // is only gnu
 #elif (defined(__GNUC__) || defined(__GNUG__))
 #define GCC_VERSION                                                            \
   (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__)
 #if GCC_VERSION > 40600
 #pragma GCC diagnostic push
 #endif
 #pragma GCC diagnostic ignored "-Wunused-local-typedefs"
 #endif
 
 /* -------------------------------------------------------------------------- */
 #include <boost/config/warning_disable.hpp>
 #include <boost/spirit/include/phoenix.hpp>
 #include <boost/spirit/include/qi.hpp>
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 MeshIOAbaqus::MeshIOAbaqus() = default;
 
 /* -------------------------------------------------------------------------- */
 MeshIOAbaqus::~MeshIOAbaqus() = default;
 
 /* -------------------------------------------------------------------------- */
 namespace spirit = boost::spirit;
 namespace qi = boost::spirit::qi;
 namespace ascii = boost::spirit::ascii;
 namespace lbs = boost::spirit::qi::labels;
 namespace phx = boost::phoenix;
 
 /* -------------------------------------------------------------------------- */
 void element_read(Mesh & mesh, const ElementType & type, UInt id,
                   const std::vector<Int> & conn,
                   const std::map<UInt, UInt> & nodes_mapping,
                   std::map<UInt, Element> & elements_mapping) {
   Vector<UInt> tmp_conn(Mesh::getNbNodesPerElement(type));
 
   AKANTU_DEBUG_ASSERT(conn.size() == tmp_conn.size(),
                       "The nodes in the Abaqus file have too many coordinates"
                           << " for the mesh you try to fill.");
 
   mesh.addConnectivityType(type);
   Array<UInt> & connectivity = mesh.getConnectivity(type);
 
   UInt i = 0;
   for (auto it = conn.begin(); it != conn.end(); ++it) {
     auto nit = nodes_mapping.find(*it);
     AKANTU_DEBUG_ASSERT(nit != nodes_mapping.end(),
                         "There is an unknown node in the connectivity.");
     tmp_conn[i++] = nit->second;
   }
   Element el{type, connectivity.size(), _not_ghost};
   elements_mapping[id] = el;
   connectivity.push_back(tmp_conn);
 }
 
 void node_read(Mesh & mesh, UInt id, const std::vector<Real> & pos,
                std::map<UInt, UInt> & nodes_mapping) {
   Vector<Real> tmp_pos(mesh.getSpatialDimension());
   UInt i = 0;
   for (auto it = pos.begin(); it != pos.end() || i < mesh.getSpatialDimension();
        ++it)
     tmp_pos[i++] = *it;
 
   nodes_mapping[id] = mesh.getNbNodes();
   mesh.getNodes().push_back(tmp_pos);
 }
 
 /* ------------------------------------------------------------------------ */
 void add_element_to_group(ElementGroup * el_grp, UInt element,
                           const std::map<UInt, Element> & elements_mapping) {
   auto eit = elements_mapping.find(element);
   AKANTU_DEBUG_ASSERT(eit != elements_mapping.end(),
                       "There is an unknown element ("
                           << element << ") in the in the ELSET "
                           << el_grp->getName() << ".");
 
   el_grp->add(eit->second, true, false);
 }
 
 ElementGroup * element_group_create(Mesh & mesh, const ID & name) {
   auto eg_it = mesh.element_group_find(name);
   if (eg_it != mesh.element_group_end()) {
     return eg_it->second;
   } else {
     return &mesh.createElementGroup(name, _all_dimensions);
   }
 }
 
 NodeGroup * node_group_create(Mesh & mesh, const ID & name) {
   auto ng_it = mesh.node_group_find(name);
   if (ng_it != mesh.node_group_end()) {
     return ng_it->second;
   } else {
     return &mesh.createNodeGroup(name, mesh.getSpatialDimension());
   }
 }
 
 void add_node_to_group(NodeGroup * node_grp, UInt node,
                        const std::map<UInt, UInt> & nodes_mapping) {
   auto nit = nodes_mapping.find(node);
 
   AKANTU_DEBUG_ASSERT(nit != nodes_mapping.end(),
                       "There is an unknown node in the in the NSET "
                           << node_grp->getName() << ".");
 
   node_grp->add(nit->second, false);
 }
 
 void optimize_group(NodeGroup * grp) { grp->optimize(); }
 void optimize_element_group(ElementGroup * grp) { grp->optimize(); }
 
 /* -------------------------------------------------------------------------- */
 template <class Iterator> struct AbaqusSkipper : qi::grammar<Iterator> {
   AbaqusSkipper() : AbaqusSkipper::base_type(skip, "abaqus_skipper") {
     /* clang-format off */
     skip
       =   (ascii::space - spirit::eol)
       |   "**" >> *(qi::char_ - spirit::eol) >> spirit::eol
       ;
     /* clang-format on */
   }
   qi::rule<Iterator> skip;
 };
 
 /* -------------------------------------------------------------------------- */
 template <class Iterator, typename Skipper = AbaqusSkipper<Iterator>>
 struct AbaqusMeshGrammar : qi::grammar<Iterator, void(), Skipper> {
 public:
   AbaqusMeshGrammar(Mesh & mesh)
       : AbaqusMeshGrammar::base_type(start, "abaqus_mesh_reader"), mesh(mesh) {
 
     /* clang-format off */
     start
       =  *(
              (qi::char_('*')
                 >  (   (qi::no_case[ qi::lit("node output")    ] > any_section)
                    |   (qi::no_case[ qi::lit("element output") ] > any_section)
                    |   (qi::no_case[ qi::lit("node")           ] > nodes)
                    |   (qi::no_case[ qi::lit("element")        ] > elements)
                    |   (qi::no_case[ qi::lit("heading")        ] > header)
                    |   (qi::no_case[ qi::lit("elset")          ] > elements_set)
                    |   (qi::no_case[ qi::lit("nset")           ] > nodes_set)
                    |   (qi::no_case[ qi::lit("material")       ] > material)
                    |   (keyword > any_section)
                    )
              )
           |  spirit::eol
           )
       ;
 
     header
       =   spirit::eol
       >   *any_line
       ;
 
     nodes
       =   *(qi::char_(',') >> option)
            >> spirit::eol
            >> *( (qi::int_
                   > node_position) [ phx::bind(&node_read,
                                                  phx::ref(mesh),
                                                  lbs::_1,
                                                  lbs::_2,
                                                  phx::ref(abaqus_nodes_to_akantu)) ]
                   >> spirit::eol
                )
       ;
 
     elements
       =   (
              (  qi::char_(',') >> qi::no_case[qi::lit("type")] >> '='
                 >> abaqus_element_type  [ lbs::_a = lbs::_1 ]
              )
           ^  *(qi::char_(',') >> option)
           )
           >> spirit::eol
           >> *(  (qi::int_
                   > connectivity) [ phx::bind(&element_read,
                                                 phx::ref(mesh),
                                                 lbs::_a,
                                                 lbs::_1,
                                                 lbs::_2,
                                                 phx::cref(abaqus_nodes_to_akantu),
                                                 phx::ref(abaqus_elements_to_akantu)) ]
                  >> spirit::eol
                )
       ;
 
     elements_set
       =   (
              (
                 (  qi::char_(',') >> qi::no_case[ qi::lit("elset") ] >> '='
                    >> value [ lbs::_a = phx::bind<ElementGroup *>(&element_group_create,
                                                                     phx::ref(mesh),
                                                                     lbs::_1) ]
                 )
              ^  *(qi::char_(',') >> option)
              )
              >> spirit::eol
              >> qi::skip
                   (qi::char_(',') | qi::space)
              [ +(qi::int_ [ phx::bind(&add_element_to_group,
                                         lbs::_a,
                                         lbs::_1,
                                         phx::cref(abaqus_elements_to_akantu)
                                         )
                                ]
                      )
                  ]
            ) [ phx::bind(&optimize_element_group, lbs::_a) ]
       ;
 
     nodes_set
       =   (
              (
                 (  qi::char_(',')
                    >> qi::no_case[ qi::lit("nset") ] >> '='
                    >> value [ lbs::_a = phx::bind<NodeGroup *>(&node_group_create, phx::ref(mesh), lbs::_1) ]
                 )
              ^  *(qi::char_(',') >> option)
              )
              >> spirit::eol
              >> qi::skip
                  (qi::char_(',') | qi::space)
                  [ +(qi::int_ [ phx::bind(&add_node_to_group,
                                             lbs::_a,
                                             lbs::_1,
                                             phx::cref(abaqus_nodes_to_akantu)
                                            )
                               ]
                     )
                  ]
            ) [ phx::bind(&optimize_group, lbs::_a) ]
       ;
 
     material
       =   (
              (  qi::char_(',') >> qi::no_case[ qi::lit("name") ] >> '='
                 >> value  [ phx::push_back(phx::ref(material_names), lbs::_1) ]
              )
           ^  *(qi::char_(',') >> option)
           ) >> spirit::eol;
       ;
 
     node_position
       =   +(qi::char_(',') > real [ phx::push_back(lbs::_val, lbs::_1) ])
       ;
 
     connectivity
       = +(qi::char_(',') > qi::int_ [ phx::push_back(lbs::_val, lbs::_1) ])
       ;
 
 
     any_section
       =   *(qi::char_(',') >> option) > spirit::eol
       >   *any_line
       ;
 
     any_line
       =   *(qi::char_ - spirit::eol - qi::char_('*')) >> spirit::eol
       ;
 
     keyword
       =   qi::lexeme[ +(qi::char_ - (qi::char_('*') | spirit::eol)) ]
       ;
 
     option
       = key > -( '=' >> value );
 
     key
       =   qi::char_("a-zA-Z_") >> *(qi::char_("a-zA-Z_0-9") | qi::char_('-'))
       ;
 
     value
       =   key.alias()
       ;
 
     BOOST_SPIRIT_DEBUG_NODE(start);
 
     abaqus_element_type.add
 #if defined(AKANTU_STRUCTURAL_MECHANICS)
       ("BE21"  , _bernoulli_beam_2)
       ("BE31"  , _bernoulli_beam_3)
 #endif
       ("T3D2"  , _segment_2) // Gmsh generates this elements
       ("T3D3"  , _segment_3) // Gmsh generates this elements
       ("CPE3"  , _triangle_3)
       ("CPS3"  , _triangle_3)
       ("DC2D3" , _triangle_3)
       ("CPE6"  , _triangle_6)
       ("CPS6"  , _triangle_6)
       ("DC2D6" , _triangle_6)
       ("CPE4"  , _quadrangle_4)
       ("CPS4"  , _quadrangle_4)
       ("DC2D4" , _quadrangle_4)
       ("CPE8"  , _quadrangle_8)
       ("CPS8"  , _quadrangle_8)
       ("DC2D8" , _quadrangle_8)
       ("C3D4"  , _tetrahedron_4)
       ("DC3D4" , _tetrahedron_4)
       ("C3D8"  , _hexahedron_8)
       ("C3D8R" , _hexahedron_8)
       ("DC3D8" , _hexahedron_8)
       ("C3D10" , _tetrahedron_10)
       ("DC3D10", _tetrahedron_10);
 
 #if !defined(AKANTU_NDEBUG) && defined(AKANTU_CORE_CXX_11)
     qi::on_error<qi::fail>(start, error_handler(lbs::_4, lbs::_3, lbs::_2));
 #endif
     
     start              .name("abaqus-start-rule");
     connectivity       .name("abaqus-connectivity");
     node_position      .name("abaqus-nodes-position");
     nodes              .name("abaqus-nodes");
     any_section        .name("abaqus-any_section");
     header             .name("abaqus-header");
     material           .name("abaqus-material");
     elements           .name("abaqus-elements");
     elements_set       .name("abaqus-elements-set");
     nodes_set          .name("abaqus-nodes-set");
     key                .name("abaqus-key");
     value              .name("abaqus-value");
     option             .name("abaqus-option");
     keyword            .name("abaqus-keyword");
     any_line           .name("abaqus-any-line");
     abaqus_element_type.name("abaqus-element-type");
 
     /* clang-format on */
   }
 
 public:
   AKANTU_GET_MACRO(MaterialNames, material_names,
                    const std::vector<std::string> &);
 
   /* ------------------------------------------------------------------------ */
   /* Rules                                                                    */
   /* ------------------------------------------------------------------------ */
 private:
   qi::rule<Iterator, void(), Skipper> start;
   qi::rule<Iterator, std::vector<int>(), Skipper> connectivity;
   qi::rule<Iterator, std::vector<Real>(), Skipper> node_position;
   qi::rule<Iterator, void(), Skipper> nodes, any_section, header, material;
   qi::rule<Iterator, void(), qi::locals<ElementType>, Skipper> elements;
   qi::rule<Iterator, void(), qi::locals<ElementGroup *>, Skipper> elements_set;
   qi::rule<Iterator, void(), qi::locals<NodeGroup *>, Skipper> nodes_set;
 
   qi::rule<Iterator, std::string(), Skipper> key, value, option, keyword,
       any_line;
 
   qi::real_parser<Real, qi::real_policies<Real>> real;
 
   qi::symbols<char, ElementType> abaqus_element_type;
 
   /* ------------------------------------------------------------------------ */
   /* Mambers                                                                  */
   /* ------------------------------------------------------------------------ */
 private:
   /// reference to the mesh to read
   Mesh & mesh;
 
   /// correspondance between the numbering of nodes in the abaqus file and in
   /// the akantu mesh
   std::map<UInt, UInt> abaqus_nodes_to_akantu;
 
   /// correspondance between the element number in the abaqus file and the
   /// Element in the akantu mesh
   std::map<UInt, Element> abaqus_elements_to_akantu;
 
   /// list of the material names
   std::vector<std::string> material_names;
 };
 /* -------------------------------------------------------------------------- */
 
 /* -------------------------------------------------------------------------- */
 void MeshIOAbaqus::read(const std::string & filename, Mesh & mesh) {
   namespace spirit = boost::spirit;
   namespace qi = boost::spirit::qi;
   namespace lbs = boost::spirit::qi::labels;
   namespace ascii = boost::spirit::ascii;
   namespace phx = boost::phoenix;
 
   std::ifstream infile;
   infile.open(filename.c_str());
 
   if (!infile.good()) {
     AKANTU_ERROR("Cannot open file " << filename);
   }
 
   std::string storage;             // We will read the contents here.
   infile.unsetf(std::ios::skipws); // No white space skipping!
   std::copy(std::istream_iterator<char>(infile), std::istream_iterator<char>(),
             std::back_inserter(storage));
 
   using iterator_t = std::string::const_iterator;
   using skipper = AbaqusSkipper<iterator_t>;
   using grammar = AbaqusMeshGrammar<iterator_t, skipper>;
 
   grammar g(mesh);
   skipper ws;
 
   iterator_t iter = storage.begin();
   iterator_t end = storage.end();
 
   qi::phrase_parse(iter, end, g, ws);
 
   MeshAccessor mesh_accessor(mesh);
 
   for (auto & mat_name : g.getMaterialNames()) {
     auto eg_it = mesh.element_group_find(mat_name);
     auto & eg = *eg_it->second;
     if (eg_it != mesh.element_group_end()) {
       for (auto & type : eg.elementTypes()) {
         Array<std::string> & abaqus_material =
             mesh_accessor.getData<std::string>("abaqus_material", type);
 
         for (auto elem : eg.getElements(type)) {
           abaqus_material(elem) = mat_name;
         }
       }
     }
   }
 
   mesh_accessor.setNbGlobalNodes(mesh.getNodes().size());
   MeshUtils::fillElementToSubElementsData(mesh);
 }
 
 } // namespace akantu
diff --git a/src/io/mesh_io/mesh_io_abaqus.hh b/src/io/mesh_io/mesh_io_abaqus.hh
index 5feea6314..305eb2d93 100644
--- a/src/io/mesh_io/mesh_io_abaqus.hh
+++ b/src/io/mesh_io/mesh_io_abaqus.hh
@@ -1,60 +1,59 @@
 /**
  * @file   mesh_io_abaqus.hh
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Sun Sep 26 2010
- * @date last modification: Tue Jun 30 2015
+ * @date last modification: Wed Nov 08 2017
  *
  * @brief  read a mesh from an abaqus input file
  *
  * @section LICENSE
  *
- * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
- * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
- * Solides)
+ * 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
+ * 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
+ * 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 "mesh_accessor.hh"
 #include "mesh_io.hh"
 
 #ifndef __AKANTU_MESH_IO_ABAQUS_HH__
 #define __AKANTU_MESH_IO_ABAQUS_HH__
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 class MeshIOAbaqus : public MeshIO {
 public:
   MeshIOAbaqus();
   ~MeshIOAbaqus() override;
 
   /// read a mesh from the file
   void read(const std::string & filename, Mesh & mesh) override;
 
   /// write a mesh to a file
   //  virtual void write(const std::string & filename, const Mesh & mesh);
 
 private:
   /// correspondence between msh element types and akantu element types
   std::map<std::string, ElementType> _abaqus_to_akantu_element_types;
 };
 
 } // akantu
 
 #endif /* __AKANTU_MESH_IO_ABAQUS_HH__ */
diff --git a/src/io/mesh_io/mesh_io_diana.cc b/src/io/mesh_io/mesh_io_diana.cc
index 634226ac0..80a3bc957 100644
--- a/src/io/mesh_io/mesh_io_diana.cc
+++ b/src/io/mesh_io/mesh_io_diana.cc
@@ -1,602 +1,601 @@
 /**
  * @file   mesh_io_diana.cc
  *
  * @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
  * @author David Simon Kammer <david.kammer@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  * @author Alodie Schneuwly <alodie.schneuwly@epfl.ch>
  *
  * @date creation: Sat Mar 26 2011
- * @date last modification: Thu Jan 21 2016
+ * @date last modification: Tue Feb 20 2018
  *
  * @brief  handles diana meshes
  *
  * @section LICENSE
  *
- * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
- * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
- * Solides)
+ * 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
+ * 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
+ * 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 <fstream>
 #include <iostream>
 
 /* -------------------------------------------------------------------------- */
 #include "element_group.hh"
 #include "mesh_io_diana.hh"
 #include "mesh_utils.hh"
 /* -------------------------------------------------------------------------- */
 #include <string.h>
 /* -------------------------------------------------------------------------- */
 #include <stdio.h>
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 /*   Methods Implentations                                                    */
 /* -------------------------------------------------------------------------- */
 
 MeshIODiana::MeshIODiana() {
   canReadSurface = true;
   canReadExtendedData = true;
   _diana_to_akantu_element_types["T9TM"] = _triangle_3;
   _diana_to_akantu_element_types["CT6CM"] = _triangle_6;
   _diana_to_akantu_element_types["Q12TM"] = _quadrangle_4;
   _diana_to_akantu_element_types["CQ8CM"] = _quadrangle_8;
   _diana_to_akantu_element_types["TP18L"] = _pentahedron_6;
   _diana_to_akantu_element_types["CTP45"] = _pentahedron_15;
   _diana_to_akantu_element_types["TE12L"] = _tetrahedron_4;
   _diana_to_akantu_element_types["HX24L"] = _hexahedron_8;
   _diana_to_akantu_element_types["CHX60"] = _hexahedron_20;
   _diana_to_akantu_mat_prop["YOUNG"] = "E";
   _diana_to_akantu_mat_prop["DENSIT"] = "rho";
   _diana_to_akantu_mat_prop["POISON"] = "nu";
 
   std::map<std::string, ElementType>::iterator it;
   for (it = _diana_to_akantu_element_types.begin();
        it != _diana_to_akantu_element_types.end(); ++it) {
     UInt nb_nodes = Mesh::getNbNodesPerElement(it->second);
 
     auto * tmp = new UInt[nb_nodes];
     for (UInt i = 0; i < nb_nodes; ++i) {
       tmp[i] = i;
     }
 
     switch (it->second) {
     case _tetrahedron_10:
       tmp[8] = 9;
       tmp[9] = 8;
       break;
     case _pentahedron_15:
       tmp[0] = 2;
       tmp[1] = 8;
       tmp[2] = 0;
       tmp[3] = 6;
       tmp[4] = 1;
       tmp[5] = 7;
       tmp[6] = 11;
       tmp[7] = 9;
       tmp[8] = 10;
       tmp[9] = 5;
       tmp[10] = 14;
       tmp[11] = 3;
       tmp[12] = 12;
       tmp[13] = 4;
       tmp[14] = 13;
       break;
     case _hexahedron_20:
       tmp[0] = 5;
       tmp[1] = 16;
       tmp[2] = 4;
       tmp[3] = 19;
       tmp[4] = 7;
       tmp[5] = 18;
       tmp[6] = 6;
       tmp[7] = 17;
       tmp[8] = 13;
       tmp[9] = 12;
       tmp[10] = 15;
       tmp[11] = 14;
       tmp[12] = 1;
       tmp[13] = 8;
       tmp[14] = 0;
       tmp[15] = 11;
       tmp[16] = 3;
       tmp[17] = 10;
       tmp[18] = 2;
       tmp[19] = 9;
       break;
     default:
       // nothing to change
       break;
     }
     _read_order[it->second] = tmp;
   }
 }
 
 /* -------------------------------------------------------------------------- */
 MeshIODiana::~MeshIODiana() = default;
 
 /* -------------------------------------------------------------------------- */
 inline void my_getline(std::ifstream & infile, std::string & line) {
   std::getline(infile, line);   // read the line
   size_t pos = line.find('\r'); /// remove the extra \r if needed
   line = line.substr(0, pos);
 }
 
 /* -------------------------------------------------------------------------- */
 void MeshIODiana::read(const std::string & filename, Mesh & mesh) {
   AKANTU_DEBUG_IN();
 
   MeshAccessor mesh_accessor(mesh);
 
   std::ifstream infile;
   infile.open(filename.c_str());
 
   std::string line;
   UInt first_node_number = std::numeric_limits<UInt>::max();
   diana_element_number_to_elements.clear();
 
   if (!infile.good()) {
     AKANTU_ERROR("Cannot open file " << filename);
   }
 
   while (infile.good()) {
     my_getline(infile, line);
 
     /// read all nodes
     if (line == "'COORDINATES'") {
       line = readCoordinates(infile, mesh, first_node_number);
     }
 
     /// read all elements
     if (line == "'ELEMENTS'") {
       line = readElements(infile, mesh, first_node_number);
     }
 
     /// read the material properties and write a .dat file
     if (line == "'MATERIALS'") {
       line = readMaterial(infile, filename);
     }
 
     /// read the material properties and write a .dat file
     if (line == "'GROUPS'") {
       line = readGroups(infile, mesh, first_node_number);
     }
   }
   infile.close();
 
   mesh_accessor.setNbGlobalNodes(mesh.getNbNodes());
 
   MeshUtils::fillElementToSubElementsData(mesh);
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void MeshIODiana::write(__attribute__((unused)) const std::string & filename,
                         __attribute__((unused)) const Mesh & mesh) {
   AKANTU_TO_IMPLEMENT();
 }
 
 /* -------------------------------------------------------------------------- */
 std::string MeshIODiana::readCoordinates(std::ifstream & infile, Mesh & mesh,
                                          UInt & first_node_number) {
   AKANTU_DEBUG_IN();
 
   MeshAccessor mesh_accessor(mesh);
 
   Array<Real> & nodes = mesh_accessor.getNodes();
 
   std::string line;
 
   UInt index;
   Vector<Real> coord(3);
 
   do {
     my_getline(infile, line);
     if ("'ELEMENTS'" == line)
       break;
 
     std::stringstream sstr_node(line);
     sstr_node >> index >> coord(0) >> coord(1) >> coord(2);
 
     first_node_number = first_node_number < index ? first_node_number : index;
 
     nodes.push_back(coord);
   } while (true);
 
   AKANTU_DEBUG_OUT();
   return line;
 }
 
 /* -------------------------------------------------------------------------- */
 UInt MeshIODiana::readInterval(std::stringstream & line,
                                std::set<UInt> & interval) {
   UInt first;
   line >> first;
   if (line.fail()) {
     return 0;
   }
   interval.insert(first);
 
   UInt second;
   int dash;
   dash = line.get();
   if (dash == '-') {
     line >> second;
     interval.insert(second);
     return 2;
   }
 
   if (line.fail())
     line.clear(std::ios::eofbit); // in case of get at end of the line
   else
     line.unget();
   return 1;
 }
 
 /* -------------------------------------------------------------------------- */
 std::string MeshIODiana::readGroups(std::ifstream & infile, Mesh & mesh,
                                     UInt first_node_number) {
   AKANTU_DEBUG_IN();
 
   std::string line;
   my_getline(infile, line);
 
   bool reading_nodes_group = false;
 
   while (line != "'SUPPORTS'") {
     if (line == "NODES") {
       reading_nodes_group = true;
       my_getline(infile, line);
     }
 
     if (line == "ELEMEN") {
       reading_nodes_group = false;
       my_getline(infile, line);
     }
 
     auto * str = new std::stringstream(line);
 
     UInt id;
     std::string name;
     char c;
     *str >> id >> name >> c;
 
     auto * list_ids = new Array<UInt>(0, 1, name);
 
     UInt s = 1;
     bool end = false;
     while (!end) {
       while (!str->eof() && s != 0) {
         std::set<UInt> interval;
         s = readInterval(*str, interval);
         auto it = interval.begin();
         if (s == 1)
           list_ids->push_back(*it);
         if (s == 2) {
           UInt first = *it;
           ++it;
           UInt second = *it;
           for (UInt i = first; i <= second; ++i) {
             list_ids->push_back(i);
           }
         }
       }
       if (str->fail())
         end = true;
       else {
         my_getline(infile, line);
         delete str;
         str = new std::stringstream(line);
       }
     }
 
     delete str;
 
     if (reading_nodes_group) {
       NodeGroup & ng = mesh.createNodeGroup(name);
       for (UInt i = 0; i < list_ids->size(); ++i) {
         UInt node = (*list_ids)(i)-first_node_number;
         ng.add(node, false);
       }
       delete list_ids;
 
     } else {
       ElementGroup & eg = mesh.createElementGroup(name);
       for (UInt i = 0; i < list_ids->size(); ++i) {
         Element & elem = diana_element_number_to_elements[(*list_ids)(i)];
         if (elem.type != _not_defined)
           eg.add(elem, false, false);
       }
 
       eg.optimize();
       delete list_ids;
     }
 
     my_getline(infile, line);
   }
 
   AKANTU_DEBUG_OUT();
   return line;
 }
 
 /* -------------------------------------------------------------------------- */
 std::string MeshIODiana::readElements(std::ifstream & infile, Mesh & mesh,
                                       UInt first_node_number) {
   AKANTU_DEBUG_IN();
 
   std::string line;
   my_getline(infile, line);
 
   if ("CONNECTIVITY" == line) {
     line = readConnectivity(infile, mesh, first_node_number);
   }
 
   /// read the line corresponding to the materials
   if ("MATERIALS" == line) {
     line = readMaterialElement(infile, mesh);
   }
 
   AKANTU_DEBUG_OUT();
   return line;
 }
 
 /* -------------------------------------------------------------------------- */
 std::string MeshIODiana::readConnectivity(std::ifstream & infile, Mesh & mesh,
                                           UInt first_node_number) {
   AKANTU_DEBUG_IN();
 
   MeshAccessor mesh_accessor(mesh);
   Int index;
   std::string lline;
 
   std::string diana_type;
   ElementType akantu_type, akantu_type_old = _not_defined;
   Array<UInt> * connectivity = nullptr;
   UInt node_per_element = 0;
   Element elem;
   UInt * read_order = nullptr;
 
   while (true) {
     my_getline(infile, lline);
     //    std::cerr << lline << std::endl;
     std::stringstream sstr_elem(lline);
     if (lline == "MATERIALS")
       break;
 
     /// traiter les coordonnees
     sstr_elem >> index;
     sstr_elem >> diana_type;
 
     akantu_type = _diana_to_akantu_element_types[diana_type];
 
     if (akantu_type == _not_defined)
       continue;
 
     if (akantu_type != akantu_type_old) {
       connectivity = &(mesh_accessor.getConnectivity(akantu_type));
 
       node_per_element = connectivity->getNbComponent();
       akantu_type_old = akantu_type;
       read_order = _read_order[akantu_type];
     }
 
     Vector<UInt> local_connect(node_per_element);
 
     // used if element is written on two lines
     UInt j_last = 0;
 
     for (UInt j = 0; j < node_per_element; ++j) {
       UInt node_index;
       sstr_elem >> node_index;
 
       // check s'il y a pas plus rien après un certain point
 
       if (sstr_elem.fail()) {
         sstr_elem.clear();
         sstr_elem.ignore();
         break;
       }
 
       node_index -= first_node_number;
       local_connect(read_order[j]) = node_index;
       j_last = j;
     }
 
     // check if element is written in two lines
     if (j_last != (node_per_element - 1)) {
 
       // if this is the case, read on more line
       my_getline(infile, lline);
       std::stringstream sstr_elem(lline);
 
       for (UInt j = (j_last + 1); j < node_per_element; ++j) {
 
         UInt node_index;
         sstr_elem >> node_index;
 
         node_index -= first_node_number;
         local_connect(read_order[j]) = node_index;
       }
     }
 
     connectivity->push_back(local_connect);
 
     elem.type = akantu_type;
     elem.element = connectivity->size() - 1;
 
     diana_element_number_to_elements[index] = elem;
     akantu_number_to_diana_number[elem] = index;
   }
 
   AKANTU_DEBUG_OUT();
   return lline;
 }
 
 /* -------------------------------------------------------------------------- */
 std::string MeshIODiana::readMaterialElement(std::ifstream & infile,
                                              Mesh & mesh) {
   AKANTU_DEBUG_IN();
 
   std::string line;
   std::stringstream sstr_tag_name;
   sstr_tag_name << "tag_" << 0;
 
   Mesh::type_iterator it = mesh.firstType();
   Mesh::type_iterator end = mesh.lastType();
   for (; it != end; ++it) {
     UInt nb_element = mesh.getNbElement(*it);
     mesh.getDataPointer<UInt>("material", *it, _not_ghost, 1)
         .resize(nb_element);
   }
 
   my_getline(infile, line);
   while (line != "'MATERIALS'") {
     line =
         line.substr(line.find('/') + 1,
                     std::string::npos); // erase the first slash / of the line
     char tutu[250];
     strncpy(tutu, line.c_str(), 250);
 
     AKANTU_DEBUG_WARNING("reading line " << line);
     Array<UInt> temp_id(0, 2);
     UInt mat;
     while (true) {
       std::stringstream sstr_intervals_elements(line);
       Vector<UInt> id(2);
       char temp;
       while (sstr_intervals_elements.good()) {
         sstr_intervals_elements >> id(0) >> temp >> id(1); // >> "/" >> mat;
         if (!sstr_intervals_elements.fail())
           temp_id.push_back(id);
       }
       if (sstr_intervals_elements.fail()) {
         sstr_intervals_elements.clear();
         sstr_intervals_elements.ignore();
         sstr_intervals_elements >> mat;
         break;
       }
       my_getline(infile, line);
     }
 
     // loop over elements
     //    UInt * temp_id_val = temp_id.storage();
     for (UInt i = 0; i < temp_id.size(); ++i)
       for (UInt j = temp_id(i, 0); j <= temp_id(i, 1); ++j) {
         Element & element = diana_element_number_to_elements[j];
         if (element.type == _not_defined)
           continue;
         UInt elem = element.element;
         ElementType type = element.type;
         Array<UInt> & data =
             mesh.getDataPointer<UInt>("material", type, _not_ghost);
         data(elem) = mat;
       }
 
     my_getline(infile, line);
   }
 
   AKANTU_DEBUG_OUT();
   return line;
 }
 
 /* -------------------------------------------------------------------------- */
 std::string MeshIODiana::readMaterial(std::ifstream & infile,
                                       const std::string & filename) {
   AKANTU_DEBUG_IN();
 
   std::stringstream mat_file_name;
 
   mat_file_name << "material_" << filename;
 
   std::ofstream material_file;
   material_file.open(mat_file_name.str().c_str()); // mat_file_name.str());
 
   UInt mat_index;
   std::string line;
 
   bool first_mat = true;
   bool end = false;
 
   UInt mat_id = 0;
 
   using MatProp = std::map<std::string, Real>;
   MatProp mat_prop;
   do {
     my_getline(infile, line);
     std::stringstream sstr_material(line);
     if (("'GROUPS'" == line) || ("'END'" == line)) {
       if (!mat_prop.empty()) {
         material_file << "material elastic [" << std::endl;
         material_file << "\tname = material" << ++mat_id << std::endl;
         for (auto it = mat_prop.begin(); it != mat_prop.end(); ++it)
           material_file << "\t" << it->first << " = " << it->second
                         << std::endl;
         material_file << "]" << std::endl;
         mat_prop.clear();
       }
       end = true;
     } else {
       /// traiter les caractéristiques des matériaux
       sstr_material >> mat_index;
 
       if (!sstr_material.fail()) {
         if (!first_mat) {
           if (!mat_prop.empty()) {
             material_file << "material elastic [" << std::endl;
             material_file << "\tname = material" << ++mat_id << std::endl;
             for (auto it = mat_prop.begin(); it != mat_prop.end(); ++it)
               material_file << "\t" << it->first << " = " << it->second
                             << std::endl;
             material_file << "]" << std::endl;
             mat_prop.clear();
           }
         }
         first_mat = false;
       } else {
         sstr_material.clear();
       }
 
       std::string prop_name;
       sstr_material >> prop_name;
 
       std::map<std::string, std::string>::iterator it;
       it = _diana_to_akantu_mat_prop.find(prop_name);
 
       if (it != _diana_to_akantu_mat_prop.end()) {
         Real value;
         sstr_material >> value;
         mat_prop[it->second] = value;
       } else {
         AKANTU_DEBUG_INFO("In material reader, property " << prop_name
                                                           << "not recognized");
       }
     }
   } while (!end);
 
   AKANTU_DEBUG_OUT();
   return line;
 }
 
 /* -------------------------------------------------------------------------- */
 
 } // namespace akantu
diff --git a/src/io/mesh_io/mesh_io_diana.hh b/src/io/mesh_io/mesh_io_diana.hh
index a5bde0911..fde134690 100644
--- a/src/io/mesh_io/mesh_io_diana.hh
+++ b/src/io/mesh_io/mesh_io_diana.hh
@@ -1,109 +1,108 @@
 /**
  * @file   mesh_io_diana.hh
  *
  * @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
  * @author David Simon Kammer <david.kammer@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  * @author Alodie Schneuwly <alodie.schneuwly@epfl.ch>
  *
  * @date creation: Fri Jun 18 2010
- * @date last modification: Thu Nov 19 2015
+ * @date last modification: Wed Nov 08 2017
  *
  * @brief  diana mesh reader description
  *
  * @section LICENSE
  *
- * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
- * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
- * Solides)
+ * 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
+ * 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
+ * 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_MESH_IO_DIANA_HH__
 #define __AKANTU_MESH_IO_DIANA_HH__
 
 /* -------------------------------------------------------------------------- */
 #include "mesh_io.hh"
 
 /* -------------------------------------------------------------------------- */
 #include <vector>
 
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 
 class MeshIODiana : public MeshIO {
   /* ------------------------------------------------------------------------ */
   /* Constructors/Destructors                                                 */
   /* ------------------------------------------------------------------------ */
 public:
   MeshIODiana();
   ~MeshIODiana() override;
 
   /* ------------------------------------------------------------------------ */
   /* Methods                                                                  */
   /* ------------------------------------------------------------------------ */
 public:
   /// read a mesh from the file
   void read(const std::string & filename, Mesh & mesh) override;
 
   /// write a mesh to a file
   void write(const std::string & filename, const Mesh & mesh) override;
 
 private:
   std::string readCoordinates(std::ifstream & infile, Mesh & mesh,
                               UInt & first_node_number);
 
   std::string readElements(std::ifstream & infile, Mesh & mesh,
                            UInt first_node_number);
 
   std::string readGroups(std::ifstream & infile, Mesh & mesh,
                          UInt first_node_number);
 
   std::string readConnectivity(std::ifstream & infile, Mesh & mesh,
                                UInt first_node_number);
 
   std::string readMaterialElement(std::ifstream & infile, Mesh & mesh);
 
   std::string readMaterial(std::ifstream & infile,
                            const std::string & filename);
 
   UInt readInterval(std::stringstream & line, std::set<UInt> & interval);
 
   /* ------------------------------------------------------------------------ */
   /* Accessors                                                                */
   /* ------------------------------------------------------------------------ */
 public:
   /* ------------------------------------------------------------------------ */
   /* Class Members                                                            */
   /* ------------------------------------------------------------------------ */
 private:
   std::map<std::string, ElementType> _diana_to_akantu_element_types;
   std::map<std::string, std::string> _diana_to_akantu_mat_prop;
 
   /// order in witch element as to be read, akantu_node_order =
   /// _read_order[diana_node_order]
   std::map<ElementType, UInt *> _read_order;
 
   std::map<UInt, Element> diana_element_number_to_elements;
   std::map<Element, UInt> akantu_number_to_diana_number;
 };
 
 } // akantu
 
 #endif /* __AKANTU_MESH_IO_DIANA_HH__ */
diff --git a/src/io/mesh_io/mesh_io_msh.cc b/src/io/mesh_io/mesh_io_msh.cc
index 2f160815c..1e50bdaa5 100644
--- a/src/io/mesh_io/mesh_io_msh.cc
+++ b/src/io/mesh_io/mesh_io_msh.cc
@@ -1,972 +1,971 @@
 /**
  * @file   mesh_io_msh.cc
  *
  * @author Dana Christen <dana.christen@gmail.com>
  * @author Mauro Corrado <mauro.corrado@epfl.ch>
  * @author David Simon Kammer <david.kammer@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Fri Jun 18 2010
- * @date last modification: Thu Jan 21 2016
+ * @date last modification: Tue Feb 20 2018
  *
  * @brief  Read/Write for MSH files generated by gmsh
  *
  * @section LICENSE
  *
- * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
- * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
- * Solides)
+ * 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
+ * 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
+ * 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/>.
  *
  */
 
 /* -----------------------------------------------------------------------------
    Version (Legacy) 1.0
 
    $NOD
    number-of-nodes
    node-number x-coord y-coord z-coord
    ...
    $ENDNOD
    $ELM
    number-of-elements
    elm-number elm-type reg-phys reg-elem number-of-nodes node-number-list
    ...
    $ENDELM
    -----------------------------------------------------------------------------
    Version 2.1
 
    $MeshFormat
    version-number file-type data-size
    $EndMeshFormat
    $Nodes
    number-of-nodes
    node-number x-coord y-coord z-coord
    ...
    $EndNodes
    $Elements
    number-of-elements
    elm-number elm-type number-of-tags < tag > ... node-number-list
    ...
    $EndElements
    $PhysicalNames
    number-of-names
    physical-dimension physical-number "physical-name"
    ...
    $EndPhysicalNames
    $NodeData
    number-of-string-tags
    < "string-tag" >
    ...
    number-of-real-tags
    < real-tag >
    ...
    number-of-integer-tags
    < integer-tag >
    ...
    node-number value ...
    ...
    $EndNodeData
    $ElementData
    number-of-string-tags
    < "string-tag" >
    ...
    number-of-real-tags
    < real-tag >
    ...
    number-of-integer-tags
    < integer-tag >
    ...
    elm-number value ...
    ...
    $EndElementData
    $ElementNodeData
    number-of-string-tags
    < "string-tag" >
    ...
    number-of-real-tags
    < real-tag >
    ...
    number-of-integer-tags
    < integer-tag >
    ...
    elm-number number-of-nodes-per-element value ...
    ...
    $ElementEndNodeData
 
    -----------------------------------------------------------------------------
    elem-type
 
    1:  2-node line.
    2:  3-node triangle.
    3:  4-node quadrangle.
    4:  4-node tetrahedron.
    5:  8-node hexahedron.
    6:  6-node prism.
    7:  5-node pyramid.
    8:  3-node second order line
    9:  6-node second order triangle
    10: 9-node second order quadrangle
    11: 10-node second order tetrahedron
    12: 27-node second order hexahedron
    13: 18-node second order prism
    14: 14-node second order pyramid
    15: 1-node point.
    16: 8-node second order quadrangle
    17: 20-node second order hexahedron
    18: 15-node second order prism
    19: 13-node second order pyramid
    20: 9-node third order incomplete triangle
    21: 10-node third order triangle
    22: 12-node fourth order incomplete triangle
    23: 15-node fourth order triangle
    24: 15-node fifth order incomplete triangle
    25: 21-node fifth order complete triangle
    26: 4-node third order edge
    27: 5-node fourth order edge
    28: 6-node fifth order edge
    29: 20-node third order tetrahedron
    30: 35-node fourth order tetrahedron
    31: 56-node fifth order tetrahedron
    -------------------------------------------------------------------------- */
 
 /* -------------------------------------------------------------------------- */
 #include <fstream>
 
 /* -------------------------------------------------------------------------- */
 #include "mesh_io.hh"
 #include "mesh_utils.hh"
 /* -------------------------------------------------------------------------- */
 
 /* -------------------------------------------------------------------------- */
 // The boost spirit is a work on the way it does not compile so I kept the
 // current code. The current code does not handle files generated on Windows
 // <CRLF>
 
 // #include <boost/config/warning_disable.hpp>
 // #include <boost/spirit/include/qi.hpp>
 // #include <boost/spirit/include/phoenix_core.hpp>
 // #include <boost/spirit/include/phoenix_fusion.hpp>
 // #include <boost/spirit/include/phoenix_object.hpp>
 // #include <boost/spirit/include/phoenix_container.hpp>
 // #include <boost/spirit/include/phoenix_operator.hpp>
 // #include <boost/spirit/include/phoenix_bind.hpp>
 // #include <boost/spirit/include/phoenix_stl.hpp>
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 /*   Methods Implentations                                                    */
 /* -------------------------------------------------------------------------- */
 MeshIOMSH::MeshIOMSH() {
   canReadSurface = true;
   canReadExtendedData = true;
 
   _msh_nodes_per_elem[_msh_not_defined] = 0;
   _msh_nodes_per_elem[_msh_segment_2] = 2;
   _msh_nodes_per_elem[_msh_triangle_3] = 3;
   _msh_nodes_per_elem[_msh_quadrangle_4] = 4;
   _msh_nodes_per_elem[_msh_tetrahedron_4] = 4;
   _msh_nodes_per_elem[_msh_hexahedron_8] = 8;
   _msh_nodes_per_elem[_msh_prism_1] = 6;
   _msh_nodes_per_elem[_msh_pyramid_1] = 1;
   _msh_nodes_per_elem[_msh_segment_3] = 3;
   _msh_nodes_per_elem[_msh_triangle_6] = 6;
   _msh_nodes_per_elem[_msh_quadrangle_9] = 9;
   _msh_nodes_per_elem[_msh_tetrahedron_10] = 10;
   _msh_nodes_per_elem[_msh_hexahedron_27] = 27;
   _msh_nodes_per_elem[_msh_hexahedron_20] = 20;
   _msh_nodes_per_elem[_msh_prism_18] = 18;
   _msh_nodes_per_elem[_msh_prism_15] = 15;
   _msh_nodes_per_elem[_msh_pyramid_14] = 14;
   _msh_nodes_per_elem[_msh_point] = 1;
   _msh_nodes_per_elem[_msh_quadrangle_8] = 8;
 
   _msh_to_akantu_element_types[_msh_not_defined] = _not_defined;
   _msh_to_akantu_element_types[_msh_segment_2] = _segment_2;
   _msh_to_akantu_element_types[_msh_triangle_3] = _triangle_3;
   _msh_to_akantu_element_types[_msh_quadrangle_4] = _quadrangle_4;
   _msh_to_akantu_element_types[_msh_tetrahedron_4] = _tetrahedron_4;
   _msh_to_akantu_element_types[_msh_hexahedron_8] = _hexahedron_8;
   _msh_to_akantu_element_types[_msh_prism_1] = _pentahedron_6;
   _msh_to_akantu_element_types[_msh_pyramid_1] = _not_defined;
   _msh_to_akantu_element_types[_msh_segment_3] = _segment_3;
   _msh_to_akantu_element_types[_msh_triangle_6] = _triangle_6;
   _msh_to_akantu_element_types[_msh_quadrangle_9] = _not_defined;
   _msh_to_akantu_element_types[_msh_tetrahedron_10] = _tetrahedron_10;
   _msh_to_akantu_element_types[_msh_hexahedron_27] = _not_defined;
   _msh_to_akantu_element_types[_msh_hexahedron_20] = _hexahedron_20;
   _msh_to_akantu_element_types[_msh_prism_18] = _not_defined;
   _msh_to_akantu_element_types[_msh_prism_15] = _pentahedron_15;
   _msh_to_akantu_element_types[_msh_pyramid_14] = _not_defined;
   _msh_to_akantu_element_types[_msh_point] = _point_1;
   _msh_to_akantu_element_types[_msh_quadrangle_8] = _quadrangle_8;
 
   _akantu_to_msh_element_types[_not_defined] = _msh_not_defined;
   _akantu_to_msh_element_types[_segment_2] = _msh_segment_2;
   _akantu_to_msh_element_types[_segment_3] = _msh_segment_3;
   _akantu_to_msh_element_types[_triangle_3] = _msh_triangle_3;
   _akantu_to_msh_element_types[_triangle_6] = _msh_triangle_6;
   _akantu_to_msh_element_types[_tetrahedron_4] = _msh_tetrahedron_4;
   _akantu_to_msh_element_types[_tetrahedron_10] = _msh_tetrahedron_10;
   _akantu_to_msh_element_types[_quadrangle_4] = _msh_quadrangle_4;
   _akantu_to_msh_element_types[_quadrangle_8] = _msh_quadrangle_8;
   _akantu_to_msh_element_types[_hexahedron_8] = _msh_hexahedron_8;
   _akantu_to_msh_element_types[_hexahedron_20] = _msh_hexahedron_20;
   _akantu_to_msh_element_types[_pentahedron_6] = _msh_prism_1;
   _akantu_to_msh_element_types[_pentahedron_15] = _msh_prism_15;
   _akantu_to_msh_element_types[_point_1] = _msh_point;
 
 #if defined(AKANTU_STRUCTURAL_MECHANICS)
   _akantu_to_msh_element_types[_bernoulli_beam_2] = _msh_segment_2;
   _akantu_to_msh_element_types[_bernoulli_beam_3] = _msh_segment_2;
   _akantu_to_msh_element_types[_discrete_kirchhoff_triangle_18] =
       _msh_triangle_3;
 #endif
 
   std::map<ElementType, MSHElementType>::iterator it;
   for (it = _akantu_to_msh_element_types.begin();
        it != _akantu_to_msh_element_types.end(); ++it) {
     UInt nb_nodes = _msh_nodes_per_elem[it->second];
 
     std::vector<UInt> tmp(nb_nodes);
     for (UInt i = 0; i < nb_nodes; ++i) {
       tmp[i] = i;
     }
 
     switch (it->first) {
     case _tetrahedron_10:
       tmp[8] = 9;
       tmp[9] = 8;
       break;
     case _pentahedron_6:
       tmp[0] = 2;
       tmp[1] = 0;
       tmp[2] = 1;
       tmp[3] = 5;
       tmp[4] = 3;
       tmp[5] = 4;
       break;
     case _pentahedron_15:
       tmp[0] = 2;
       tmp[1] = 0;
       tmp[2] = 1;
       tmp[3] = 5;
       tmp[4] = 3;
       tmp[5] = 4;
       tmp[6] = 8;
       tmp[8] = 11;
       tmp[9] = 6;
       tmp[10] = 9;
       tmp[11] = 10;
       tmp[12] = 14;
       tmp[14] = 12;
       break;
     case _hexahedron_20:
       tmp[9] = 11;
       tmp[10] = 12;
       tmp[11] = 9;
       tmp[12] = 13;
       tmp[13] = 10;
       tmp[17] = 19;
       tmp[18] = 17;
       tmp[19] = 18;
       break;
     default:
       // nothing to change
       break;
     }
     _read_order[it->first] = tmp;
   }
 }
 
 /* -------------------------------------------------------------------------- */
 MeshIOMSH::~MeshIOMSH() = default;
 
 /* -------------------------------------------------------------------------- */
 /* Spirit stuff                                                               */
 /* -------------------------------------------------------------------------- */
 // namespace _parser {
 //   namespace spirit  = ::boost::spirit;
 //   namespace qi      = ::boost::spirit::qi;
 //   namespace ascii   = ::boost::spirit::ascii;
 //   namespace lbs     = ::boost::spirit::qi::labels;
 //   namespace phx     = ::boost::phoenix;
 
 //   /* ------------------------------------------------------------------------
 //   */
 //   /* Lazy functors */
 //   /* ------------------------------------------------------------------------
 //   */
 //   struct _Element {
 //     int index;
 //     std::vector<int> tags;
 //     std::vector<int> connectivity;
 //     ElementType type;
 //   };
 
 //   /* ------------------------------------------------------------------------
 //   */
 //   struct lazy_get_nb_nodes_ {
 //     template <class elem_type> struct result { typedef int type; };
 //     template <class elem_type> bool operator()(elem_type et) {
 //       return MeshIOMSH::_msh_nodes_per_elem[et];
 //     }
 //   };
 
 //   /* ------------------------------------------------------------------------
 //   */
 //   struct lazy_element_ {
 //     template <class id_t, class tags_t, class elem_type, class conn_t>
 //     struct result {
 //       typedef _Element type;
 //     };
 //     template <class id_t, class tags_t, class elem_type, class conn_t>
 //     _Element operator()(id_t id, const elem_type & et, const tags_t & t,
 //                        const conn_t & c) {
 //       _Element tmp_el;
 //       tmp_el.index = id;
 //       tmp_el.tags = t;
 //       tmp_el.connectivity = c;
 //       tmp_el.type = et;
 //       return tmp_el;
 //     }
 //   };
 
 //   /* ------------------------------------------------------------------------
 //   */
 //   struct lazy_check_value_ {
 //     template <class T> struct result { typedef void type; };
 //     template <class T> void operator()(T v1, T v2) {
 //       if (v1 != v2) {
 //         AKANTU_EXCEPTION("The msh parser expected a "
 //                          << v2 << " in the header bug got a " << v1);
 //       }
 //     }
 //   };
 
 //   /* ------------------------------------------------------------------------
 //   */
 //   struct lazy_node_read_ {
 //     template <class Mesh, class ID, class V, class size, class Map>
 //     struct result {
 //       typedef bool type;
 //     };
 //     template <class Mesh, class ID, class V, class size, class Map>
 //     bool operator()(Mesh & mesh, const ID & id, const V & pos, size max,
 //                     Map & nodes_mapping) const {
 //       Vector<Real> tmp_pos(mesh.getSpatialDimension());
 //       UInt i = 0;
 //       for (typename V::const_iterator it = pos.begin();
 //            it != pos.end() || i < mesh.getSpatialDimension(); ++it)
 //         tmp_pos[i++] = *it;
 
 //       nodes_mapping[id] = mesh.getNbNodes();
 //       mesh.getNodes().push_back(tmp_pos);
 //       return (mesh.getNbNodes() < UInt(max));
 //     }
 //   };
 
 //   /* ------------------------------------------------------------------------
 //   */
 //   struct lazy_element_read_ {
 //     template <class Mesh, class EL, class size, class NodeMap, class ElemMap>
 //     struct result {
 //       typedef bool type;
 //     };
 
 //     template <class Mesh, class EL, class size, class NodeMap, class ElemMap>
 //     bool operator()(Mesh & mesh, const EL & element, size max,
 //                     const NodeMap & nodes_mapping,
 //                     ElemMap & elements_mapping) const {
 //       Vector<UInt> tmp_conn(Mesh::getNbNodesPerElement(element.type));
 
 //       AKANTU_DEBUG_ASSERT(element.connectivity.size() == tmp_conn.size(),
 //                           "The element "
 //                               << element.index
 //                               << "in the MSH file has too many nodes.");
 
 //       mesh.addConnectivityType(element.type);
 //       Array<UInt> & connectivity = mesh.getConnectivity(element.type);
 
 //       UInt i = 0;
 //       for (std::vector<int>::const_iterator it =
 //       element.connectivity.begin();
 //            it != element.connectivity.end(); ++it) {
 //         typename NodeMap::const_iterator nit = nodes_mapping.find(*it);
 //         AKANTU_DEBUG_ASSERT(nit != nodes_mapping.end(),
 //                             "There is an unknown node in the connectivity.");
 //         tmp_conn[i++] = nit->second;
 //       }
 
 //       ::akantu::Element el(element.type, connectivity.size());
 //       elements_mapping[element.index] = el;
 
 //       connectivity.push_back(tmp_conn);
 
 //       for (UInt i = 0; i < element.tags.size(); ++i) {
 //         std::stringstream tag_sstr;
 //         tag_sstr << "tag_" << i;
 //         Array<UInt> * data =
 //             mesh.template getDataPointer<UInt>(tag_sstr.str(), element.type,
 //             _not_ghost);
 //         data->push_back(element.tags[i]);
 //       }
 
 //       return (mesh.getNbElement() < UInt(max));
 //     }
 //   };
 
 //   /* ------------------------------------------------------------------------
 //   */
 //   template <class Iterator, typename Skipper = ascii::space_type>
 //   struct MshMeshGrammar : qi::grammar<Iterator, void(), Skipper> {
 //   public:
 //     MshMeshGrammar(Mesh & mesh)
 //         : MshMeshGrammar::base_type(start, "msh_mesh_reader"), mesh(mesh) {
 //       phx::function<lazy_element_> lazy_element;
 //       phx::function<lazy_get_nb_nodes_> lazy_get_nb_nodes;
 //       phx::function<lazy_check_value_> lazy_check_value;
 //       phx::function<lazy_node_read_> lazy_node_read;
 //       phx::function<lazy_element_read_> lazy_element_read;
 
 // clang-format off
 
 //       start
 //         =  *( known_section | unknown_section
 //             )
 //        ;
 
 //       known_section
 //         =  qi::char_("$")
 //            >> sections            [ lbs::_a = lbs::_1 ]
 //            >> qi::lazy(*lbs::_a)
 //            >> qi::lit("$End")
 //           //>> qi::lit(phx::ref(lbs::_a))
 //         ;
 
 //       unknown_section
 //         =  qi::char_("$")
 //            >> qi::char_("")     [ lbs::_a = lbs::_1 ]
 //            >> ignore_section
 //            >> qi::lit("$End")
 //            >> qi::lit(phx::val(lbs::_a))
 //         ;
 
 //       mesh_format // version followed by 0 or 1 for ascii or binary
 //         =  version >> (
 //                         ( qi::char_("0")
 //                           >> qi::int_       [ lazy_check_value(lbs::_1, 8) ]
 //                         )
 //                         | ( qi::char_("1")
 //                             >> qi::int_     [ lazy_check_value(lbs::_1, 8) ]
 //                             >> qi::dword    [ lazy_check_value(lbs::_1, 1) ]
 //                           )
 //                         )
 //         ;
 
 //       nodes
 //         =  nodes_
 //         ;
 
 //       nodes_
 //         =  qi::int_                      [ lbs::_a = lbs::_1 ]
 //            > *(
 //                 ( qi::int_ >> position ) [ lazy_node_read(phx::ref(mesh),
 //                                                           lbs::_1,
 //                                                           phx::cref(lbs::_2),
 //                                                           lbs::_a,
 //                                                           phx::ref(this->msh_nodes_to_akantu)) ]
 //               )
 //         ;
 
 //       element
 //         =  elements_
 //         ;
 
 //       elements_
 //         =  qi::int_                                 [ lbs::_a = lbs::_1 ]
 //            > qi::repeat(phx::ref(lbs::_a))[ element [ lazy_element_read(phx::ref(mesh),
 //                                                                         lbs::_1,
 //                                                                         phx::cref(lbs::_a),
 //                                                                         phx::cref(this->msh_nodes_to_akantu),
 //                                                                         phx::ref(this->msh_elemt_to_akantu)) ]]
 //         ;
 
 //       ignore_section
 //         =  *(qi::char_ - qi::char_('$'))
 //         ;
 
 //       interpolation_scheme = ignore_section;
 //       element_data         = ignore_section;
 //       node_data            = ignore_section;
 
 //       version
 //         =  qi::int_                         [ phx::push_back(lbs::_val, lbs::_1) ]
 //            >> *( qi::char_(".") >> qi::int_ [ phx::push_back(lbs::_val, lbs::_1) ] )
 //         ;
 
 //       position
 //         =  real   [ phx::push_back(lbs::_val, lbs::_1) ]
 //            > real [ phx::push_back(lbs::_val, lbs::_1) ]
 //            > real [ phx::push_back(lbs::_val, lbs::_1) ]
 //         ;
 
 //       tags
 //         =  qi::int_      [ lbs::_a = lbs::_1 ]
 //           > qi::repeat(phx::val(lbs::_a))[ qi::int_ [ phx::push_back(lbs::_val,
 //                                                                      lbs::_1) ] ]
 //         ;
 
 //       element
 //         =  ( qi::int_                [ lbs::_a = lbs::_1 ]
 //              > msh_element_type      [ lbs::_b = lazy_get_nb_nodes(lbs::_1) ]
 //              > tags                  [ lbs::_c = lbs::_1 ]
 //              > connectivity(lbs::_a) [ lbs::_d = lbs::_1 ]
 //            )                         [ lbs::_val = lazy_element(lbs::_a,
 //                                                                 phx::cref(lbs::_b),
 //                                                                 phx::cref(lbs::_c),
 //                                                                 phx::cref(lbs::_d)) ]
 //         ;
 //       connectivity
 //         =  qi::repeat(lbs::_r1)[ qi::int_ [ phx::push_back(lbs::_val,
 //                                                            lbs::_1) ] ]
 //         ;
 
 //       sections.add
 //           ("MeshFormat", &mesh_format)
 //           ("Nodes", &nodes)
 //           ("Elements", &elements)
 //           ("PhysicalNames", &physical_names)
 //           ("InterpolationScheme", &interpolation_scheme)
 //           ("ElementData", &element_data)
 //           ("NodeData", &node_data);
 
 //       msh_element_type.add
 //           ("0" , _not_defined   )
 //           ("1" , _segment_2     )
 //           ("2" , _triangle_3    )
 //           ("3" , _quadrangle_4  )
 //           ("4" , _tetrahedron_4 )
 //           ("5" , _hexahedron_8  )
 //           ("6" , _pentahedron_6 )
 //           ("7" , _not_defined   )
 //           ("8" , _segment_3     )
 //           ("9" , _triangle_6    )
 //           ("10", _not_defined   )
 //           ("11", _tetrahedron_10)
 //           ("12", _not_defined   )
 //           ("13", _not_defined   )
 //           ("14", _hexahedron_20 )
 //           ("15", _pentahedron_15)
 //           ("16", _not_defined   )
 //           ("17", _point_1       )
 //           ("18", _quadrangle_8  );
 
 //       mesh_format         .name("MeshFormat"         );
 //       nodes               .name("Nodes"              );
 //       elements            .name("Elements"           );
 //       physical_names      .name("PhysicalNames"      );
 //       interpolation_scheme.name("InterpolationScheme");
 //       element_data        .name("ElementData"        );
 //       node_data           .name("NodeData"           );
 
 // clang-format on
 //     }
 
 //     /* ----------------------------------------------------------------------
 //     */
 //     /* Rules */
 //     /* ----------------------------------------------------------------------
 //     */
 //   private:
 //     qi::symbols<char, ElementType> msh_element_type;
 //     qi::symbols<char, qi::rule<Iterator, void(), Skipper> *> sections;
 //     qi::rule<Iterator, void(), Skipper> start;
 //     qi::rule<Iterator, void(), Skipper, qi::locals<std::string> >
 //     unknown_section;
 //     qi::rule<Iterator, void(), Skipper, qi::locals<qi::rule<Iterator,
 //     Skipper> *> > known_section;
 //     qi::rule<Iterator, void(), Skipper> mesh_format, nodes, elements,
 //     physical_names, ignore_section,
 //         interpolation_scheme, element_data, node_data, any_line;
 //     qi::rule<Iterator, void(), Skipper, qi::locals<int> > nodes_;
 //     qi::rule<Iterator, void(), Skipper, qi::locals< int, int, vector<int>,
 //     vector<int> > > elements_;
 
 //     qi::rule<Iterator, std::vector<int>(), Skipper> version;
 //     qi::rule<Iterator, _Element(), Skipper, qi::locals<ElementType> >
 //     element;
 //     qi::rule<Iterator, std::vector<int>(), Skipper, qi::locals<int> > tags;
 //     qi::rule<Iterator, std::vector<int>(int), Skipper> connectivity;
 //     qi::rule<Iterator, std::vector<Real>(), Skipper> position;
 
 //     qi::real_parser<Real, qi::real_policies<Real> > real;
 
 //     /* ----------------------------------------------------------------------
 //     */
 //     /* Members */
 //     /* ----------------------------------------------------------------------
 //     */
 //   private:
 //     /// reference to the mesh to read
 //     Mesh & mesh;
 
 //     /// correspondance between the numbering of nodes in the abaqus file and
 //     in
 //     /// the akantu mesh
 //     std::map<UInt, UInt> msh_nodes_to_akantu;
 
 //     /// correspondance between the element number in the abaqus file and the
 //     /// Element in the akantu mesh
 //     std::map<UInt, Element> msh_elemt_to_akantu;
 //   };
 // }
 
 // /* --------------------------------------------------------------------------
 // */
 // void MeshIOAbaqus::read(const std::string& filename, Mesh& mesh) {
 //   namespace qi      = boost::spirit::qi;
 //   namespace ascii   = boost::spirit::ascii;
 
 //   std::ifstream infile;
 //   infile.open(filename.c_str());
 
 //   if(!infile.good()) {
 //     AKANTU_ERROR("Cannot open file " << filename);
 //   }
 
 //   std::string storage; // We will read the contents here.
 //   infile.unsetf(std::ios::skipws); // No white space skipping!
 //   std::copy(std::istream_iterator<char>(infile),
 //             std::istream_iterator<char>(),
 //             std::back_inserter(storage));
 
 //   typedef std::string::const_iterator iterator_t;
 //   typedef ascii::space_type skipper;
 //   typedef _parser::MshMeshGrammar<iterator_t, skipper> grammar;
 
 //   grammar g(mesh);
 //   skipper ws;
 
 //   iterator_t iter = storage.begin();
 //   iterator_t end  = storage.end();
 
 //   qi::phrase_parse(iter, end, g, ws);
 
 //   this->setNbGlobalNodes(mesh, mesh.getNodes().size());
 //   MeshUtils::fillElementToSubElementsData(mesh);
 // }
 
 static void my_getline(std::ifstream & infile, std::string & str) {
   std::string tmp_str;
   std::getline(infile, tmp_str);
   str = trim(tmp_str);
 }
 
 /* -------------------------------------------------------------------------- */
 void MeshIOMSH::read(const std::string & filename, Mesh & mesh) {
 
   MeshAccessor mesh_accessor(mesh);
 
   std::ifstream infile;
   infile.open(filename.c_str());
 
   std::string line;
   UInt first_node_number = std::numeric_limits<UInt>::max(),
        last_node_number = 0, file_format = 1, current_line = 0;
   bool has_physical_names = false;
 
   if (!infile.good()) {
     AKANTU_EXCEPTION("Cannot open file " << filename);
   }
 
   while (infile.good()) {
     my_getline(infile, line);
     current_line++;
 
     /// read the header
     if (line == "$MeshFormat") {
       my_getline(infile, line); /// the format line
       std::stringstream sstr(line);
       std::string version;
       sstr >> version;
       Int format;
       sstr >> format;
       if (format != 0)
         AKANTU_ERROR("This reader can only read ASCII files.");
       my_getline(infile, line); /// the end of block line
       current_line += 2;
       file_format = 2;
     }
 
     /// read the physical names
     if (line == "$PhysicalNames") {
       has_physical_names = true;
       my_getline(infile, line); /// the format line
       std::stringstream sstr(line);
 
       UInt num_of_phys_names;
       sstr >> num_of_phys_names;
 
       for (UInt k(0); k < num_of_phys_names; k++) {
         my_getline(infile, line);
         std::stringstream sstr_phys_name(line);
         UInt phys_name_id;
         UInt phys_dim;
 
         sstr_phys_name >> phys_dim >> phys_name_id;
 
         std::size_t b = line.find('\"');
         std::size_t e = line.rfind('\"');
         std::string phys_name = line.substr(b + 1, e - b - 1);
 
         phys_name_map[phys_name_id] = phys_name;
       }
     }
 
     /// read all nodes
     if (line == "$Nodes" || line == "$NOD") {
       UInt nb_nodes;
 
       my_getline(infile, line);
       std::stringstream sstr(line);
       sstr >> nb_nodes;
       current_line++;
 
       Array<Real> & nodes = mesh_accessor.getNodes();
       nodes.resize(nb_nodes);
       mesh_accessor.setNbGlobalNodes(nb_nodes);
 
       UInt index;
       Real coord[3];
       UInt spatial_dimension = nodes.getNbComponent();
       /// for each node, read the coordinates
       for (UInt i = 0; i < nb_nodes; ++i) {
         UInt offset = i * spatial_dimension;
 
         my_getline(infile, line);
         std::stringstream sstr_node(line);
         sstr_node >> index >> coord[0] >> coord[1] >> coord[2];
         current_line++;
 
         first_node_number = std::min(first_node_number, index);
         last_node_number = std::max(last_node_number, index);
 
         /// read the coordinates
         for (UInt j = 0; j < spatial_dimension; ++j)
           nodes.storage()[offset + j] = coord[j];
       }
       my_getline(infile, line); /// the end of block line
     }
 
     /// read all elements
     if (line == "$Elements" || line == "$ELM") {
       UInt nb_elements;
 
       std::vector<UInt> read_order;
 
       my_getline(infile, line);
       std::stringstream sstr(line);
       sstr >> nb_elements;
       current_line++;
 
       Int index;
       UInt msh_type;
       ElementType akantu_type, akantu_type_old = _not_defined;
       Array<UInt> * connectivity = nullptr;
       UInt node_per_element = 0;
 
       for (UInt i = 0; i < nb_elements; ++i) {
         my_getline(infile, line);
         std::stringstream sstr_elem(line);
         current_line++;
 
         sstr_elem >> index;
         sstr_elem >> msh_type;
 
         /// get the connectivity vector depending on the element type
         akantu_type =
             this->_msh_to_akantu_element_types[(MSHElementType)msh_type];
 
         if (akantu_type == _not_defined) {
           AKANTU_DEBUG_WARNING("Unsuported element kind "
                                << msh_type << " at line " << current_line);
           continue;
         }
 
         if (akantu_type != akantu_type_old) {
           connectivity = &mesh_accessor.getConnectivity(akantu_type);
           //          connectivity->resize(0);
 
           node_per_element = connectivity->getNbComponent();
           akantu_type_old = akantu_type;
           read_order = this->_read_order[akantu_type];
         }
 
         /// read tags informations
         if (file_format == 2) {
           UInt nb_tags;
           sstr_elem >> nb_tags;
           for (UInt j = 0; j < nb_tags; ++j) {
             Int tag;
             sstr_elem >> tag;
             std::stringstream sstr_tag_name;
             sstr_tag_name << "tag_" << j;
             Array<UInt> & data = mesh.getDataPointer<UInt>(
                 sstr_tag_name.str(), akantu_type, _not_ghost);
             data.push_back(tag);
           }
         } else if (file_format == 1) {
           Int tag;
           sstr_elem >> tag; // reg-phys
           std::string tag_name = "tag_0";
           Array<UInt> * data =
               &mesh.getDataPointer<UInt>(tag_name, akantu_type, _not_ghost);
           data->push_back(tag);
 
           sstr_elem >> tag; // reg-elem
           tag_name = "tag_1";
           data = &mesh.getDataPointer<UInt>(tag_name, akantu_type, _not_ghost);
           data->push_back(tag);
 
           sstr_elem >> tag; // number-of-nodes
         }
 
         Vector<UInt> local_connect(node_per_element);
         for (UInt j = 0; j < node_per_element; ++j) {
           UInt node_index;
           sstr_elem >> node_index;
 
           AKANTU_DEBUG_ASSERT(node_index <= last_node_number,
                               "Node number not in range : line "
                                   << current_line);
 
           node_index -= first_node_number;
           local_connect(read_order[j]) = node_index;
         }
         connectivity->push_back(local_connect);
       }
       my_getline(infile, line); /// the end of block line
     }
 
     if ((line[0] == '$') && (line.find("End") == std::string::npos)) {
       AKANTU_DEBUG_WARNING("Unsuported block_kind " << line << " at line "
                                                     << current_line);
     }
   }
 
   // mesh.updateTypesOffsets(_not_ghost);
 
   infile.close();
 
   this->constructPhysicalNames("tag_0", mesh);
 
   if (has_physical_names)
     mesh.createGroupsFromMeshData<std::string>("physical_names");
 
   MeshUtils::fillElementToSubElementsData(mesh);
 }
 
 /* -------------------------------------------------------------------------- */
 void MeshIOMSH::write(const std::string & filename, const Mesh & mesh) {
   std::ofstream outfile;
   const Array<Real> & nodes = mesh.getNodes();
 
   outfile.open(filename.c_str());
 
   outfile << "$MeshFormat" << std::endl;
   outfile << "2.1 0 8" << std::endl;
   outfile << "$EndMeshFormat" << std::endl;
 
   outfile << std::setprecision(std::numeric_limits<Real>::digits10);
   outfile << "$Nodes" << std::endl;
 
   outfile << nodes.size() << std::endl;
 
   outfile << std::uppercase;
   for (UInt i = 0; i < nodes.size(); ++i) {
     Int offset = i * nodes.getNbComponent();
     outfile << i + 1;
     for (UInt j = 0; j < nodes.getNbComponent(); ++j) {
       outfile << " " << nodes.storage()[offset + j];
     }
 
     for (UInt p = nodes.getNbComponent(); p < 3; ++p)
       outfile << " " << 0.;
     outfile << std::endl;
     ;
   }
   outfile << std::nouppercase;
   outfile << "$EndNodes" << std::endl;
   ;
 
   outfile << "$Elements" << std::endl;
   ;
 
   Int nb_elements = 0;
   for (auto && type :
        mesh.elementTypes(_all_dimensions, _not_ghost, _ek_not_defined)) {
     const Array<UInt> & connectivity = mesh.getConnectivity(type, _not_ghost);
     nb_elements += connectivity.size();
   }
   outfile << nb_elements << std::endl;
 
   UInt element_idx = 1;
   for (auto && type :
        mesh.elementTypes(_all_dimensions, _not_ghost, _ek_not_defined)) {
     const auto & connectivity = mesh.getConnectivity(type, _not_ghost);
 
     UInt * tag[2] = {nullptr, nullptr};
     if (mesh.hasData<UInt>("tag_0", type, _not_ghost)) {
       const auto & data_tag_0 = mesh.getData<UInt>("tag_0", type, _not_ghost);
       tag[0] = data_tag_0.storage();
     }
 
     if (mesh.hasData<UInt>("tag_1", type, _not_ghost)) {
       const auto & data_tag_1 = mesh.getData<UInt>("tag_1", type, _not_ghost);
       tag[1] = data_tag_1.storage();
     }
 
     for (UInt i = 0; i < connectivity.size(); ++i) {
       UInt offset = i * connectivity.getNbComponent();
       outfile << element_idx << " " << _akantu_to_msh_element_types[type]
               << " 2";
 
       /// \todo write the real data in the file
       for (UInt t = 0; t < 2; ++t)
         if (tag[t])
           outfile << " " << tag[t][i];
         else
           outfile << " 0";
 
       for (UInt j = 0; j < connectivity.getNbComponent(); ++j) {
         outfile << " " << connectivity.storage()[offset + j] + 1;
       }
       outfile << std::endl;
       element_idx++;
     }
   }
 
   outfile << "$EndElements" << std::endl;
   ;
 
   outfile.close();
 }
 
 /* -------------------------------------------------------------------------- */
 
 } // namespace akantu
diff --git a/src/io/mesh_io/mesh_io_msh.hh b/src/io/mesh_io/mesh_io_msh.hh
index 70c52f4c4..568f5cca6 100644
--- a/src/io/mesh_io/mesh_io_msh.hh
+++ b/src/io/mesh_io/mesh_io_msh.hh
@@ -1,110 +1,109 @@
 /**
  * @file   mesh_io_msh.hh
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Fri Jun 18 2010
- * @date last modification: Mon Dec 07 2015
+ * @date last modification: Wed Nov 08 2017
  *
  * @brief  Read/Write for MSH files
  *
  * @section LICENSE
  *
- * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
- * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
- * Solides)
+ * 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
+ * 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
+ * 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_MESH_IO_MSH_HH__
 #define __AKANTU_MESH_IO_MSH_HH__
 
 /* -------------------------------------------------------------------------- */
 #include "mesh_io.hh"
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 
 class MeshIOMSH : public MeshIO {
   /* ------------------------------------------------------------------------ */
   /* Constructors/Destructors                                                 */
   /* ------------------------------------------------------------------------ */
 public:
   MeshIOMSH();
 
   ~MeshIOMSH() override;
 
   /* ------------------------------------------------------------------------ */
   /* Methods                                                                  */
   /* ------------------------------------------------------------------------ */
 public:
   /// read a mesh from the file
   void read(const std::string & filename, Mesh & mesh) override;
 
   /// write a mesh to a file
   void write(const std::string & filename, const Mesh & mesh) override;
 
   /* ------------------------------------------------------------------------ */
   /* Accessors                                                                */
   /* ------------------------------------------------------------------------ */
 public:
   /* ------------------------------------------------------------------------ */
   /* Class Members                                                            */
   /* ------------------------------------------------------------------------ */
 protected:
   /// MSH element types
   enum MSHElementType {
     _msh_not_defined = 0,
     _msh_segment_2 = 1,       // 2-node line.
     _msh_triangle_3 = 2,      // 3-node triangle.
     _msh_quadrangle_4 = 3,    // 4-node quadrangle.
     _msh_tetrahedron_4 = 4,   // 4-node tetrahedron.
     _msh_hexahedron_8 = 5,    // 8-node hexahedron.
     _msh_prism_1 = 6,         // 6-node prism.
     _msh_pyramid_1 = 7,       // 5-node pyramid.
     _msh_segment_3 = 8,       // 3-node second order line
     _msh_triangle_6 = 9,      // 6-node second order triangle
     _msh_quadrangle_9 = 10,   // 9-node second order quadrangle
     _msh_tetrahedron_10 = 11, // 10-node second order tetrahedron
     _msh_hexahedron_27 = 12,  // 27-node second order hexahedron
     _msh_prism_18 = 13,       // 18-node second order prism
     _msh_pyramid_14 = 14,     // 14-node second order pyramid
     _msh_point = 15,          // 1-node point.
     _msh_quadrangle_8 = 16,   // 8-node second order quadrangle
     _msh_hexahedron_20 = 17,  // 20-node second order hexahedron
     _msh_prism_15 = 18        // 15-node second order prism
   };
 
 #define MAX_NUMBER_OF_NODE_PER_ELEMENT 10 // tetrahedron of second order
 
   /// order in witch element as to be read
   std::map<ElementType, std::vector<UInt>> _read_order;
 
   /// number of nodes per msh element
   std::map<MSHElementType, UInt> _msh_nodes_per_elem;
 
   /// correspondence between msh element types and akantu element types
   std::map<MSHElementType, ElementType> _msh_to_akantu_element_types;
 
   /// correspondence between akantu element types and msh element types
   std::map<ElementType, MSHElementType> _akantu_to_msh_element_types;
 };
 
 } // akantu
 
 #endif /* __AKANTU_MESH_IO_MSH_HH__ */
diff --git a/src/io/mesh_io/mesh_io_msh_struct.cc b/src/io/mesh_io/mesh_io_msh_struct.cc
index 96f3fbec8..55300ef69 100644
--- a/src/io/mesh_io/mesh_io_msh_struct.cc
+++ b/src/io/mesh_io/mesh_io_msh_struct.cc
@@ -1,80 +1,80 @@
 /**
  * @file   mesh_io_msh_struct.cc
  *
+ * @author Lucas Frerot <lucas.frerot@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Fri Jun 18 2010
- * @date last modification: Mon Dec 07 2015
+ * @date last modification: Fri Jan 26 2018
  *
  * @brief  Read/Write for MSH files generated by gmsh
  *
  * @section LICENSE
  *
- * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
- * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
- * Solides)
+ * 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
+ * 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
+ * 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 "mesh_io_msh_struct.hh"
 /* -------------------------------------------------------------------------- */
 #include <numeric>
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 MeshIOMSHStruct::MeshIOMSHStruct() : MeshIOMSH() {
   canReadSurface = true;
   canReadExtendedData = true;
 
   _msh_to_akantu_element_types.clear();
   _msh_to_akantu_element_types[_msh_not_defined] = _not_defined;
   _msh_to_akantu_element_types[_msh_segment_2] = _bernoulli_beam_2;
   _msh_to_akantu_element_types[_msh_triangle_3] =
       _discrete_kirchhoff_triangle_18;
 
   _akantu_to_msh_element_types.clear();
   _akantu_to_msh_element_types[_not_defined] = _msh_not_defined;
   _akantu_to_msh_element_types[_bernoulli_beam_2] = _msh_segment_2;
   _akantu_to_msh_element_types[_bernoulli_beam_3] = _msh_segment_2;
   _akantu_to_msh_element_types[_discrete_kirchhoff_triangle_18] =
       _msh_triangle_3;
 
   for (auto & kv_pair : _akantu_to_msh_element_types) {
     UInt nb_nodes = _msh_nodes_per_elem[kv_pair.second];
     std::vector<UInt> tmp(nb_nodes);
     std::iota(tmp.begin(), tmp.end(), 0);
     _read_order[kv_pair.first] = tmp;
   }
 }
 
 /* -------------------------------------------------------------------------- */
 void MeshIOMSHStruct::read(const std::string & filename, Mesh & mesh) {
   if (mesh.getSpatialDimension() == 2) {
     _msh_to_akantu_element_types[_msh_segment_2] = _bernoulli_beam_2;
   } else if (mesh.getSpatialDimension() == 3) {
     _msh_to_akantu_element_types[_msh_segment_2] = _bernoulli_beam_3;
     AKANTU_DEBUG_WARNING("The MeshIOMSHStruct is reading bernoulli beam 3D be "
                          "sure to provide the missing normals with the element "
                          "data \"extra_normal\"");
   }
 
   MeshIOMSH::read(filename, mesh);
 }
 
 } // akantu
diff --git a/src/io/mesh_io/mesh_io_msh_struct.hh b/src/io/mesh_io/mesh_io_msh_struct.hh
index b83045ce5..542d65743 100644
--- a/src/io/mesh_io/mesh_io_msh_struct.hh
+++ b/src/io/mesh_io/mesh_io_msh_struct.hh
@@ -1,54 +1,54 @@
 /**
  * @file   mesh_io_msh_struct.hh
  *
+ * @author Lucas Frerot <lucas.frerot@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Fri Jun 18 2010
- * @date last modification: Sun Oct 19 2014
+ * @date last modification: Fri Jan 26 2018
  *
  * @brief  Read/Write for MSH files
  *
  * @section LICENSE
  *
- * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
- * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
- * Solides)
+ * 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
+ * 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
+ * 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_MESH_IO_MSH_STRUCT_HH__
 #define __AKANTU_MESH_IO_MSH_STRUCT_HH__
 /* -------------------------------------------------------------------------- */
 #include "mesh_io.hh"
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 
 class MeshIOMSHStruct : public MeshIOMSH {
   /* ------------------------------------------------------------------------ */
   /* Constructors/Destructors                                                 */
   /* ------------------------------------------------------------------------ */
 public:
   MeshIOMSHStruct();
 
   /// read a mesh from the file
   void read(const std::string & filename, Mesh & mesh) override;
 };
 
 } // akantu
 
 #endif /* __AKANTU_MESH_IO_MSH_STRUCT_HH__ */
diff --git a/src/io/parser/algebraic_parser.hh b/src/io/parser/algebraic_parser.hh
index da97a2380..bfecaeb63 100644
--- a/src/io/parser/algebraic_parser.hh
+++ b/src/io/parser/algebraic_parser.hh
@@ -1,512 +1,512 @@
 /**
  * @file   algebraic_parser.hh
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Wed Nov 13 2013
- * @date last modification: Wed Nov 11 2015
+ * @date last modification: Wed Nov 08 2017
  *
  * @brief  algebraic_parser definition of the grammar
  *
  * @section LICENSE
  *
- * Copyright  (©)  2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de Lausanne)
+ * 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
+ * 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
+ * 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"
 /* -------------------------------------------------------------------------- */
 // Boost
 #include <boost/config/warning_disable.hpp>
 #include <boost/spirit/include/phoenix.hpp>
 #include <boost/spirit/include/qi.hpp>
 /* -------------------------------------------------------------------------- */
 
 #ifndef __AKANTU_ALGEBRAIC_PARSER_HH__
 #define __AKANTU_ALGEBRAIC_PARSER_HH__
 
 namespace spirit = boost::spirit;
 namespace qi = boost::spirit::qi;
 namespace lbs = boost::spirit::qi::labels;
 namespace ascii = boost::spirit::ascii;
 namespace phx = boost::phoenix;
 
 namespace akantu {
 namespace parser {
   struct algebraic_error_handler_ {
     template <typename, typename, typename> struct result {
       using type = void;
     };
 
     template <typename Iterator>
     void operator()(qi::info const & what, Iterator err_pos,
                     Iterator last) const {
       AKANTU_EXCEPTION(
           "Error! Expecting "
           << what // what failed?
           << " here: \""
           << std::string(err_pos, last) // iterators to error-pos, end
           << "\"");
     }
   };
 
   static Real my_min(Real a, Real b) { return std::min(a, b); }
   static Real my_max(Real a, Real b) { return std::max(a, b); }
   static Real my_pow(Real a, Real b) { return std::pow(a, b); }
 
   static Real eval_param(const ID & a, const ParserSection & section) {
     return section.getParameter(a, _ppsc_current_and_parent_scope);
   }
 
   static Real unary_func(Real (*func)(Real), Real a) { return func(a); }
 
   static Real binary_func(Real (*func)(Real, Real), Real a, Real b) {
     return func(a, b);
   }
 
   template <class Iterator, typename Skipper = spirit::unused_type>
   struct AlgebraicGrammar : qi::grammar<Iterator, Real(), Skipper> {
     AlgebraicGrammar(const ParserSection & section)
         : AlgebraicGrammar::base_type(start, "algebraic_grammar"),
           section(section) {
       // phx::function<lazy_pow_>  lazy_pow;
       // phx::function<lazy_unary_func_>  lazy_unary_func;
       // phx::function<lazy_binary_func_> lazy_binary_func;
       // phx::function<lazy_eval_param_> lazy_eval_param;
       /* clang-format off */
       start
         =   expr.alias()
         ;
 
       expr
         =   term                  [ lbs::_val  = lbs::_1 ]
             >> *( ('+' > term     [ lbs::_val += lbs::_1 ])
                 | ('-' > term     [ lbs::_val -= lbs::_1 ])
                 )
         ;
 
       term
         =   factor                [ lbs::_val  = lbs::_1 ]
             >> *( ('*' > factor   [ lbs::_val *= lbs::_1 ])
                 | ('/' > factor   [ lbs::_val /= lbs::_1 ])
                 )
         ;
 
       factor
         =   number                [ lbs::_val = lbs::_1 ]
         >> *("**" > number    [ lbs::_val = phx::bind(&my_pow, lbs::_val, lbs::_1) ])
         ;
 
       number
         =   real                  [ lbs::_val =  lbs::_1 ]
         |   ('-' > number         [ lbs::_val = -lbs::_1 ])
         |   ('+' > number         [ lbs::_val =  lbs::_1 ])
         |   constant              [ lbs::_val =  lbs::_1 ]
         |   function              [ lbs::_val =  lbs::_1 ]
         |   ('(' > expr > ')')    [ lbs::_val =  lbs::_1 ]
         |   variable              [ lbs::_val =  lbs::_1 ]
         ;
 
       function
         =   (qi::no_case[unary_function]
              > '('
              > expr
              > ')')               [ lbs::_val = phx::bind(&unary_func, lbs::_1, lbs::_2) ]
         |   (qi::no_case[binary_function]
              > '(' >> expr
              > ',' >> expr
              > ')')               [ lbs::_val = phx::bind(&binary_func ,lbs::_1, lbs::_2, lbs::_3) ]
         ;
 
       variable
         =   key [ lbs::_val = phx::bind(&eval_param, lbs::_1, section) ]
         ;
 
       key
         =   qi::no_skip[qi::char_("a-zA-Z_") >> *qi::char_("a-zA-Z_0-9")] // coming from the InputFileGrammar
         ;
 
 #ifndef M_PI
 #  define M_PI          3.14159265358979323846
 #endif
 #ifndef M_E
 #  define M_E           2.7182818284590452354
 #endif
       constant.add
         ("pi", M_PI)
         ("e",  M_E);
 
       unary_function.add
         ("abs"   , &std::abs   )
         ("acos"  , &std::acos  )
         ("asin"  , &std::asin  )
         ("atan"  , &std::atan  )
         ("ceil"  , &std::ceil  )
         ("cos"   , &std::cos   )
         ("cosh"  , &std::cosh  )
         ("exp"   , &std::exp   )
         ("floor" , &std::floor )
         ("log10" , &std::log10 )
         ("log"   , &std::log   )
         ("sin"   , &std::sin   )
         ("sinh"  , &std::sinh  )
         ("sqrt"  , &std::sqrt  )
         ("tan"   , &std::tan   )
         ("tanh"  , &std::tanh  )
         ("acosh" , &std::acosh )
         ("asinh" , &std::asinh )
         ("atanh" , &std::atanh )
         ("exp2"  , &std::exp2  )
         ("expm1" , &std::expm1 )
         ("log1p" , &std::log1p )
         ("log2"  , &std::log2  )
         ("erf"   , &std::erf   )
         ("erfc"  , &std::erfc  )
         ("lgamma", &std::lgamma)
         ("tgamma", &std::tgamma)
         ("trunc" , &std::trunc )
         ("round" , &std::round )
         //      ("crbt"  , &std::crbt  )
         ;
 
       binary_function.add
         ("pow"  , &std::pow      )
         ("min"  , &parser::my_min)
         ("max"  , &parser::my_max)
         ("atan2", &std::atan2    )
         ("fmod" , &std::fmod     )
         ("hypot", &std::hypot    )
           ;
 
 #if !defined(AKANTU_NDEBUG)
       phx::function<algebraic_error_handler_> const error_handler = algebraic_error_handler_();
       qi::on_error<qi::fail>(start, error_handler(lbs::_4, lbs::_3, lbs::_2));
 #endif
 
       expr    .name("expression");
       term    .name("term");
       factor  .name("factor");
       number  .name("numerical-value");
       variable.name("variable");
       function.name("function");
 
       constant.name("constants-list");
       unary_function.name("unary-functions-list");
       binary_function.name("binary-functions-list");
 
 #if !defined AKANTU_NDEBUG
       if(AKANTU_DEBUG_TEST(dblDebug)) {
         qi::debug(expr);
         qi::debug(term);
         qi::debug(factor);
         qi::debug(number);
         qi::debug(variable);
         qi::debug(function);
       }
 #endif
     }
     /* clang-format on */
   private:
     qi::rule<Iterator, Real(), Skipper> start;
     qi::rule<Iterator, Real(), Skipper> expr;
     qi::rule<Iterator, Real(), Skipper> term;
     qi::rule<Iterator, Real(), Skipper> factor;
     qi::rule<Iterator, Real(), Skipper> number;
     qi::rule<Iterator, Real(), Skipper> variable;
     qi::rule<Iterator, Real(), Skipper> function;
 
     qi::rule<Iterator, std::string(), Skipper> key;
 
     qi::real_parser<Real, qi::real_policies<Real>> real;
 
     qi::symbols<char, Real> constant;
     qi::symbols<char, Real (*)(Real)> unary_function;
     qi::symbols<char, Real (*)(Real, Real)> binary_function;
 
     const ParserSection & section;
   };
 
   /* ---------------------------------------------------------------------- */
   /* Vector Parser                                                          */
   /* ---------------------------------------------------------------------- */
   struct parsable_vector {
     operator Vector<Real>() {
       Vector<Real> tmp(_cells.size());
       auto it = _cells.begin();
       for (UInt i = 0; it != _cells.end(); ++it, ++i)
         tmp(i) = *it;
       return tmp;
     }
 
     std::vector<Real> _cells;
   };
 
   inline std::ostream & operator<<(std::ostream & stream,
                                    const parsable_vector & pv) {
     stream << "pv[";
     auto it = pv._cells.begin();
     if (it != pv._cells.end()) {
       stream << *it;
       for (++it; it != pv._cells.end(); ++it)
         stream << ", " << *it;
     }
     stream << "]";
     return stream;
   }
 
   struct parsable_matrix {
     operator Matrix<Real>() {
       size_t cols = 0;
       auto it_rows = _cells.begin();
       for (; it_rows != _cells.end(); ++it_rows)
         cols = std::max(cols, it_rows->_cells.size());
 
       Matrix<Real> tmp(_cells.size(), _cells[0]._cells.size(), 0.);
 
       it_rows = _cells.begin();
       for (UInt i = 0; it_rows != _cells.end(); ++it_rows, ++i) {
         auto it_cols = it_rows->_cells.begin();
         for (UInt j = 0; it_cols != it_rows->_cells.end(); ++it_cols, ++j) {
           tmp(i, j) = *it_cols;
         }
       }
       return tmp;
     }
 
     std::vector<parsable_vector> _cells;
   };
 
   inline std::ostream & operator<<(std::ostream & stream,
                                    const parsable_matrix & pm) {
     stream << "pm[";
     auto it = pm._cells.begin();
     if (it != pm._cells.end()) {
       stream << *it;
       for (++it; it != pm._cells.end(); ++it)
         stream << ", " << *it;
     }
     stream << "]";
     return stream;
   }
 
   /* ---------------------------------------------------------------------- */
   template <typename T1, typename T2>
   static void cont_add(T1 & cont, T2 & value) {
     cont._cells.push_back(value);
   }
 
   /* ---------------------------------------------------------------------- */
   template <class Iterator, typename Skipper = spirit::unused_type>
   struct VectorGrammar : qi::grammar<Iterator, parsable_vector(), Skipper> {
     VectorGrammar(const ParserSection & section)
         : VectorGrammar::base_type(start, "vector_algebraic_grammar"),
           number(section) {
 
       start = '[' > vector > ']';
 
       vector =
           (number[phx::bind(&cont_add<parsable_vector, Real>, lbs::_a,
                             lbs::_1)] >>
            *(',' >> number[phx::bind(&cont_add<parsable_vector, Real>, lbs::_a,
                                      lbs::_1)]))[lbs::_val = lbs::_a];
 
 #if !defined(AKANTU_NDEBUG) && defined(AKANTU_CORE_CXX_11)
       phx::function<algebraic_error_handler_> const error_handler =
           algebraic_error_handler_();
       qi::on_error<qi::fail>(start, error_handler(lbs::_4, lbs::_3, lbs::_2));
 #endif
 
       start.name("start");
       vector.name("vector");
       number.name("value");
 
 #if !defined AKANTU_NDEBUG
       if (AKANTU_DEBUG_TEST(dblDebug)) {
         qi::debug(start);
         qi::debug(vector);
       }
 #endif
     }
 
   private:
     qi::rule<Iterator, parsable_vector(), Skipper> start;
     qi::rule<Iterator, parsable_vector(), qi::locals<parsable_vector>, Skipper>
         vector;
     qi::rule<Iterator, Real(), Skipper> value;
     AlgebraicGrammar<Iterator, Skipper> number;
   };
 
   /* ---------------------------------------------------------------------- */
   static inline bool vector_eval(const ID & a, const ParserSection & section,
                                  parsable_vector & result) {
     std::string value = section.getParameter(a, _ppsc_current_and_parent_scope);
     std::string::const_iterator b = value.begin();
     std::string::const_iterator e = value.end();
     parser::VectorGrammar<std::string::const_iterator, qi::space_type> grammar(
         section);
     return qi::phrase_parse(b, e, grammar, qi::space, result);
   }
 
   /* ---------------------------------------------------------------------- */
   template <class Iterator, typename Skipper = spirit::unused_type>
   struct MatrixGrammar : qi::grammar<Iterator, parsable_matrix(), Skipper> {
     MatrixGrammar(const ParserSection & section)
         : MatrixGrammar::base_type(start, "matrix_algebraic_grammar"),
           vector(section) {
 
       start = '[' >> matrix >> ']';
 
       matrix =
           (rows[phx::bind(&cont_add<parsable_matrix, parsable_vector>, lbs::_a,
                           lbs::_1)] >>
            *(',' >> rows[phx::bind(&cont_add<parsable_matrix, parsable_vector>,
                                    lbs::_a, lbs::_1)]))[lbs::_val = lbs::_a];
 
       rows = eval_vector | vector;
 
       eval_vector = (key[lbs::_pass = phx::bind(&vector_eval, lbs::_1, section,
                                                 lbs::_a)])[lbs::_val = lbs::_a];
 
       key = qi::char_("a-zA-Z_") >>
             *qi::char_("a-zA-Z_0-9") // coming from the InputFileGrammar
           ;
 
 #if !defined(AKANTU_NDEBUG) && defined(AKANTU_CORE_CXX_11)
       phx::function<algebraic_error_handler_> const error_handler =
           algebraic_error_handler_();
       qi::on_error<qi::fail>(start, error_handler(lbs::_4, lbs::_3, lbs::_2));
 #endif
 
       start.name("matrix");
       matrix.name("all_rows");
       rows.name("rows");
       vector.name("vector");
       eval_vector.name("eval_vector");
 
 #ifndef AKANTU_NDEBUG
       if (AKANTU_DEBUG_TEST(dblDebug)) {
         qi::debug(start);
         qi::debug(matrix);
         qi::debug(rows);
         qi::debug(eval_vector);
         qi::debug(key);
       }
 #endif
     }
 
   private:
     qi::rule<Iterator, parsable_matrix(), Skipper> start;
     qi::rule<Iterator, parsable_matrix(), qi::locals<parsable_matrix>, Skipper>
         matrix;
     qi::rule<Iterator, parsable_vector(), Skipper> rows;
     qi::rule<Iterator, parsable_vector(), qi::locals<parsable_vector>, Skipper>
         eval_vector;
     qi::rule<Iterator, std::string(), Skipper> key;
     VectorGrammar<Iterator, Skipper> vector;
   };
 
   /* ---------------------------------------------------------------------- */
   /* Randon Generator                                                       */
   /* ---------------------------------------------------------------------- */
   struct ParsableRandomGenerator {
     ParsableRandomGenerator(
         Real base = Real(),
         const RandomDistributionType & type = _rdt_not_defined,
         const parsable_vector & parameters = parsable_vector())
         : base(base), type(type), parameters(parameters) {}
 
     Real base;
     RandomDistributionType type;
     parsable_vector parameters;
   };
 
   inline std::ostream & operator<<(std::ostream & stream,
                                    const ParsableRandomGenerator & prg) {
     stream << "prg[" << prg.base << " " << UInt(prg.type) << " "
            << prg.parameters << "]";
     return stream;
   }
 
   /* ---------------------------------------------------------------------- */
   template <class Iterator, typename Skipper = spirit::unused_type>
   struct RandomGeneratorGrammar
       : qi::grammar<Iterator, ParsableRandomGenerator(), Skipper> {
     RandomGeneratorGrammar(const ParserSection & section)
         : RandomGeneratorGrammar::base_type(start, "random_generator_grammar"),
           number(section) {
 
       start = generator.alias();
 
       generator =
           qi::hold[distribution[lbs::_val = lbs::_1]] |
           number[lbs::_val = phx::construct<ParsableRandomGenerator>(lbs::_1)];
 
       distribution = (number >> generator_type >> '[' >> generator_params >>
                       ']')[lbs::_val = phx::construct<ParsableRandomGenerator>(
                                lbs::_1, lbs::_2, lbs::_3)];
 
       generator_params =
           (number[phx::bind(&cont_add<parsable_vector, Real>, lbs::_a,
                             lbs::_1)] >>
            *(',' > number[phx::bind(&cont_add<parsable_vector, Real>, lbs::_a,
                                     lbs::_1)]))[lbs::_val = lbs::_a];
 
 #define AKANTU_RANDOM_DISTRIBUTION_TYPE_ADD(r, data, elem)                     \
   (BOOST_PP_STRINGIZE(BOOST_PP_TUPLE_ELEM(2, 0, elem)),                        \
    AKANTU_RANDOM_DISTRIBUTION_TYPES_PREFIX(BOOST_PP_TUPLE_ELEM(2, 0, elem)))
 
       generator_type.add BOOST_PP_SEQ_FOR_EACH(
           AKANTU_RANDOM_DISTRIBUTION_TYPE_ADD, _,
           AKANTU_RANDOM_DISTRIBUTION_TYPES);
 #undef AKANTU_RANDOM_DISTRIBUTION_TYPE_ADD
 
 #if !defined(AKANTU_NDEBUG) && defined(AKANTU_CORE_CXX_11)
       phx::function<algebraic_error_handler_> const error_handler =
           algebraic_error_handler_();
       qi::on_error<qi::fail>(start, error_handler(lbs::_4, lbs::_3, lbs::_2));
 #endif
 
       start.name("random-generator");
       generator.name("random-generator");
       distribution.name("random-distribution");
       generator_type.name("generator-type");
       generator_params.name("generator-parameters");
       number.name("number");
 
 #ifndef AKANTU_NDEBUG
       if (AKANTU_DEBUG_TEST(dblDebug)) {
         qi::debug(generator);
         qi::debug(distribution);
         qi::debug(generator_params);
       }
 #endif
     }
 
   private:
     qi::rule<Iterator, ParsableRandomGenerator(), Skipper> start;
     qi::rule<Iterator, ParsableRandomGenerator(), Skipper> generator;
     qi::rule<Iterator, ParsableRandomGenerator(), Skipper> distribution;
     qi::rule<Iterator, parsable_vector(), qi::locals<parsable_vector>, Skipper>
         generator_params;
     AlgebraicGrammar<Iterator, Skipper> number;
     qi::symbols<char, RandomDistributionType> generator_type;
   };
 }
 }
 
 #endif /* __AKANTU_ALGEBRAIC_PARSER_HH__ */
diff --git a/src/io/parser/cppargparse/cppargparse.cc b/src/io/parser/cppargparse/cppargparse.cc
index 5c3280299..55ab84290 100644
--- a/src/io/parser/cppargparse/cppargparse.cc
+++ b/src/io/parser/cppargparse/cppargparse.cc
@@ -1,523 +1,523 @@
 /**
  * @file   cppargparse.cc
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Thu Apr 03 2014
- * @date last modification: Wed Nov 11 2015
+ * @date last modification: Wed Nov 08 2017
  *
  * @brief  implementation of the ArgumentParser
  *
  * @section LICENSE
  *
- * Copyright  (©)  2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de Lausanne)
+ * 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
+ * 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
+ * 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 "cppargparse.hh"
 
 #include <cstdlib>
 #include <cstring>
 #include <libgen.h>
 
 #include <algorithm>
 #include <iomanip>
 #include <iostream>
 #include <queue>
 #include <sstream>
 #include <string>
 
 #include <exception>
 #include <stdexcept>
 #include <string.h>
 
 namespace cppargparse {
 
 /* -------------------------------------------------------------------------- */
 static inline std::string to_upper(const std::string & str) {
   std::string lstr = str;
   std::transform(lstr.begin(), lstr.end(), lstr.begin(),
                  (int (*)(int))std::toupper);
   return lstr;
 }
 
 /* -------------------------------------------------------------------------- */
 /* ArgumentParser                                                             */
 /* -------------------------------------------------------------------------- */
 ArgumentParser::ArgumentParser() {
   this->addArgument("-h;--help", "show this help message and exit", 0, _boolean,
                     false, true);
 }
 
 /* -------------------------------------------------------------------------- */
 ArgumentParser::~ArgumentParser() {
   for (auto it = arguments.begin(); it != arguments.end(); ++it) {
     delete it->second;
   }
 }
 
 /* -------------------------------------------------------------------------- */
 void ArgumentParser::setParallelContext(int prank, int psize) {
   this->prank = prank;
   this->psize = psize;
 }
 
 /* -------------------------------------------------------------------------- */
 void ArgumentParser::_exit(const std::string & msg, int status) {
   if (prank == 0) {
     if (msg != "") {
       std::cerr << msg << std::endl;
       std::cerr << std::endl;
     }
 
     this->print_help(std::cerr);
   }
 
   if (external_exit)
     (*external_exit)(status);
   else {
     exit(status);
   }
 }
 
 /* -------------------------------------------------------------------------- */
 const ArgumentParser::Argument & ArgumentParser::
 operator[](const std::string & name) const {
   auto it = success_parsed.find(name);
 
   if (it != success_parsed.end()) {
     return *(it->second);
   } else {
     throw std::range_error("No argument named \'" + name +
                            "\' was found in the parsed argument," +
                            " make sur to specify it \'required\'" +
                            " or to give it a default value");
   }
 }
 
 /* -------------------------------------------------------------------------- */
 bool ArgumentParser::has(const std::string & name) const {
   return (success_parsed.find(name) != success_parsed.end());
 }
 
 /* -------------------------------------------------------------------------- */
 void ArgumentParser::addArgument(const std::string & name_or_flag,
                                  const std::string & help, int nargs,
                                  ArgumentType type) {
   _addArgument(name_or_flag, help, nargs, type);
 }
 
 /* -------------------------------------------------------------------------- */
 ArgumentParser::_Argument &
 ArgumentParser::_addArgument(const std::string & name, const std::string & help,
                              int nargs, ArgumentType type) {
   _Argument * arg = nullptr;
 
   switch (type) {
   case _string: {
     arg = new ArgumentStorage<std::string>();
     break;
   }
   case _float: {
     arg = new ArgumentStorage<double>();
     break;
   }
   case _integer: {
     arg = new ArgumentStorage<int>();
     break;
   }
   case _boolean: {
     arg = new ArgumentStorage<bool>();
     break;
   }
   }
 
   arg->help = help;
   arg->nargs = nargs;
   arg->type = type;
 
   std::stringstream sstr(name);
   std::string item;
   std::vector<std::string> tmp_keys;
   while (std::getline(sstr, item, ';')) {
     tmp_keys.push_back(item);
   }
 
   int long_key = -1;
   int short_key = -1;
   bool problem = (tmp_keys.size() > 2) || (name == "");
   for (auto it = tmp_keys.begin(); it != tmp_keys.end(); ++it) {
     if (it->find("--") == 0) {
       problem |= (long_key != -1);
       long_key = it - tmp_keys.begin();
     } else if (it->find("-") == 0) {
       problem |= (long_key != -1);
       short_key = it - tmp_keys.begin();
     }
   }
 
   problem |= ((tmp_keys.size() == 2) && (long_key == -1 || short_key == -1));
 
   if (problem) {
     delete arg;
     throw std::invalid_argument("Synthax of name or flags is not correct. "
                                 "Possible synthax are \'-f\', \'-f;--foo\', "
                                 "\'--foo\', \'bar\'");
   }
 
   if (long_key != -1) {
     arg->name = tmp_keys[long_key];
     arg->name.erase(0, 2);
   } else if (short_key != -1) {
     arg->name = tmp_keys[short_key];
     arg->name.erase(0, 1);
   } else {
     arg->name = tmp_keys[0];
     pos_args.push_back(arg);
     arg->required = (nargs != _one_if_possible);
     arg->is_positional = true;
   }
 
   arguments[arg->name] = arg;
 
   if (!arg->is_positional) {
     if (short_key != -1) {
       std::string key = tmp_keys[short_key];
       key_args[key] = arg;
       arg->keys.push_back(key);
     }
 
     if (long_key != -1) {
       std::string key = tmp_keys[long_key];
       key_args[key] = arg;
       arg->keys.push_back(key);
     }
   }
 
   return *arg;
 }
 
 #if not HAVE_STRDUP
 static char * strdup(const char * str) {
   size_t len = strlen(str);
   auto * x = (char *)malloc(len + 1); /* 1 for the null terminator */
   if (!x)
     return nullptr;        /* malloc could not allocate memory */
   memcpy(x, str, len + 1); /* copy the string into the new buffer */
   return x;
 }
 #endif
 
 /* -------------------------------------------------------------------------- */
 void ArgumentParser::parse(int & argc, char **& argv, int flags,
                            bool parse_help) {
   bool stop_in_not_parsed = flags & _stop_on_not_parsed;
   bool remove_parsed = flags & _remove_parsed;
 
   std::vector<std::string> argvs;
 
   argvs.reserve(argc);
   for (int i = 0; i < argc; ++i) {
     argvs.emplace_back(argv[i]);
   }
 
   unsigned int current_position = 0;
   if (this->program_name == "" && argc > 0) {
     std::string prog = argvs[current_position];
     const char * c_prog = prog.c_str();
     char * c_prog_tmp = strdup(c_prog);
     std::string base_prog(basename(c_prog_tmp));
     this->program_name = base_prog;
     std::free(c_prog_tmp);
   }
 
   std::queue<_Argument *> positional_queue;
   for (auto it = pos_args.begin(); it != pos_args.end(); ++it)
     positional_queue.push(*it);
 
   std::vector<int> argvs_to_remove;
   ++current_position; // consume argv[0]
   while (current_position < argvs.size()) {
     std::string arg = argvs[current_position];
     ++current_position;
 
     auto key_it = key_args.find(arg);
 
     bool is_positional = false;
     _Argument * argument_ptr = nullptr;
     if (key_it == key_args.end()) {
       if (positional_queue.empty()) {
         if (stop_in_not_parsed)
           this->_exit("Argument " + arg + " not recognized", EXIT_FAILURE);
         continue;
       } else {
         argument_ptr = positional_queue.front();
         is_positional = true;
         --current_position;
       }
     } else {
       argument_ptr = key_it->second;
     }
 
     if (remove_parsed && !is_positional && argument_ptr->name != "help") {
       argvs_to_remove.push_back(current_position - 1);
     }
 
     _Argument & argument = *argument_ptr;
 
     unsigned int min_nb_val = 0, max_nb_val = 0;
     switch (argument.nargs) {
     case _one_if_possible:
       max_nb_val = 1;
       break; // "?"
     case _at_least_one:
       min_nb_val = 1; // "+"
     /* FALLTHRU */
     /* [[fallthrough]]; un-comment when compiler will get it*/
     case _any:
       max_nb_val = argc - current_position;
       break; // "*"
     default:
       min_nb_val = max_nb_val = argument.nargs; // "N"
     }
 
     std::vector<std::string> values;
     unsigned int arg_consumed = 0;
     if (max_nb_val <= (argc - current_position)) {
       for (; arg_consumed < max_nb_val; ++arg_consumed) {
         std::string v = argvs[current_position];
         ++current_position;
         bool is_key = key_args.find(v) != key_args.end();
         bool is_good_type = checkType(argument.type, v);
 
         if (!is_key && is_good_type) {
           values.push_back(v);
           if (remove_parsed)
             argvs_to_remove.push_back(current_position - 1);
         } else {
           // unconsume not parsed argument for optional
           if (!is_positional || is_key)
             --current_position;
           break;
         }
       }
     }
 
     if (arg_consumed < min_nb_val) {
       if (!is_positional) {
         this->_exit("Not enought values for the argument " + argument.name +
                         " where provided",
                     EXIT_FAILURE);
       } else {
         if (stop_in_not_parsed)
           this->_exit("Argument " + arg + " not recognized", EXIT_FAILURE);
       }
     } else {
       if (is_positional)
         positional_queue.pop();
 
       if (!argument.parsed) {
         success_parsed[argument.name] = &argument;
         argument.parsed = true;
         if ((argument.nargs == _one_if_possible || argument.nargs == 0) &&
             arg_consumed == 0) {
           if (argument.has_const)
             argument.setToConst();
           else if (argument.has_default)
             argument.setToDefault();
         } else {
           argument.setValues(values);
         }
       } else {
         this->_exit("Argument " + argument.name +
                         " already present in the list of argument",
                     EXIT_FAILURE);
       }
     }
   }
 
   for (auto ait = arguments.begin(); ait != arguments.end(); ++ait) {
     _Argument & argument = *(ait->second);
     if (!argument.parsed) {
       if (argument.has_default) {
         argument.setToDefault();
         success_parsed[argument.name] = &argument;
       }
 
       if (argument.required) {
         this->_exit("Argument " + argument.name + " required but not given!",
                     EXIT_FAILURE);
       }
     }
   }
 
   // removing the parsed argument if remove_parsed is true
   if (argvs_to_remove.size()) {
     std::vector<int>::const_iterator next_to_remove = argvs_to_remove.begin();
     for (int i = 0, c = 0; i < argc; ++i) {
       if (next_to_remove == argvs_to_remove.end() || i != *next_to_remove) {
         argv[c] = argv[i];
         ++c;
       } else {
         if (next_to_remove != argvs_to_remove.end())
           ++next_to_remove;
       }
     }
 
     argc -= argvs_to_remove.size();
   }
 
   this->argc = &argc;
   this->argv = &argv;
 
   if (this->arguments["help"]->parsed && parse_help) {
     this->_exit();
   }
 }
 
 /* -------------------------------------------------------------------------- */
 bool ArgumentParser::checkType(ArgumentType type,
                                const std::string & value) const {
   std::stringstream sstr(value);
   switch (type) {
   case _string: {
     std::string s;
     sstr >> s;
     break;
   }
   case _float: {
     double d;
     sstr >> d;
     break;
   }
   case _integer: {
     int i;
     sstr >> i;
     break;
   }
   case _boolean: {
     bool b;
     sstr >> b;
     break;
   }
   }
 
   return (sstr.fail() == false);
 }
 
 /* -------------------------------------------------------------------------- */
 void ArgumentParser::printself(std::ostream & stream) const {
   for (auto it = success_parsed.begin(); it != success_parsed.end(); ++it) {
     const Argument & argument = *(it->second);
     argument.printself(stream);
     stream << std::endl;
   }
 }
 
 /* -------------------------------------------------------------------------- */
 void ArgumentParser::print_usage(std::ostream & stream) const {
   stream << "Usage: " << this->program_name;
 
   // print shorten usage
   for (auto it = arguments.begin(); it != arguments.end(); ++it) {
     const _Argument & argument = *(it->second);
     if (!argument.is_positional) {
       if (!argument.required)
         stream << " [";
       stream << argument.keys[0];
       this->print_usage_nargs(stream, argument);
       if (!argument.required)
         stream << "]";
     }
   }
 
   for (auto it = pos_args.begin(); it != pos_args.end(); ++it) {
     const _Argument & argument = **it;
     this->print_usage_nargs(stream, argument);
   }
 
   stream << std::endl;
 }
 
 /* -------------------------------------------------------------------------- */
 void ArgumentParser::print_usage_nargs(std::ostream & stream,
                                        const _Argument & argument) const {
   std::string u_name = to_upper(argument.name);
   switch (argument.nargs) {
   case _one_if_possible:
     stream << " [" << u_name << "]";
     break;
   case _at_least_one:
     stream << " " << u_name;
   /* FALLTHRU */
   /* [[fallthrough]]; un-comment when compiler will get it */
   case _any:
     stream << " [" << u_name << " ...]";
     break;
   default:
     for (int i = 0; i < argument.nargs; ++i) {
       stream << " " << u_name;
     }
   }
 }
 
 void ArgumentParser::print_help(std::ostream & stream) const {
   this->print_usage(stream);
   if (!pos_args.empty()) {
     stream << std::endl;
     stream << "positional arguments:" << std::endl;
     for (auto it = pos_args.begin(); it != pos_args.end(); ++it) {
       const _Argument & argument = **it;
       this->print_help_argument(stream, argument);
     }
   }
 
   if (!key_args.empty()) {
     stream << std::endl;
     stream << "optional arguments:" << std::endl;
     for (auto it = arguments.begin(); it != arguments.end(); ++it) {
       const _Argument & argument = *(it->second);
       if (!argument.is_positional) {
         this->print_help_argument(stream, argument);
       }
     }
   }
 }
 
 void ArgumentParser::print_help_argument(std::ostream & stream,
                                          const _Argument & argument) const {
   std::string key("");
   if (argument.is_positional)
     key = argument.name;
   else {
     std::stringstream sstr;
     for (unsigned int i = 0; i < argument.keys.size(); ++i) {
       if (i != 0)
         sstr << ", ";
       sstr << argument.keys[i];
       this->print_usage_nargs(sstr, argument);
     }
     key = sstr.str();
   }
 
   stream << "  " << std::left << std::setw(15) << key << "  " << argument.help;
   argument.printDefault(stream);
 
   stream << std::endl;
 }
 }
diff --git a/src/io/parser/cppargparse/cppargparse.hh b/src/io/parser/cppargparse/cppargparse.hh
index 4a89f4c54..4608c9187 100644
--- a/src/io/parser/cppargparse/cppargparse.hh
+++ b/src/io/parser/cppargparse/cppargparse.hh
@@ -1,200 +1,200 @@
 /**
  * @file   cppargparse.hh
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Thu Apr 03 2014
- * @date last modification: Tue Dec 08 2015
+ * @date last modification: Sun Dec 03 2017
  *
  * @brief  Get the commandline options and store them as short, long and others
  *
  * @section LICENSE
  *
- * Copyright  (©)  2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de Lausanne)
+ * 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
+ * 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
+ * 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 <iostream>
 #include <map>
 #include <string>
 #include <vector>
 
 #ifndef __CPPARGPARSE_HH__
 #define __CPPARGPARSE_HH__
 
 /* -------------------------------------------------------------------------- */
 namespace cppargparse {
 
 /// define the types of the arguments
 enum ArgumentType { _string, _integer, _float, _boolean };
 
 /// Defines how many arguments to expect
 enum ArgumentNargs { _one_if_possible = -1, _at_least_one = -2, _any = -3 };
 
 /// Flags for the parse function of ArgumentParser
 enum ParseFlags {
   _no_flags = 0x0,           ///< Default behavior
   _stop_on_not_parsed = 0x1, ///< Stop on unknown arguments
   _remove_parsed = 0x2       ///< Remove parsed arguments from argc argv
 };
 
 /// Helps to combine parse flags
 inline ParseFlags operator|(const ParseFlags & a, const ParseFlags & b) {
   auto tmp = ParseFlags(int(a) | int(b));
   return tmp;
 }
 
 /* -------------------------------------------------------------------------- */
 
 /**
  * ArgumentParser is a class that mimics the Python argparse module
  */
 class ArgumentParser {
 public:
   /// public definition of an argument
   class Argument {
   public:
     Argument() : name(std::string()) {}
     virtual ~Argument() = default;
     virtual void printself(std::ostream & stream) const = 0;
     template <class T> operator T() const;
     std::string name;
   };
 
   /// constructor
   ArgumentParser();
 
   /// destroy everything
   ~ArgumentParser();
 
   /// add an argument with a description
   void addArgument(const std::string & name_or_flag, const std::string & help,
                    int nargs = 1, ArgumentType type = _string);
 
   /// add an argument with an help and a default value
   template <class T>
   void addArgument(const std::string & name_or_flag, const std::string & help,
                    int nargs, ArgumentType type, T def);
 
   /// add an argument with an help and a default + const value
   template <class T>
   void addArgument(const std::string & name_or_flag, const std::string & help,
                    int nargs, ArgumentType type, T def, T cons);
 
   /// parse argc, argv
   void parse(int & argc, char **& argv, int flags = _stop_on_not_parsed,
              bool parse_help = true);
 
   /// get the last argc parsed
   int & getArgC() { return *(this->argc); }
 
   /// get the last argv parsed
   char **& getArgV() { return *(this->argv); }
 
   /// print the content in the stream
   void printself(std::ostream & stream) const;
 
   /// print the help text
   void print_help(std::ostream & stream = std::cout) const;
 
   /// print the usage text
   void print_usage(std::ostream & stream = std::cout) const;
 
   /// set an external function to replace the exit function from the stdlib
   void setExternalExitFunction(void (*external_exit)(int)) {
     this->external_exit = external_exit;
   }
 
   /// accessor for a registered argument that was parsed, throw an exception if
   /// the argument does not exist or was not set (parsed or default value)
   const Argument & operator[](const std::string & name) const;
 
   /// is the argument present
   bool has(const std::string &) const;
 
   /// set the parallel context to avoid multiple help messages in
   /// multiproc/thread cases
   void setParallelContext(int prank, int psize);
 
 public:
   /// Internal class describing the arguments
   struct _Argument;
   /// Stores that value of an argument
   template <class T> class ArgumentStorage;
 
 private:
   /// Internal function to be used by the public addArgument
   _Argument & _addArgument(const std::string & name_or_flag,
                            const std::string & description, int nargs,
                            ArgumentType type);
 
   void _exit(const std::string & msg = "", int status = 0);
   bool checkType(ArgumentType type, const std::string & value) const;
 
   /// function to help to print help
   void print_usage_nargs(std::ostream & stream,
                          const _Argument & argument) const;
   /// function to help to print help
   void print_help_argument(std::ostream & stream,
                            const _Argument & argument) const;
 
 private:
   /// public arguments storage
   using Arguments = std::map<std::string, Argument *>;
   /// internal arguments storage
   using _Arguments = std::map<std::string, _Argument *>;
   /// association key argument
   using ArgumentKeyMap = std::map<std::string, _Argument *>;
   /// position arguments
   using PositionalArgument = std::vector<_Argument *>;
 
   /// internal storage of arguments declared by the user
   _Arguments arguments;
   /// list of arguments successfully parsed
   Arguments success_parsed;
   /// keys associated to arguments
   ArgumentKeyMap key_args;
   /// positional arguments
   PositionalArgument pos_args;
 
   /// program name
   std::string program_name;
 
   /// exit function to use
   void (*external_exit)(int){nullptr};
 
   /// Parallel context, rank and size of communicator
   int prank{0}, psize{1};
 
   /// The last argc parsed (those are the modified version after parse)
   int * argc;
 
   /// The last argv parsed (those are the modified version after parse)
   char *** argv;
 };
 }
 
 inline std::ostream & operator<<(std::ostream & stream,
                                  const cppargparse::ArgumentParser & argparse) {
   argparse.printself(stream);
   return stream;
 }
 
 #endif /* __CPPARGPARSE_HH__ */
 
 #include "cppargparse_tmpl.hh"
diff --git a/src/io/parser/cppargparse/cppargparse_tmpl.hh b/src/io/parser/cppargparse/cppargparse_tmpl.hh
index c12727656..9dcad76df 100644
--- a/src/io/parser/cppargparse/cppargparse_tmpl.hh
+++ b/src/io/parser/cppargparse/cppargparse_tmpl.hh
@@ -1,240 +1,240 @@
 /**
  * @file   cppargparse_tmpl.hh
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Thu Apr 03 2014
- * @date last modification: Tue Dec 08 2015
+ * @date last modification: Wed Nov 08 2017
  *
  * @brief  Implementation of the templated part of the commandline argument
  * parser
  *
  * @section LICENSE
  *
- * Copyright  (©)  2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de Lausanne)
+ * 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
+ * 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
+ * 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 <sstream>
 #include <stdexcept>
 
 #ifndef __CPPARGPARSE_TMPL_HH__
 #define __CPPARGPARSE_TMPL_HH__
 
 namespace cppargparse {
 /* -------------------------------------------------------------------------- */
 /* Argument                                                                   */
 /* -------------------------------------------------------------------------- */
 
 /// internal description of arguments
 struct ArgumentParser::_Argument : public Argument {
   _Argument() : Argument(), help(std::string()) {}
   ~_Argument() override = default;
 
   void setValues(std::vector<std::string> & values) {
     for (auto it = values.begin(); it != values.end(); ++it) {
       this->addValue(*it);
     }
   }
 
   virtual void addValue(std::string & value) = 0;
   virtual void setToDefault() = 0;
   virtual void setToConst() = 0;
 
   std::ostream & printDefault(std::ostream & stream) const {
     stream << std::boolalpha;
     if (has_default) {
       stream << " (default: ";
       this->_printDefault(stream);
       stream << ")";
     }
     if (has_const) {
       stream << " (const: ";
       this->_printConst(stream);
       stream << ")";
     }
     return stream;
   }
 
   virtual std::ostream & _printDefault(std::ostream & stream) const = 0;
   virtual std::ostream & _printConst(std::ostream & stream) const = 0;
 
   std::string help;
   int nargs{1};
   ArgumentType type{_string};
   bool required{false};
   bool parsed{false};
   bool has_default{false};
   bool has_const{false};
   std::vector<std::string> keys;
   bool is_positional{false};
 };
 
 /* -------------------------------------------------------------------------- */
 /// typed storage of the arguments
 template <class T>
 class ArgumentParser::ArgumentStorage : public ArgumentParser::_Argument {
 public:
   ArgumentStorage() : _default(T()), _const(T()), values(std::vector<T>()) {}
 
   void addValue(std::string & value) override {
     std::stringstream sstr(value);
     T t;
     sstr >> t;
     values.push_back(t);
   }
 
   void setToDefault() override {
     values.clear();
     values.push_back(_default);
   }
 
   void setToConst() override {
     values.clear();
     values.push_back(_const);
   }
 
   void printself(std::ostream & stream) const override {
     stream << this->name << " =";
     stream << std::boolalpha; // for boolean
     for (auto vit = this->values.begin(); vit != this->values.end(); ++vit) {
       stream << " " << *vit;
     }
   }
 
   std::ostream & _printDefault(std::ostream & stream) const override {
     stream << _default;
     return stream;
   }
 
   std::ostream & _printConst(std::ostream & stream) const override {
     stream << _const;
     return stream;
   }
 
   T _default;
   T _const;
   std::vector<T> values;
 };
 
 /* -------------------------------------------------------------------------- */
 template <>
 inline void
 ArgumentParser::ArgumentStorage<std::string>::addValue(std::string & value) {
   values.push_back(value);
 }
 
 template <class T> struct is_vector {
   enum { value = false };
 };
 
 template <class T> struct is_vector<std::vector<T>> {
   enum { value = true };
 };
 
 /* -------------------------------------------------------------------------- */
 template <class T, bool is_vector = cppargparse::is_vector<T>::value>
 struct cast_helper {
   static T cast(const ArgumentParser::Argument & arg) {
     const auto & _arg =
         dynamic_cast<const ArgumentParser::ArgumentStorage<T> &>(arg);
     if (_arg.values.size() == 1) {
       return _arg.values[0];
     } else {
       throw std::length_error("Not enougth or too many argument where passed "
                               "for the command line argument: " +
                               arg.name);
     }
   }
 };
 
 template <class T> struct cast_helper<T, true> {
   static T cast(const ArgumentParser::Argument & arg) {
     const auto & _arg =
         dynamic_cast<const ArgumentParser::ArgumentStorage<T> &>(arg);
     return _arg.values;
   }
 };
 
 /* -------------------------------------------------------------------------- */
 template <class T> ArgumentParser::Argument::operator T() const {
   return cast_helper<T>::cast(*this);
 }
 
 template <> inline ArgumentParser::Argument::operator const char *() const {
   return cast_helper<std::string>::cast(*this).c_str();
 }
 
 template <> inline ArgumentParser::Argument::operator unsigned int() const {
   return cast_helper<int>::cast(*this);
 }
 
 template <class T>
 void ArgumentParser::addArgument(const std::string & name_or_flag,
                                  const std::string & help, int nargs,
                                  ArgumentType type, T def) {
   _Argument & arg = _addArgument(name_or_flag, help, nargs, type);
   dynamic_cast<ArgumentStorage<T> &>(arg)._default = def;
   arg.has_default = true;
 }
 
 template <class T>
 void ArgumentParser::addArgument(const std::string & name_or_flag,
                                  const std::string & help, int nargs,
                                  ArgumentType type, T def, T cons) {
   _Argument & arg = _addArgument(name_or_flag, help, nargs, type);
   dynamic_cast<ArgumentStorage<T> &>(arg)._default = def;
   arg.has_default = true;
   dynamic_cast<ArgumentStorage<T> &>(arg)._const = cons;
   arg.has_const = true;
 }
 
 /* -------------------------------------------------------------------------- */
 template <>
 inline void
 ArgumentParser::addArgument<const char *>(const std::string & name_or_flag,
                                           const std::string & help, int nargs,
                                           ArgumentType type, const char * def) {
   this->addArgument<std::string>(name_or_flag, help, nargs, type, def);
 }
 
 template <>
 inline void
 ArgumentParser::addArgument<unsigned int>(const std::string & name_or_flag,
                                           const std::string & help, int nargs,
                                           ArgumentType type, unsigned int def) {
   this->addArgument<int>(name_or_flag, help, nargs, type, def);
 }
 
 /* -------------------------------------------------------------------------- */
 template <>
 inline void ArgumentParser::addArgument<const char *>(
     const std::string & name_or_flag, const std::string & help, int nargs,
     ArgumentType type, const char * def, const char * cons) {
   this->addArgument<std::string>(name_or_flag, help, nargs, type, def, cons);
 }
 
 template <>
 inline void ArgumentParser::addArgument<unsigned int>(
     const std::string & name_or_flag, const std::string & help, int nargs,
     ArgumentType type, unsigned int def, unsigned int cons) {
   this->addArgument<int>(name_or_flag, help, nargs, type, def, cons);
 }
 }
 
 #endif /* __AKANTU_CPPARGPARSE_TMPL_HH__ */
diff --git a/src/io/parser/input_file_parser.hh b/src/io/parser/input_file_parser.hh
index 3826abca1..8de5904c9 100644
--- a/src/io/parser/input_file_parser.hh
+++ b/src/io/parser/input_file_parser.hh
@@ -1,268 +1,268 @@
 /**
  * @file   input_file_parser.hh
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Wed Nov 13 2013
- * @date last modification: Tue May 19 2015
+ * @date last modification: Mon Dec 18 2017
  *
  * @brief  Grammar definition for the input files
  *
  * @section LICENSE
  *
- * Copyright  (©)  2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de Lausanne)
+ * 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
+ * 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
+ * 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/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 // Boost
 /* -------------------------------------------------------------------------- */
 
 #include <boost/config/warning_disable.hpp>
 #include <boost/spirit/include/phoenix_bind.hpp>
 #include <boost/spirit/include/phoenix_core.hpp>
 #include <boost/spirit/include/phoenix_fusion.hpp>
 #include <boost/spirit/include/phoenix_operator.hpp>
 #include <boost/spirit/include/qi.hpp>
 #include <boost/variant/recursive_variant.hpp>
 
 #ifndef __AKANTU_INPUT_FILE_PARSER_HH__
 #define __AKANTU_INPUT_FILE_PARSER_HH__
 
 namespace spirit = boost::spirit;
 namespace qi = boost::spirit::qi;
 namespace lbs = boost::spirit::qi::labels;
 namespace ascii = boost::spirit::ascii;
 namespace phx = boost::phoenix;
 
 namespace akantu {
 
 namespace parser {
   struct error_handler_ {
     template <typename, typename, typename, typename> struct result {
       using type = void;
     };
 
     template <typename Iterator>
     void operator()(qi::info const & what, Iterator err_pos, Iterator /*first*/,
                     Iterator /*last*/) const {
       spirit::classic::file_position pos = err_pos.get_position();
 
       AKANTU_EXCEPTION("Parse error [ "
                        << "Expecting " << what << " instead of \"" << *err_pos
                        << "\" ]"
                        << " in file " << pos.file << " line " << pos.line
                        << " column " << pos.column << std::endl
                        << "'" << err_pos.get_currentline() << "'" << std::endl
                        << std::setw(pos.column) << " "
                        << "^- here");
     }
 
   private:
   };
 
   static ParserSection & create_subsection(
       const ParserType & type, const boost::optional<std::string> & opt_name,
       const boost::optional<std::string> & opt_option, ParserSection & sect) {
     std::string option = "";
     if (opt_option)
       option = *opt_option;
 
     static size_t id = 12;
     std::string name = "anonymous_" + std::to_string(id++);
     if (opt_name)
       name = *opt_name;
 
     ParserSection sect_tmp(name, type, option, sect);
     return sect.addSubSection(sect_tmp);
   }
 
   template <typename Iter>
   static bool create_parameter(boost::iterator_range<Iter> & rng,
                                std::string & value, ParserSection & sect) {
     try {
       std::string name(rng.begin(), rng.end());
       name = trim(name);
       spirit::classic::file_position pos = rng.begin().get_position();
 
       ParserParameter param_tmp(name, value, sect);
       param_tmp.setDebugInfo(pos.file, pos.line, pos.column);
       sect.addParameter(param_tmp);
     } catch (debug::Exception & e) {
       return false;
     }
     return true;
   }
 
   static std::string concatenate(const std::string & t1,
                                  const std::string & t2) {
     return (t1 + t2);
   }
 
   /* ---------------------------------------------------------------------- */
   /* Grammars definitions                                                   */
   /* ---------------------------------------------------------------------- */
   template <class Iterator>
   struct InputFileGrammar
       : qi::grammar<Iterator, void(), typename Skipper<Iterator>::type> {
     InputFileGrammar(ParserSection * sect)
         : InputFileGrammar::base_type(start, "input_file_grammar"),
           parent_section(sect) {
 
       /* clang-format off */
     start
       =   mini_section(parent_section)
       ;
 
     mini_section
       =   *(
                entry  (lbs::_r1)
            |   section(lbs::_r1)
            )
       ;
 
     entry
       =   (
              qi::raw[key]
           >> '='
           >  value
           ) [ lbs::_pass = phx::bind(&create_parameter<Iterator>,
                                      lbs::_1,
                                      lbs::_2,
                                      *lbs::_r1) ]
       ;
 
     section
       =   (
             qi::no_case[section_type]
           > qi::lexeme
                [
                    -section_name
                    > -section_option
                ]
            ) [ lbs::_a = &phx::bind(&create_subsection,
                                     lbs::_1,
                                     phx::at_c<0>(lbs::_2),
                                     phx::at_c<1>(lbs::_2),
                                     *lbs::_r1) ]
           > '['
           > mini_section(lbs::_a)
           > ']'
       ;
 
     section_name
       =   qi::char_("a-zA-Z_") >> *qi::char_("a-zA-Z_0-9")
       ;
 
     section_option
       =   (+ascii::space >> section_name) [ lbs::_val = lbs::_2 ]
       ;
 
     key
       =   qi::char_("a-zA-Z_") >> *qi::char_("a-zA-Z_0-9")
       ;
 
     value
       =   (
            mono_line_value          [ lbs::_a = phx::bind(&concatenate, lbs::_a, lbs::_1) ]
         > *(
             '\\' > mono_line_value  [ lbs::_a = phx::bind(&concatenate, lbs::_a, lbs::_1) ]
            )
           ) [ lbs::_val = lbs::_a ]
       ;
 
     mono_line_value
       =   qi::lexeme
              [
            +(qi::char_ - (qi::char_('=') | spirit::eol | '#' | ';' | '\\'))
              ]
       ;
 
     skipper
       =     ascii::space
       |     "#" >> *(qi::char_ - spirit::eol)
       ;
 
 /* clang-format on */
 
 #define AKANTU_SECTION_TYPE_ADD(r, data, elem)                                 \
   (BOOST_PP_STRINGIZE(elem), BOOST_PP_CAT(ParserType::_, elem))
 
       section_type.add BOOST_PP_SEQ_FOR_EACH(AKANTU_SECTION_TYPE_ADD, _,
                                              AKANTU_SECTION_TYPES);
 #undef AKANTU_SECTION_TYPE_ADD
 
 #if !defined(AKANTU_NDEBUG) && defined(AKANTU_CORE_CXX_11)
       phx::function<error_handler_> const error_handler = error_handler_();
       qi::on_error<qi::fail>(start,
                              error_handler(lbs::_4, lbs::_3, lbs::_1, lbs::_2));
 #endif
 
       section.name("section");
       section_name.name("section-name");
       section_option.name("section-option");
       mini_section.name("section-content");
       entry.name("parameter");
       key.name("parameter-name");
       value.name("parameter-value");
       section_type.name("section-types-list");
       mono_line_value.name("mono-line-value");
 
 #if !defined AKANTU_NDEBUG
       if (AKANTU_DEBUG_TEST(dblDebug)) {
         //        qi::debug(section);
         qi::debug(section_name);
         qi::debug(section_option);
         //        qi::debug(mini_section);
         //	qi::debug(entry);
         qi::debug(key);
         qi::debug(value);
         qi::debug(mono_line_value);
       }
 #endif
     }
 
     const std::string & getErrorMessage() const { return error_message; };
 
     using skipper_type = typename Skipper<Iterator>::type;
     skipper_type skipper;
 
   private:
     std::string error_message;
 
     qi::rule<Iterator, void(ParserSection *), skipper_type> mini_section;
     qi::rule<Iterator, void(ParserSection *), qi::locals<ParserSection *>,
              skipper_type>
         section;
     qi::rule<Iterator, void(), skipper_type> start;
     qi::rule<Iterator, std::string()> section_name;
     qi::rule<Iterator, std::string()> section_option;
     qi::rule<Iterator, void(ParserSection *), skipper_type> entry;
     qi::rule<Iterator, std::string(), skipper_type> key;
     qi::rule<Iterator, std::string(), qi::locals<std::string>, skipper_type>
         value;
     qi::rule<Iterator, std::string(), skipper_type> mono_line_value;
 
     qi::symbols<char, ParserType> section_type;
 
     ParserSection * parent_section;
   };
 }
 
 } // akantu
 
 #endif /* __AKANTU_INPUT_FILE_PARSER_HH__ */
diff --git a/src/io/parser/parameter_registry.cc b/src/io/parser/parameter_registry.cc
index 1e63f3127..69f2a0c47 100644
--- a/src/io/parser/parameter_registry.cc
+++ b/src/io/parser/parameter_registry.cc
@@ -1,154 +1,154 @@
 /**
  * @file   parameter_registry.cc
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
- * @date creation: Wed Nov 13 2013
- * @date last modification: Thu Nov 19 2015
+ * @date creation: Wed May 04 2016
+ * @date last modification: Thu Feb 01 2018
  *
  * @brief  Parameter Registry and derived classes implementation
  *
  * @section LICENSE
  *
- * Copyright  (©)  2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de Lausanne)
+ * 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
+ * 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
+ * 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 <utility>
 
 #include "parameter_registry.hh"
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 
 Parameter::Parameter() : name(""), description("") {}
 
 /* -------------------------------------------------------------------------- */
 Parameter::Parameter(std::string name, std::string description,
                      ParameterAccessType param_type)
     : name(std::move(name)), description(std::move(description)),
       param_type(param_type) {}
 
 /* -------------------------------------------------------------------------- */
 bool Parameter::isWritable() const { return param_type & _pat_writable; }
 
 /* -------------------------------------------------------------------------- */
 bool Parameter::isReadable() const { return param_type & _pat_readable; }
 
 /* -------------------------------------------------------------------------- */
 bool Parameter::isInternal() const { return param_type & _pat_internal; }
 
 /* -------------------------------------------------------------------------- */
 bool Parameter::isParsable() const { return param_type & _pat_parsable; }
 
 /* -------------------------------------------------------------------------- */
 void Parameter::setAccessType(ParameterAccessType ptype) {
   this->param_type = ptype;
 }
 
 /* -------------------------------------------------------------------------- */
 void Parameter::printself(std::ostream & stream) const {
   stream << " ";
   if (isInternal())
     stream << "iii";
   else {
     if (isReadable())
       stream << "r";
     else
       stream << "-";
 
     if (isWritable())
       stream << "w";
     else
       stream << "-";
 
     if (isParsable())
       stream << "p";
     else
       stream << "-";
   }
   stream << " ";
 
   std::stringstream sstr;
   sstr << name;
   UInt width = std::max(int(10 - sstr.str().length()), 0);
   sstr.width(width);
 
   if (description != "") {
     sstr << " [" << description << "]";
   }
 
   stream << sstr.str();
   width = std::max(int(50 - sstr.str().length()), 0);
   stream.width(width);
 
   stream << " : ";
 }
 
 /* -------------------------------------------------------------------------- */
 /* -------------------------------------------------------------------------- */
 ParameterRegistry::ParameterRegistry() = default;
 
 /* -------------------------------------------------------------------------- */
 ParameterRegistry::~ParameterRegistry() {
   std::map<std::string, Parameter *>::iterator it, end;
   for (it = params.begin(); it != params.end(); ++it) {
     delete it->second;
     it->second = NULL;
   }
   this->params.clear();
 }
 
 /* -------------------------------------------------------------------------- */
 void ParameterRegistry::printself(std::ostream & stream, int indent) const {
   std::string space;
   for (Int i = 0; i < indent; i++, space += AKANTU_INDENT)
     ;
 
   Parameters::const_iterator it;
   for (it = params.begin(); it != params.end(); ++it) {
     stream << space;
     it->second->printself(stream);
   }
 
   SubRegisteries::const_iterator sub_it;
   for (sub_it = sub_registries.begin(); sub_it != sub_registries.end();
        ++sub_it) {
     stream << space << "Registry [" << std::endl;
     sub_it->second->printself(stream, indent + 1);
     stream << space << "]";
   }
 }
 
 /* -------------------------------------------------------------------------- */
 void ParameterRegistry::registerSubRegistry(const ID & id,
                                             ParameterRegistry & registry) {
   sub_registries[id] = &registry;
 }
 
 /* -------------------------------------------------------------------------- */
 void ParameterRegistry::setParameterAccessType(const std::string & name,
                                                ParameterAccessType ptype) {
   auto it = params.find(name);
   if (it == params.end())
     AKANTU_CUSTOM_EXCEPTION(debug::ParameterUnexistingException(name, *this));
   Parameter & param = *(it->second);
   param.setAccessType(ptype);
 }
 
 } // akantu
diff --git a/src/io/parser/parameter_registry.hh b/src/io/parser/parameter_registry.hh
index af649bdc8..733883f78 100644
--- a/src/io/parser/parameter_registry.hh
+++ b/src/io/parser/parameter_registry.hh
@@ -1,222 +1,221 @@
 /**
  * @file   parameter_registry.hh
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Thu Aug 09 2012
- * @date last modification: Thu Dec 17 2015
+ * @date last modification: Tue Jan 30 2018
  *
  * @brief  Interface of the parameter registry
  *
  * @section LICENSE
  *
- * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
- * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
- * Solides)
+ * 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
+ * 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
+ * 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 "parser.hh"
 /* -------------------------------------------------------------------------- */
 
 #ifndef __AKANTU_PARAMETER_REGISTRY_HH__
 #define __AKANTU_PARAMETER_REGISTRY_HH__
 
 namespace akantu {
 class ParserParameter;
 }
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 /// Defines the access modes of parsable parameters
 enum ParameterAccessType {
   _pat_internal = 0x0001,
   _pat_writable = 0x0010,
   _pat_readable = 0x0100,
   _pat_modifiable = 0x0110, //<_pat_readable | _pat_writable,
   _pat_parsable = 0x1000,
   _pat_parsmod = 0x1110 //< _pat_parsable | _pat_modifiable
 };
 
 /// Bit-wise operator between access modes
 inline ParameterAccessType operator|(const ParameterAccessType & a,
                                      const ParameterAccessType & b) {
   auto tmp = ParameterAccessType(UInt(a) | UInt(b));
   return tmp;
 }
 
 /* -------------------------------------------------------------------------- */
 template <typename T> class ParameterTyped;
 
 /**
  * Interface for the Parameter
  */
 class Parameter {
 public:
   Parameter();
   Parameter(std::string name, std::string description,
             ParameterAccessType param_type);
 
   virtual ~Parameter() = default;
   /* ------------------------------------------------------------------------ */
   bool isInternal() const;
   bool isWritable() const;
   bool isReadable() const;
   bool isParsable() const;
 
   void setAccessType(ParameterAccessType ptype);
 
   /* ------------------------------------------------------------------------ */
   template <typename T, typename V> void set(const V & value);
   virtual void setAuto(const ParserParameter & param);
   template <typename T> T & get();
   template <typename T> const T & get() const;
 
   virtual inline operator Real() const { throw std::bad_cast(); };
   template <typename T> inline operator T() const;
   /* ------------------------------------------------------------------------ */
   virtual void printself(std::ostream & stream) const;
 
   virtual const std::type_info & type() const = 0;
 
 protected:
   /// Returns const instance of templated sub-class ParameterTyped
   template <typename T> const ParameterTyped<T> & getParameterTyped() const;
 
   /// Returns instance of templated sub-class ParameterTyped
   template <typename T> ParameterTyped<T> & getParameterTyped();
 
 protected:
   /// Name of parameter
   std::string name;
 
 private:
   /// Description of parameter
   std::string description;
   /// Type of access
   ParameterAccessType param_type{_pat_internal};
 };
 
 /* -------------------------------------------------------------------------- */
 /* Typed Parameter                                                            */
 /* -------------------------------------------------------------------------- */
 /**
  * Type parameter transfering a ParserParameter (string: string) to a typed
  * parameter in the memory of the p
  */
 template <typename T> class ParameterTyped : public Parameter {
 public:
   ParameterTyped(std::string name, std::string description,
                  ParameterAccessType param_type, T & param);
 
   /* ------------------------------------------------------------------------ */
   template <typename V> void setTyped(const V & value);
   void setAuto(const ParserParameter & param) override;
   T & getTyped();
   const T & getTyped() const;
 
   void printself(std::ostream & stream) const override;
 
   inline operator Real() const override;
 
   inline const std::type_info & type() const override { return typeid(T); }
 
 private:
   /// Value of parameter
   T & param;
 };
 
 /* -------------------------------------------------------------------------- */
 /* Parsable Interface                                                         */
 /* -------------------------------------------------------------------------- */
 /// Defines interface for classes to manipulate parsable parameters
 class ParameterRegistry {
 public:
   ParameterRegistry();
   virtual ~ParameterRegistry();
 
   /* ------------------------------------------------------------------------ */
   /// Add parameter to the params map
   template <typename T>
   void registerParam(std::string name, T & variable, ParameterAccessType type,
                      const std::string & description = "");
 
   /// Add parameter to the params map (with default value)
   template <typename T>
   void registerParam(std::string name, T & variable, const T & default_value,
                      ParameterAccessType type,
                      const std::string & description = "");
 
   /*------------------------------------------------------------------------- */
 protected:
   void registerSubRegistry(const ID & id, ParameterRegistry & registry);
 
   /* ------------------------------------------------------------------------ */
 public:
   /// Set value to a parameter (with possible different type)
   template <typename T, typename V>
   void setMixed(const std::string & name, const V & value);
 
   /// Set value to a parameter
   template <typename T> void set(const std::string & name, const T & value);
 
   /// Get value of a parameter
   inline const Parameter & get(const std::string & name) const;
 
   std::vector<ID> listParameters() const {
     std::vector<ID> params;
     for (auto & pair : this->params)
       params.push_back(pair.first);
     return params;
   }
 
   std::vector<ID> listSubRegisteries() const {
     std::vector<ID> subs;
     for (auto & pair : this->sub_registries)
       subs.push_back(pair.first);
     return subs;
   }
 
 protected:
   template <typename T> T & get_(const std::string & name);
 
 protected:
   void setParameterAccessType(const std::string & name,
                               ParameterAccessType ptype);
   /* ------------------------------------------------------------------------ */
   virtual void printself(std::ostream & stream, int indent) const;
 
 protected:
   /// Parameters map
   using Parameters = std::map<std::string, Parameter *>;
   Parameters params;
 
   /// list of sub-registries
   using SubRegisteries = std::map<std::string, ParameterRegistry *>;
   SubRegisteries sub_registries;
 
   /// should accessor check in sub registries
   bool consisder_sub{true};
 };
 
 } // akantu
 
 #include "parameter_registry_tmpl.hh"
 
 #endif /* __AKANTU_PARAMETER_REGISTRY_HH__ */
diff --git a/src/io/parser/parameter_registry_tmpl.hh b/src/io/parser/parameter_registry_tmpl.hh
index 935338739..dd9f00d4d 100644
--- a/src/io/parser/parameter_registry_tmpl.hh
+++ b/src/io/parser/parameter_registry_tmpl.hh
@@ -1,391 +1,390 @@
 /**
  * @file   parameter_registry_tmpl.hh
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
- * @date creation: Thu Aug 09 2012
- * @date last modification: Fri Mar 27 2015
+ * @date creation: Wed May 04 2016
+ * @date last modification: Tue Jan 30 2018
  *
- * @brief implementation of the templated part of ParameterRegistry class and
+ * @brief  implementation of the templated part of ParameterRegistry class and
  * the derivated ones
  *
  * @section LICENSE
  *
- * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
- * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
- * Solides)
+ * 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
+ * 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
+ * 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_error.hh"
 #include "aka_iterators.hh"
 #include "parameter_registry.hh"
 #include "parser.hh"
 /* -------------------------------------------------------------------------- */
 #include <algorithm>
 #include <string>
 #include <vector>
 /* -------------------------------------------------------------------------- */
 
 #ifndef __AKANTU_PARAMETER_REGISTRY_TMPL_HH__
 #define __AKANTU_PARAMETER_REGISTRY_TMPL_HH__
 
 namespace akantu {
 
 namespace debug {
   class ParameterException : public Exception {
   public:
     ParameterException(const std::string & name, const std::string & message)
         : Exception(message), name(name) {}
     const std::string & name;
   };
 
   class ParameterUnexistingException : public ParameterException {
   public:
     ParameterUnexistingException(const std::string & name,
                                  const ParameterRegistry & registery)
         : ParameterException(
               name, "Parameter " + name + " does not exists in this scope") {
       auto && params = registery.listParameters();
       this->_info =
           std::accumulate(params.begin(), params.end(),
                           this->_info + "\n Possible parameters are: ",
                           [](auto && str, auto && param) {
                             static auto first = true;
                             auto && ret = str + (first ? " " : ", ") + param;
                             first = false;
                             return ret;
                           });
     }
   };
 
   class ParameterAccessRightException : public ParameterException {
   public:
     ParameterAccessRightException(const std::string & name,
                                   const std::string & perm)
         : ParameterException(name, "Parameter " + name + " is not " + perm) {}
   };
 
   class ParameterWrongTypeException : public ParameterException {
   public:
     ParameterWrongTypeException(const std::string & name,
                                 const std::type_info & wrong_type,
                                 const std::type_info & type)
         : ParameterException(name,
                              "Parameter " + name +
                                  " type error, cannot convert " +
                                  debug::demangle(type.name()) + " to " +
                                  debug::demangle(wrong_type.name())) {}
   };
 } // namespace debug
 /* -------------------------------------------------------------------------- */
 template <typename T>
 const ParameterTyped<T> & Parameter::getParameterTyped() const {
   try {
     const auto & tmp = dynamic_cast<const ParameterTyped<T> &>(*this);
     return tmp;
   } catch (std::bad_cast &) {
     AKANTU_CUSTOM_EXCEPTION(
         debug::ParameterWrongTypeException(name, typeid(T), this->type()));
   }
 }
 
 /* -------------------------------------------------------------------------- */
 template <typename T> ParameterTyped<T> & Parameter::getParameterTyped() {
   try {
     auto & tmp = dynamic_cast<ParameterTyped<T> &>(*this);
     return tmp;
   } catch (std::bad_cast &) {
     AKANTU_CUSTOM_EXCEPTION(
         debug::ParameterWrongTypeException(name, typeid(T), this->type()));
   }
 }
 
 /* ------------------------------------------------------------------------ */
 template <typename T, typename V> void Parameter::set(const V & value) {
   if (!(isWritable()))
     AKANTU_CUSTOM_EXCEPTION(
         debug::ParameterAccessRightException(name, "writable"));
   ParameterTyped<T> & typed_param = getParameterTyped<T>();
   typed_param.setTyped(value);
 }
 
 /* ------------------------------------------------------------------------ */
 inline void Parameter::setAuto(__attribute__((unused))
                                const ParserParameter & value) {
   if (!(isParsable()))
     AKANTU_CUSTOM_EXCEPTION(
         debug::ParameterAccessRightException(name, "parsable"));
 }
 
 /* -------------------------------------------------------------------------- */
 template <typename T> const T & Parameter::get() const {
   if (!(isReadable()))
     AKANTU_CUSTOM_EXCEPTION(
         debug::ParameterAccessRightException(name, "readable"));
   const ParameterTyped<T> & typed_param = getParameterTyped<T>();
   return typed_param.getTyped();
 }
 
 /* -------------------------------------------------------------------------- */
 template <typename T> T & Parameter::get() {
   ParameterTyped<T> & typed_param = getParameterTyped<T>();
   if (!(isReadable()) || !(this->isWritable()))
     AKANTU_CUSTOM_EXCEPTION(
         debug::ParameterAccessRightException(name, "accessible"));
   return typed_param.getTyped();
 }
 
 /* -------------------------------------------------------------------------- */
 template <typename T> inline Parameter::operator T() const {
   return this->get<T>();
 }
 
 /* -------------------------------------------------------------------------- */
 template <typename T>
 ParameterTyped<T>::ParameterTyped(std::string name, std::string description,
                                   ParameterAccessType param_type, T & param)
     : Parameter(name, description, param_type), param(param) {}
 
 /* -------------------------------------------------------------------------- */
 template <typename T>
 template <typename V>
 void ParameterTyped<T>::setTyped(const V & value) {
   param = value;
 }
 
 /* -------------------------------------------------------------------------- */
 template <typename T>
 inline void ParameterTyped<T>::setAuto(const ParserParameter & value) {
   Parameter::setAuto(value);
   param = static_cast<T>(value);
 }
 
 /* -------------------------------------------------------------------------- */
 template <>
 inline void
 ParameterTyped<std::string>::setAuto(const ParserParameter & value) {
   Parameter::setAuto(value);
   param = value.getValue();
 }
 
 /* -------------------------------------------------------------------------- */
 template <>
 inline void
 ParameterTyped<Vector<Real>>::setAuto(const ParserParameter & in_param) {
   Parameter::setAuto(in_param);
   Vector<Real> tmp = in_param;
   if (param.size() == 0) {
     param = tmp;
   } else {
     for (UInt i = 0; i < param.size(); ++i) {
       param(i) = tmp(i);
     }
   }
 }
 
 /* -------------------------------------------------------------------------- */
 template <>
 inline void
 ParameterTyped<Matrix<Real>>::setAuto(const ParserParameter & in_param) {
   Parameter::setAuto(in_param);
   Matrix<Real> tmp = in_param;
   if (param.size() == 0) {
     param = tmp;
   } else {
     for (UInt i = 0; i < param.rows(); ++i) {
       for (UInt j = 0; j < param.cols(); ++j) {
         param(i, j) = tmp(i, j);
       }
     }
   }
 }
 
 /* -------------------------------------------------------------------------- */
 template <typename T> const T & ParameterTyped<T>::getTyped() const {
   return param;
 }
 /* -------------------------------------------------------------------------- */
 template <typename T> T & ParameterTyped<T>::getTyped() { return param; }
 
 /* -------------------------------------------------------------------------- */
 template <typename T>
 inline void ParameterTyped<T>::printself(std::ostream & stream) const {
   Parameter::printself(stream);
   stream << param << "\n";
 }
 
 /* -------------------------------------------------------------------------- */
 template <typename T> class ParameterTyped<std::vector<T>> : public Parameter {
 public:
   ParameterTyped(std::string name, std::string description,
                  ParameterAccessType param_type, std::vector<T> & param)
       : Parameter(name, description, param_type), param(param) {}
 
   /* ------------------------------------------------------------------------ */
   template <typename V> void setTyped(const V & value) { param = value; }
   void setAuto(const ParserParameter & value) override {
     Parameter::setAuto(value);
     param.clear();
     const std::vector<T> & tmp = value;
     for (auto && z : tmp) {
       param.emplace_back(z);
     }
   }
 
   std::vector<T> & getTyped() { return param; }
   const std::vector<T> & getTyped() const { return param; }
 
   void printself(std::ostream & stream) const override {
     Parameter::printself(stream);
     stream << "[ ";
     for (auto && v : param)
       stream << v << " ";
     stream << "]\n";
   }
 
   inline const std::type_info & type() const override {
     return typeid(std::vector<T>);
   }
 
 private:
   /// Value of parameter
   std::vector<T> & param;
 };
 
 /* ------o--------------------------------------------------------------------
  */
 template <>
 inline void ParameterTyped<bool>::printself(std::ostream & stream) const {
   Parameter::printself(stream);
   stream << std::boolalpha << param << "\n";
 }
 
 /* -------------------------------------------------------------------------- */
 template <typename T>
 void ParameterRegistry::registerParam(std::string name, T & variable,
                                       ParameterAccessType type,
                                       const std::string & description) {
   auto it = params.find(name);
   if (it != params.end())
     AKANTU_CUSTOM_EXCEPTION(debug::ParameterException(
         name, "Parameter named " + name + " already registered."));
   auto * param = new ParameterTyped<T>(name, description, type, variable);
   params[name] = param;
 }
 
 /* -------------------------------------------------------------------------- */
 template <typename T>
 void ParameterRegistry::registerParam(std::string name, T & variable,
                                       const T & default_value,
                                       ParameterAccessType type,
                                       const std::string & description) {
   variable = default_value;
   registerParam(name, variable, type, description);
 }
 
 /* -------------------------------------------------------------------------- */
 template <typename T, typename V>
 void ParameterRegistry::setMixed(const std::string & name, const V & value) {
   auto it = params.find(name);
   if (it == params.end()) {
     if (consisder_sub) {
       for (auto it = sub_registries.begin(); it != sub_registries.end(); ++it) {
         it->second->setMixed<T>(name, value);
       }
     } else {
       AKANTU_CUSTOM_EXCEPTION(debug::ParameterUnexistingException(name, *this));
     }
   } else {
     Parameter & param = *(it->second);
     param.set<T>(value);
   }
 }
 
 /* -------------------------------------------------------------------------- */
 template <typename T>
 void ParameterRegistry::set(const std::string & name, const T & value) {
   this->template setMixed<T>(name, value);
 }
 
 /* -------------------------------------------------------------------------- */
 template <typename T> T & ParameterRegistry::get_(const std::string & name) {
   auto it = params.find(name);
   if (it == params.end()) {
     if (consisder_sub) {
       for (auto it = sub_registries.begin(); it != sub_registries.end(); ++it) {
         try {
           return it->second->get_<T>(name);
         } catch (...) {
         }
       }
     }
 
     // nothing was found not even in sub registries
     AKANTU_CUSTOM_EXCEPTION(debug::ParameterUnexistingException(name, *this));
   }
 
   Parameter & param = *(it->second);
   return param.get<T>();
 }
 
 /* -------------------------------------------------------------------------- */
 const Parameter & ParameterRegistry::get(const std::string & name) const {
   auto it = params.find(name);
   if (it == params.end()) {
     if (consisder_sub) {
       for (auto it = sub_registries.begin(); it != sub_registries.end(); ++it) {
         try {
           return it->second->get(name);
         } catch (...) {
         }
       }
     }
 
     // nothing was found not even in sub registries
     AKANTU_CUSTOM_EXCEPTION(debug::ParameterUnexistingException(name, *this));
   }
 
   Parameter & param = *(it->second);
   return param;
 }
 
 /* -------------------------------------------------------------------------- */
 namespace {
   namespace details {
     template <class T, class R, class Enable = void> struct CastHelper {
       static R convert(const T &) { throw std::bad_cast(); }
     };
 
     template <class T, class R>
     struct CastHelper<T, R,
                       std::enable_if_t<std::is_convertible<T, R>::value>> {
       static R convert(const T & val) { return val; }
     };
   } // namespace details
 } // namespace
 
 template <typename T> inline ParameterTyped<T>::operator Real() const {
   if (not isReadable())
     AKANTU_CUSTOM_EXCEPTION(
         debug::ParameterAccessRightException(name, "accessible"));
   return details::CastHelper<T, Real>::convert(param);
 }
 
 } // namespace akantu
 
 #endif /* __AKANTU_PARAMETER_REGISTRY_TMPL_HH__ */
diff --git a/src/io/parser/parsable.cc b/src/io/parser/parsable.cc
index 89b41a458..c779bd11f 100644
--- a/src/io/parser/parsable.cc
+++ b/src/io/parser/parsable.cc
@@ -1,109 +1,110 @@
 /**
  * @file   parsable.cc
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Wed Nov 13 2013
- * @date last modification: Thu Nov 19 2015
+ * @date last modification: Thu Feb 08 2018
  *
  * @brief  Parsable implementation
  *
  * @section LICENSE
  *
- * Copyright  (©)  2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de Lausanne)
+ * 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
+ * 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
+ * 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 "parsable.hh"
 #include "aka_random_generator.hh"
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 Parsable::Parsable(const ParserType & section_type, const ID & id)
     : section_type(section_type), pid(id) {
   this->consisder_sub = false;
 }
 
 /* -------------------------------------------------------------------------- */
 Parsable::~Parsable() = default;
 
 /* -------------------------------------------------------------------------- */
 void Parsable::registerSubSection(const ParserType & type,
                                   const std::string & name,
                                   Parsable & sub_section) {
   SubSectionKey key(type, name);
   sub_sections[key] = &sub_section;
 
   this->registerSubRegistry(name, sub_section);
 }
 
 /* -------------------------------------------------------------------------- */
 void Parsable::parseParam(const ParserParameter & in_param) {
   auto it = params.find(in_param.getName());
   if (it == params.end()) {
     if (Parser::isPermissive()) {
       AKANTU_DEBUG_WARNING("No parameter named " << in_param.getName()
                                                  << " registered in " << pid
                                                  << ".");
       return;
     } else
       AKANTU_EXCEPTION("No parameter named " << in_param.getName()
                                              << " registered in " << pid
                                              << ".");
   }
   Parameter & param = *(it->second);
   param.setAuto(in_param);
 }
 
 /* -------------------------------------------------------------------------- */
 void Parsable::parseSection(const ParserSection & section) {
   if (section_type != section.getType())
     AKANTU_EXCEPTION("The object "
                      << pid << " is meant to parse section of type "
                      << section_type << ", so it cannot parse section of type "
                      << section.getType());
 
   auto params = section.getParameters();
   auto it = params.first;
   for (; it != params.second; ++it) {
     parseParam(*it);
   }
 
   auto sit = section.getSubSections().first;
   for (; sit != section.getSubSections().second; ++sit) {
     parseSubSection(*sit);
   }
 }
 
 /* -------------------------------------------------------------------------- */
 void Parsable::parseSubSection(const ParserSection & section) {
   SubSectionKey key(section.getType(), section.getName());
   auto it = sub_sections.find(key);
   if (it != sub_sections.end()) {
     it->second->parseSection(section);
   } else if (!Parser::isPermissive()) {
     AKANTU_EXCEPTION("No parsable defined for sub sections of type <"
                      << key.first << "," << key.second << "> in " << pid);
   } else {
     AKANTU_DEBUG_WARNING("No parsable defined for sub sections of type <"
                          << key.first << "," << key.second << "> in " << pid);
   }
 }
 
 } // akantu
diff --git a/src/io/parser/parsable.hh b/src/io/parser/parsable.hh
index 5eb45a4e8..542c64769 100644
--- a/src/io/parser/parsable.hh
+++ b/src/io/parser/parsable.hh
@@ -1,74 +1,73 @@
 /**
- * @file   parameter_registry.hh
+ * @file   parsable.hh
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Thu Aug 09 2012
- * @date last modification: Thu Dec 17 2015
+ * @date last modification: Fri Dec 08 2017
  *
  * @brief  Interface of the parameter registry
  *
  * @section LICENSE
  *
- * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
- * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
- * Solides)
+ * 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
+ * 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
+ * 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 "parameter_registry.hh"
 #include "parser.hh"
 /* -------------------------------------------------------------------------- */
 
 #ifndef __AKANTU_PARSABLE_HH__
 #define __AKANTU_PARSABLE_HH__
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 /* Parsable Interface                                                         */
 /* -------------------------------------------------------------------------- */
 /// Defines interface for classes to manipulate parsable parameters
 class Parsable : public ParameterRegistry {
 public:
   Parsable(const ParserType & section_type, const ID & id = std::string());
   ~Parsable() override;
 
   /// Add subsection to the sub_sections map
   void registerSubSection(const ParserType & type, const std::string & name,
                           Parsable & sub_section);
 
   /* ------------------------------------------------------------------------ */
 public:
   virtual void parseSection(const ParserSection & section);
   virtual void parseSubSection(const ParserSection & section);
   virtual void parseParam(const ParserParameter & parameter);
 
 private:
   ParserType section_type;
   /// ID of parsable object
   ID pid;
   using SubSectionKey = std::pair<ParserType, std::string>;
   using SubSections = std::map<SubSectionKey, Parsable *>;
   /// Subsections map
   SubSections sub_sections;
 };
 
 } // namespace akantu
 
 #endif /* __AKANTU_PARSABLE_HH__ */
diff --git a/src/io/parser/parser.cc b/src/io/parser/parser.cc
index b21c0db0f..30b34ad8c 100644
--- a/src/io/parser/parser.cc
+++ b/src/io/parser/parser.cc
@@ -1,101 +1,101 @@
 /**
  * @file   parser.cc
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Wed Nov 13 2013
- * @date last modification: Wed Jan 13 2016
+ * @date last modification: Thu Feb 01 2018
  *
  * @brief  implementation of the parser
  *
  * @section LICENSE
  *
- * Copyright  (©)  2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de Lausanne)
+ * 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
+ * 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
+ * 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/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 // STL
 #include <fstream>
 #include <iomanip>
 #include <map>
 
 /* -------------------------------------------------------------------------- */
 #include "aka_common.hh"
 #include "parser.hh"
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 ParserSection::~ParserSection() { this->clean(); }
 
 /* -------------------------------------------------------------------------- */
 ParserParameter & ParserSection::addParameter(const ParserParameter & param) {
   if (parameters.find(param.getName()) != parameters.end())
     AKANTU_EXCEPTION("The parameter \"" + param.getName() +
                      "\" is already defined in this section");
 
   return (parameters
               .insert(std::pair<std::string, ParserParameter>(param.getName(),
                                                               param))
               .first->second);
 }
 
 /* -------------------------------------------------------------------------- */
 ParserSection & ParserSection::addSubSection(const ParserSection & section) {
   return ((sub_sections_by_type.insert(std::pair<ParserType, ParserSection>(
                section.getType(), section)))
               ->second);
 }
 
 /* -------------------------------------------------------------------------- */
 std::string Parser::getLastParsedFile() const { return last_parsed_file; }
 
 /* -------------------------------------------------------------------------- */
 void ParserSection::printself(std::ostream & stream,
                               unsigned int indent) const {
   std::string space;
   std::string ind = AKANTU_INDENT;
   for (unsigned int i = 0; i < indent; i++, space += ind)
     ;
 
   stream << space << "Section(" << this->type << ") " << this->name
          << (option != "" ? (" " + option) : "") << " [" << std::endl;
   if (!this->parameters.empty()) {
     stream << space << ind << "Parameters [" << std::endl;
     auto pit = this->parameters.begin();
     for (; pit != this->parameters.end(); ++pit) {
       stream << space << ind << " + ";
       pit->second.printself(stream);
       stream << std::endl;
     }
     stream << space << ind << "]" << std::endl;
   }
 
   if (!this->sub_sections_by_type.empty()) {
     stream << space << ind << "Subsections [" << std::endl;
     auto sit = this->sub_sections_by_type.begin();
     for (; sit != this->sub_sections_by_type.end(); ++sit)
       sit->second.printself(stream, indent + 2);
     stream << std::endl;
     stream << space << ind << "]" << std::endl;
   }
   stream << space << "]" << std::endl;
 }
 
 } // akantu
diff --git a/src/io/parser/parser.hh b/src/io/parser/parser.hh
index d97850eef..c762f0493 100644
--- a/src/io/parser/parser.hh
+++ b/src/io/parser/parser.hh
@@ -1,506 +1,506 @@
 /**
  * @file   parser.hh
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Wed Nov 13 2013
- * @date last modification: Wed Jan 13 2016
+ * @date last modification: Fri Dec 08 2017
  *
  * @brief  File parser interface
  *
  * @section LICENSE
  *
- * Copyright  (©)  2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de Lausanne)
+ * 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
+ * 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
+ * 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 "aka_random_generator.hh"
 /* -------------------------------------------------------------------------- */
 #include <map>
 /* -------------------------------------------------------------------------- */
 
 #ifndef __AKANTU_PARSER_HH__
 #define __AKANTU_PARSER_HH__
 
 namespace akantu {
 
 // clang-format off
 #define AKANTU_SECTION_TYPES                                            \
   (cohesive_inserter)                                                   \
   (contact)                                                             \
   (embedded_interface)                                                  \
   (friction)                                                            \
   (global)                                                              \
   (heat)                                                                \
   (integration_scheme)                                                  \
   (material)                                                            \
   (mesh)                                                                \
   (model)                                                               \
   (model_solver)                                                        \
   (neighborhood)                                                        \
   (neighborhoods)                                                       \
   (non_linear_solver)                                                   \
   (non_local)                                                           \
   (rules)                                                               \
   (solver)                                                              \
   (time_step_solver)                                                    \
   (user)                                                                \
   (weight_function)                                                     \
   (not_defined)
 // clang-format on
 
 /// Defines the possible section types
 AKANTU_ENUM_DECLARE(ParserType, AKANTU_SECTION_TYPES)
 AKANTU_ENUM_OUTPUT_STREAM(ParserType, AKANTU_SECTION_TYPES)
 AKANTU_ENUM_INPUT_STREAM(ParserType, AKANTU_SECTION_TYPES)
 
 /// Defines the possible search contexts/scopes (for parameter search)
 enum ParserParameterSearchCxt {
   _ppsc_current_scope = 0x1,
   _ppsc_parent_scope = 0x2,
   _ppsc_current_and_parent_scope = 0x3
 };
 
 /* ------------------------------------------------------------------------ */
 /* Parameters Class                                                         */
 /* ------------------------------------------------------------------------ */
 class ParserSection;
 
 /// @brief The ParserParameter objects represent the end of tree branches as
 /// they
 /// are the different informations contained in the input file.
 class ParserParameter {
 public:
   ParserParameter()
       : name(std::string()), value(std::string()), dbg_filename(std::string()) {
   }
 
   ParserParameter(const std::string & name, const std::string & value,
                   const ParserSection & parent_section)
       : parent_section(&parent_section), name(name), value(value),
         dbg_filename(std::string()) {}
 
   ParserParameter(const ParserParameter & param) = default;
 
   virtual ~ParserParameter() = default;
 
   /// Get parameter name
   const std::string & getName() const { return name; }
   /// Get parameter value
   const std::string & getValue() const { return value; }
 
   /// Set info for debug output
   void setDebugInfo(const std::string & filename, UInt line, UInt column) {
     dbg_filename = filename;
     dbg_line = line;
     dbg_column = column;
   }
 
   template <typename T> inline operator T() const;
 
   // template <typename T> inline operator Vector<T>() const;
   // template <typename T> inline operator Matrix<T>() const;
 
   /// Print parameter info in stream
   void printself(std::ostream & stream,
                  __attribute__((unused)) unsigned int indent = 0) const {
     stream << name << ": " << value << " (" << dbg_filename << ":" << dbg_line
            << ":" << dbg_column << ")";
   }
 
 private:
   void setParent(const ParserSection & sect) { parent_section = &sect; }
 
   friend class ParserSection;
 
 private:
   /// Pointer to the parent section
   const ParserSection * parent_section{nullptr};
   /// Name of the parameter
   std::string name;
   /// Value of the parameter
   std::string value;
   /// File for debug output
   std::string dbg_filename;
   /// Position of parameter in parsed file
   UInt dbg_line, dbg_column;
 };
 
 /* ------------------------------------------------------------------------ */
 /* Sections Class                                                           */
 /* ------------------------------------------------------------------------ */
 /// ParserSection represents a branch of the parsing tree.
 class ParserSection {
 public:
   using SubSections = std::multimap<ParserType, ParserSection>;
   using Parameters = std::map<std::string, ParserParameter>;
 
 private:
   using const_section_iterator_ = SubSections::const_iterator;
 
 public:
   /* ------------------------------------------------------------------------ */
   /* SubSection iterator                                                      */
   /* ------------------------------------------------------------------------ */
   /// Iterator on sections
   class const_section_iterator {
   public:
     using iterator_category = std::forward_iterator_tag;
     using value_type = ParserSection;
     using pointer = ParserSection *;
     using reference = ParserSection &;
 
     const_section_iterator() = default;
     const_section_iterator(const const_section_iterator_ & it) : it(it) {}
     const_section_iterator(const const_section_iterator & other) = default;
     const_section_iterator &
     operator=(const const_section_iterator & other) = default;
 
     const ParserSection & operator*() const { return it->second; }
     const ParserSection * operator->() const { return &(it->second); }
 
     bool operator==(const const_section_iterator & other) const {
       return it == other.it;
     }
 
     bool operator!=(const const_section_iterator & other) const {
       return it != other.it;
     }
 
     const_section_iterator & operator++() {
       ++it;
       return *this;
     }
 
     const_section_iterator operator++(int) {
       const_section_iterator tmp = *this;
       operator++();
       return tmp;
     }
 
   private:
     const_section_iterator_ it;
   };
 
   /* ------------------------------------------------------------------------ */
   /* Parameters iterator                                                      */
   /* ------------------------------------------------------------------------ */
   /// Iterator on parameters
   class const_parameter_iterator {
   public:
     const_parameter_iterator(const const_parameter_iterator & other) = default;
     const_parameter_iterator(const Parameters::const_iterator & it) : it(it) {}
 
     const_parameter_iterator &
     operator=(const const_parameter_iterator & other) {
       if (this != &other) {
         it = other.it;
       }
       return *this;
     }
     const ParserParameter & operator*() const { return it->second; }
     const ParserParameter * operator->() { return &(it->second); };
     bool operator==(const const_parameter_iterator & other) const {
       return it == other.it;
     }
     bool operator!=(const const_parameter_iterator & other) const {
       return it != other.it;
     }
     const_parameter_iterator & operator++() {
       ++it;
       return *this;
     }
     const_parameter_iterator operator++(int) {
       const_parameter_iterator tmp = *this;
       operator++();
       return tmp;
     }
 
   private:
     Parameters::const_iterator it;
   };
 
   /* ---------------------------------------------------------------------- */
   ParserSection() : name(std::string()) {}
 
   ParserSection(const std::string & name, ParserType type)
       : parent_section(nullptr), name(name), type(type) {}
 
   ParserSection(const std::string & name, ParserType type,
                 const std::string & option,
                 const ParserSection & parent_section)
       : parent_section(&parent_section), name(name), type(type),
         option(option) {}
 
   ParserSection(const ParserSection & section)
       : parent_section(section.parent_section), name(section.name),
         type(section.type), option(section.option),
         parameters(section.parameters),
         sub_sections_by_type(section.sub_sections_by_type) {
     setChldrenPointers();
   }
 
   ParserSection & operator=(const ParserSection & other) {
     if (&other != this) {
       parent_section = other.parent_section;
       name = other.name;
       type = other.type;
       option = other.option;
       parameters = other.parameters;
       sub_sections_by_type = other.sub_sections_by_type;
       setChldrenPointers();
     }
     return *this;
   }
 
   virtual ~ParserSection();
 
   virtual void printself(std::ostream & stream, unsigned int indent = 0) const;
 
   /* ---------------------------------------------------------------------- */
   /* Creation functions                                                     */
   /* ---------------------------------------------------------------------- */
 public:
   ParserParameter & addParameter(const ParserParameter & param);
   ParserSection & addSubSection(const ParserSection & section);
 
 protected:
   /// Clean ParserSection content
   void clean() {
     parameters.clear();
     sub_sections_by_type.clear();
   }
 
 private:
   void setChldrenPointers() {
     for (auto && param_pair : this->parameters)
       param_pair.second.setParent(*this);
 
     for (auto && sub_sect_pair : this->sub_sections_by_type)
       sub_sect_pair.second.setParent(*this);
   }
 
   /* ---------------------------------------------------------------------- */
   /* Accessors                                                              */
   /* ---------------------------------------------------------------------- */
 public:
   class SubSectionsRange
       : public std::pair<const_section_iterator, const_section_iterator> {
   public:
     SubSectionsRange(const const_section_iterator & first,
                      const const_section_iterator & second)
         : std::pair<const_section_iterator, const_section_iterator>(first,
                                                                     second) {}
     auto begin() { return this->first; }
     auto end() { return this->second; }
   };
 
   /// Get begin and end iterators on subsections of certain type
   auto getSubSections(ParserType type = ParserType::_not_defined) const {
     if (type != ParserType::_not_defined) {
       auto range = sub_sections_by_type.equal_range(type);
       return SubSectionsRange(range.first, range.second);
     } else {
       return SubSectionsRange(sub_sections_by_type.begin(),
                               sub_sections_by_type.end());
     }
   }
 
   /// Get number of subsections of certain type
   UInt getNbSubSections(ParserType type = ParserType::_not_defined) const {
     if (type != ParserType::_not_defined) {
       return this->sub_sections_by_type.count(type);
     } else {
       return this->sub_sections_by_type.size();
     }
   }
 
   /// Get begin and end iterators on parameters
   auto getParameters() const {
     return std::pair<const_parameter_iterator, const_parameter_iterator>(
         parameters.begin(), parameters.end());
   }
 
   /* ---------------------------------------------------------------------- */
   /// Get parameter within specified context
   const ParserParameter & getParameter(
       const std::string & name,
       ParserParameterSearchCxt search_ctx = _ppsc_current_scope) const {
     Parameters::const_iterator it;
     if (search_ctx & _ppsc_current_scope)
       it = parameters.find(name);
 
     if (it == parameters.end()) {
       if ((search_ctx & _ppsc_parent_scope) && parent_section)
         return parent_section->getParameter(name, search_ctx);
       else {
         AKANTU_SILENT_EXCEPTION(
             "The parameter " << name
                              << " has not been found in the specified context");
       }
     }
     return it->second;
   }
 
   /* ------------------------------------------------------------------------ */
   /// Get parameter within specified context, with a default value in case the
   /// parameter does not exists
   template <class T>
   const T getParameter(
       const std::string & name, const T & default_value,
       ParserParameterSearchCxt search_ctx = _ppsc_current_scope) const {
     try {
       T tmp = this->getParameter(name, search_ctx);
       return tmp;
     } catch (debug::Exception &) {
       return default_value;
     }
   }
 
   /* ------------------------------------------------------------------------ */
   /// Check if parameter exists within specified context
   bool hasParameter(
       const std::string & name,
       ParserParameterSearchCxt search_ctx = _ppsc_current_scope) const {
 
     Parameters::const_iterator it;
     if (search_ctx & _ppsc_current_scope)
       it = parameters.find(name);
 
     if (it == parameters.end()) {
       if ((search_ctx & _ppsc_parent_scope) && parent_section)
         return parent_section->hasParameter(name, search_ctx);
       else {
         return false;
       }
     }
     return true;
   }
 
   /* --------------------------------------------------------------------------
    */
   /// Get value of given parameter in context
   template <class T>
   T getParameterValue(
       const std::string & name,
       ParserParameterSearchCxt search_ctx = _ppsc_current_scope) const {
     const ParserParameter & tmp_param = getParameter(name, search_ctx);
     T t = tmp_param;
     return t;
   }
 
   /* --------------------------------------------------------------------------
    */
   /// Get section name
   const std::string getName() const { return name; }
   /// Get section type
   ParserType getType() const { return type; }
   /// Get section option
   const std::string getOption(const std::string & def = "") const {
     return option != "" ? option : def;
   }
 
 protected:
   void setParent(const ParserSection & sect) { parent_section = &sect; }
 
   /* ---------------------------------------------------------------------- */
   /* Members                                                                */
   /* ---------------------------------------------------------------------- */
 private:
   /// Pointer to the parent section
   const ParserSection * parent_section{nullptr};
   /// Name of section
   std::string name;
   /// Type of section, see AKANTU_SECTION_TYPES
   ParserType type{ParserType::_not_defined};
   /// Section option
   std::string option;
   /// Map of parameters in section
   Parameters parameters;
   /// Multi-map of subsections
   SubSections sub_sections_by_type;
 };
 
 /* ------------------------------------------------------------------------ */
 /* Parser Class                                                             */
 /* ------------------------------------------------------------------------ */
 /// Root of parsing tree, represents the global ParserSection
 class Parser : public ParserSection {
 public:
   Parser() : ParserSection("global", ParserType::_global) {}
 
   void parse(const std::string & filename);
 
   std::string getLastParsedFile() const;
 
   static bool isPermissive() { return permissive_parser; }
 
 public:
   /// Parse real scalar
   static Real parseReal(const std::string & value,
                         const ParserSection & section);
   /// Parse real vector
   static Vector<Real> parseVector(const std::string & value,
                                   const ParserSection & section);
   /// Parse real matrix
   static Matrix<Real> parseMatrix(const std::string & value,
                                   const ParserSection & section);
   /// Parse real random parameter
   static RandomParameter<Real>
   parseRandomParameter(const std::string & value,
                        const ParserSection & section);
 
 protected:
   /// General parse function
   template <class T, class Grammar>
   static T parseType(const std::string & value, Grammar & grammar);
 
 protected:
   //  friend class Parsable;
   static bool permissive_parser;
   std::string last_parsed_file;
 };
 
 inline std::ostream & operator<<(std::ostream & stream,
                                  const ParserParameter & _this) {
   _this.printself(stream);
   return stream;
 }
 
 inline std::ostream & operator<<(std::ostream & stream,
                                  const ParserSection & section) {
   section.printself(stream);
   return stream;
 }
 
 } // akantu
 
 namespace std {
 template <> struct iterator_traits<::akantu::Parser::const_section_iterator> {
   using iterator_category = input_iterator_tag;
   using value_type = ::akantu::ParserParameter;
   using difference_type = ptrdiff_t;
   using pointer = const ::akantu::ParserParameter *;
   using reference = const ::akantu::ParserParameter &;
 };
 }
 
 #include "parser_tmpl.hh"
 
 #endif /* __AKANTU_PARSER_HH__ */
diff --git a/src/io/parser/parser_grammar_tmpl.hh b/src/io/parser/parser_grammar_tmpl.hh
index 9174f2529..d957801b7 100644
--- a/src/io/parser/parser_grammar_tmpl.hh
+++ b/src/io/parser/parser_grammar_tmpl.hh
@@ -1,81 +1,82 @@
 /**
  * @file   parser_grammar_tmpl.hh
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Wed Nov 11 2015
+ * @date last modification: Sun Dec 03 2017
  *
  * @brief  implementation of the templated part of ParsableParam Parsable and
  * ParsableParamTyped
  *
  * @section LICENSE
  *
- * Copyright (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne) Laboratory
- * (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * Copyright (©) 2015-2018 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
- * terms  of the  GNU Lesser  General Public  License as  published by  the Free
+ * 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
+ * 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 <boost/config/warning_disable.hpp>
 #include <boost/spirit/include/classic_position_iterator.hpp>
 #include <boost/spirit/include/qi.hpp>
 #include <boost/spirit/include/support_multi_pass.hpp>
 /* -------------------------------------------------------------------------- */
 
 #ifndef AKANTU_PARSER_GRAMMAR_TMPL_HH
 #define AKANTU_PARSER_GRAMMAR_TMPL_HH
 
 namespace akantu {
 
 namespace qi = boost::spirit::qi;
 
 /* -------------------------------------------------------------------------- */
 template <class T, class Grammar>
 T Parser::parseType(const std::string & value, Grammar & grammar) {
   using boost::spirit::ascii::space;
 
   std::string::const_iterator b = value.begin();
   std::string::const_iterator e = value.end();
 
   T resultat = T();
   bool res = false;
   try {
     res = qi::phrase_parse(b, e, grammar, space, resultat);
   } catch (debug::Exception & ex) {
     AKANTU_EXCEPTION("Could not parse '"
                      << value << "' as a " << debug::demangle(typeid(T).name())
                      << ", an unknown error append '" << ex.what());
   }
 
   if (!res || (b != e)) {
     AKANTU_EXCEPTION("Could not parse '"
                      << value << "' as a " << debug::demangle(typeid(T).name())
                      << ", an unknown error append '"
                      << std::string(value.begin(), b) << "<HERE>"
                      << std::string(b, e) << "'");
   }
   return resultat;
 }
 
 namespace parser {
   template <class Iterator> struct Skipper {
     using type = qi::rule<Iterator, void()>;
   };
 }
 
 } // akantu
 
 #endif // AKANTU_PARSER_GRAMMAR_TMPL_HH
diff --git a/src/io/parser/parser_input_files.cc b/src/io/parser/parser_input_files.cc
index 06d388c56..c3016a000 100644
--- a/src/io/parser/parser_input_files.cc
+++ b/src/io/parser/parser_input_files.cc
@@ -1,119 +1,119 @@
 /**
  * @file   parser_input_files.cc
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Wed Nov 11 2015
- * @date last modification: Wed Jan 13 2016
+ * @date last modification: Wed Nov 08 2017
  *
  * @brief  implementation of the parser
  *
  * @section LICENSE
  *
- * Copyright (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne) Laboratory
- * (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * Copyright (©) 2015-2018 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
- * terms  of the  GNU Lesser  General Public  License as  published by  the Free
+ * 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
+ * A PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 #if defined(__INTEL_COMPILER)
 //#pragma warning ( disable : 383 )
 #elif defined(__clang__) // test clang to be sure that when we test for gnu it
-                         // is only gnu
+// is only gnu
 #elif (defined(__GNUC__) || defined(__GNUG__))
 #define GCC_VERSION                                                            \
   (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__)
 #if GCC_VERSION > 40600
 #pragma GCC diagnostic push
 #endif
 #pragma GCC diagnostic ignored "-Wunused-local-typedefs"
 #endif
 
 /* -------------------------------------------------------------------------- */
 #include "parser.hh"
 #include "parser_grammar_tmpl.hh"
 /* -------------------------------------------------------------------------- */
 #include "input_file_parser.hh"
 /* -------------------------------------------------------------------------- */
 #include <fstream>
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 void Parser::parse(const std::string & filename) {
   this->clean();
   std::ifstream input(filename.c_str());
 
   if (!input.good()) {
     AKANTU_EXCEPTION("Could not open file " << filename << "!");
   }
 
   input.unsetf(std::ios::skipws);
 
   // wrap istream into iterator
   spirit::istream_iterator fwd_begin(input);
   spirit::istream_iterator fwd_end;
 
   // wrap forward iterator with position iterator, to record the position
   using pos_iterator_type =
       spirit::classic::position_iterator2<spirit::istream_iterator>;
   pos_iterator_type position_begin(fwd_begin, fwd_end, filename);
   pos_iterator_type position_end;
 
   // parse
   parser::InputFileGrammar<pos_iterator_type> ag(this);
 
   bool result = qi::phrase_parse(position_begin, position_end, ag, ag.skipper);
 
   if (!result || position_begin != position_end) {
     spirit::classic::file_position pos = position_begin.get_position();
 
     AKANTU_EXCEPTION("Parse error [ "
                      << ag.getErrorMessage() << " ]"
                      << " in file " << filename << " line " << pos.line
                      << " column " << pos.column << std::endl
                      << "'" << position_begin.get_currentline() << "'"
                      << std::endl
                      << std::setw(pos.column) << " "
                      << "^- here");
   }
 
   try {
     bool permissive = getParameter("permissive_parser", _ppsc_current_scope);
 
     permissive_parser = permissive;
     AKANTU_DEBUG_INFO("Parser switched permissive mode to "
                       << std::boolalpha << permissive_parser);
   } catch (debug::Exception & e) {
   }
 
   last_parsed_file = filename;
   input.close();
 }
 
 } // akantu
 
 #if defined(__INTEL_COMPILER)
 //#pragma warning ( disable : 383 )
 #elif defined(__clang__) // test clang to be sure that when we test for gnu it
-                         // is only gnu
+// is only gnu
 #elif defined(__GNUG__)
 #if GCC_VERSION > 40600
 #pragma GCC diagnostic pop
 #else
 #pragma GCC diagnostic warning "-Wunused-local-typedefs"
 #endif
 #endif
diff --git a/src/io/parser/parser_random.cc b/src/io/parser/parser_random.cc
index 40b05fe81..46714a06e 100644
--- a/src/io/parser/parser_random.cc
+++ b/src/io/parser/parser_random.cc
@@ -1,109 +1,109 @@
 /**
  * @file   parser_random.cc
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
- * @date creation: Thu Feb 21 2013
- * @date last modification: Mon Dec 07 2015
+ * @date creation: Fri Jun 18 2010
+ * @date last modification: Sun Jul 09 2017
  *
  * @brief  implementation of the parser
  *
  * @section LICENSE
  *
- * Copyright  (©)  2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de Lausanne)
+ * 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
+ * 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
+ * A PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 #if defined(__INTEL_COMPILER)
 //#pragma warning ( disable : 383 )
 #elif defined(__clang__) // test clang to be sure that when we test for gnu it
 // is only gnu
 #elif (defined(__GNUC__) || defined(__GNUG__))
 #define GCC_VERSION                                                            \
   (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__)
 #if GCC_VERSION > 40600
 #pragma GCC diagnostic push
 #endif
 #pragma GCC diagnostic ignored "-Wunused-local-typedefs"
 #endif
 
 /* -------------------------------------------------------------------------- */
 #include "parser.hh"
 #include "parser_grammar_tmpl.hh"
 /* -------------------------------------------------------------------------- */
 #include "algebraic_parser.hh"
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 RandomParameter<Real>
 Parser::parseRandomParameter(const std::string & value,
                              const ParserSection & section) {
   using boost::spirit::ascii::space_type;
   parser::RandomGeneratorGrammar<std::string::const_iterator, space_type>
       grammar(section);
   grammar.name("random_grammar");
   parser::ParsableRandomGenerator rg =
       Parser::parseType<parser::ParsableRandomGenerator>(value, grammar);
   Vector<Real> params = rg.parameters;
 
   switch (rg.type) {
   case _rdt_not_defined:
     return RandomParameter<Real>(rg.base,
                                  std::uniform_real_distribution<Real>(0, 0));
   case _rdt_uniform:
     return RandomParameter<Real>(
         rg.base, std::uniform_real_distribution<Real>(params(0), params(1)));
   case _rdt_exponential:
     return RandomParameter<Real>(
         rg.base, std::exponential_distribution<Real>(params(0)));
   case _rdt_gamma:
     return RandomParameter<Real>(
         rg.base, std::gamma_distribution<Real>(params(0), params(1)));
   case _rdt_weibull:
     return RandomParameter<Real>(
         rg.base, std::weibull_distribution<Real>(params(1), params(0)));
   case _rdt_extreme_value:
     return RandomParameter<Real>(
         rg.base, std::extreme_value_distribution<Real>(params(0), params(1)));
   case _rdt_normal:
     return RandomParameter<Real>(
         rg.base, std::normal_distribution<Real>(params(0), params(1)));
   case _rdt_lognormal:
     return RandomParameter<Real>(
         rg.base, std::lognormal_distribution<Real>(params(0), params(1)));
   case _rdt_chi_squared:
     return RandomParameter<Real>(
         rg.base, std::chi_squared_distribution<Real>(params(0)));
   case _rdt_cauchy:
     return RandomParameter<Real>(
         rg.base, std::cauchy_distribution<Real>(params(0), params(1)));
   case _rdt_fisher_f:
     return RandomParameter<Real>(
         rg.base, std::fisher_f_distribution<Real>(params(0), params(1)));
   case _rdt_student_t:
     return RandomParameter<Real>(rg.base,
                                  std::student_t_distribution<Real>(params(0)));
   default:
     AKANTU_EXCEPTION("This is an unknown random distribution in the parser");
   }
 }
 
 /* -------------------------------------------------------------------------- */
 
 } // namespace akantu
diff --git a/src/io/parser/parser_real.cc b/src/io/parser/parser_real.cc
index 423307831..0c8471c13 100644
--- a/src/io/parser/parser_real.cc
+++ b/src/io/parser/parser_real.cc
@@ -1,63 +1,63 @@
 /**
  * @file   parser_real.cc
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
- * @date creation: Thu Feb 21 2013
- * @date last modification: Wed Nov 11 2015
+ * @date creation: Mon Dec 13 2010
+ * @date last modification: Mon Jun 19 2017
  *
  * @brief  implementation of the parser
  *
  * @section LICENSE
  *
- * Copyright  (©)  2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de Lausanne)
+ * 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
+ * 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
+ * A PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 #if defined(__INTEL_COMPILER)
 //#pragma warning ( disable : 383 )
 #elif defined(__clang__) // test clang to be sure that when we test for gnu it
-                         // is only gnu
+// is only gnu
 #elif (defined(__GNUC__) || defined(__GNUG__))
 #define GCC_VERSION                                                            \
   (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__)
 #if GCC_VERSION > 40600
 #pragma GCC diagnostic push
 #endif
 #pragma GCC diagnostic ignored "-Wunused-local-typedefs"
 #endif
 
 /* -------------------------------------------------------------------------- */
 #include "parser.hh"
 #include "parser_grammar_tmpl.hh"
 /* -------------------------------------------------------------------------- */
 #include "algebraic_parser.hh"
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 Real Parser::parseReal(const std::string & value,
                        const ParserSection & section) {
   using boost::spirit::ascii::space_type;
   parser::AlgebraicGrammar<std::string::const_iterator, space_type> grammar(
       section);
   grammar.name("algebraic_grammar");
   return Parser::parseType<Real>(value, grammar);
 }
 
 } // akantu
diff --git a/src/io/parser/parser_tmpl.hh b/src/io/parser/parser_tmpl.hh
index c65c8d82c..f3ba422c9 100644
--- a/src/io/parser/parser_tmpl.hh
+++ b/src/io/parser/parser_tmpl.hh
@@ -1,111 +1,112 @@
 /**
  * @file   parser_tmpl.hh
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Wed Nov 13 2013
- * @date last modification: Wed Apr 22 2015
+ * @date last modification: Mon Dec 18 2017
  *
  * @brief  Implementation of the parser templated methods
  *
  * @section LICENSE
  *
- * Copyright  (©)  2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de Lausanne)
+ * 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
+ * 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
+ * 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 <regex>
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 template <typename T> inline ParserParameter::operator T() const {
   T t;
   std::stringstream sstr(value);
   sstr >> t;
   if (sstr.bad())
     AKANTU_EXCEPTION("No known conversion of a ParserParameter \""
                      << name << "\" to the type " << typeid(T).name());
   return t;
 }
 
 /* -------------------------------------------------------------------------- */
 template <> inline ParserParameter::operator const char *() const {
   return value.c_str();
 }
 
 /* -------------------------------------------------------------------------- */
 template <> inline ParserParameter::operator Real() const {
   return Parser::parseReal(value, *parent_section);
 }
 
 /* --------------------------------------------------------- -----------------
  */
 template <> inline ParserParameter::operator bool() const {
   bool b;
   std::stringstream sstr(value);
   sstr >> std::boolalpha >> b;
   if (sstr.fail()) {
     sstr.clear();
     sstr >> std::noboolalpha >> b;
   }
   return b;
 }
 
 /* -------------------------------------------------------------------------- */
 template <> inline ParserParameter::operator std::vector<std::string>() const {
   std::vector<std::string> tmp;
   auto string =
       std::regex_replace(value, std::regex("[[:space:]]|\\[|\\]"), "");
   std::smatch sm;
   while (std::regex_search(string, sm, std::regex("[^,]+"))) {
     tmp.push_back(sm.str());
     string = sm.suffix();
   }
   return tmp;
 }
 
 /* --------------------------------------------------------- -----------------
  */
 template <> inline ParserParameter::operator Vector<Real>() const {
   return Parser::parseVector(value, *parent_section);
 }
 
 /* --------------------------------------------------------- -----------------
  */
 template <> inline ParserParameter::operator Vector<UInt>() const {
   Vector<Real> tmp = Parser::parseVector(value, *parent_section);
   Vector<UInt> tmp_uint(tmp.size());
   for (UInt i = 0; i < tmp.size(); ++i) {
     tmp_uint(i) = UInt(tmp(i));
   }
   return tmp_uint;
 }
 
 /* --------------------------------------------------------- -----------------
  */
 template <> inline ParserParameter::operator Matrix<Real>() const {
   return Parser::parseMatrix(value, *parent_section);
 }
 
 /* -------------------------------------------------------------------------- */
 template <> inline ParserParameter::operator RandomParameter<Real>() const {
   return Parser::parseRandomParameter(value, *parent_section);
 }
 
 } // akantu
diff --git a/src/io/parser/parser_types.cc b/src/io/parser/parser_types.cc
index 34bde6424..2b60bfdbd 100644
--- a/src/io/parser/parser_types.cc
+++ b/src/io/parser/parser_types.cc
@@ -1,75 +1,75 @@
 /**
  * @file   parser_types.cc
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
- * @date creation: Thu Feb 21 2013
- * @date last modification: Wed Nov 11 2015
+ * @date creation: Fri Jun 18 2010
+ * @date last modification: Mon Jun 19 2017
  *
  * @brief  implementation of the parser
  *
  * @section LICENSE
  *
- * Copyright  (©)  2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de Lausanne)
+ * 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
+ * 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
+ * A PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 #if defined(__INTEL_COMPILER)
 //#pragma warning ( disable : 383 )
 #elif defined(__clang__) // test clang to be sure that when we test for gnu it
-                         // is only gnu
+// is only gnu
 #elif (defined(__GNUC__) || defined(__GNUG__))
 #define GCC_VERSION                                                            \
   (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__)
 #if GCC_VERSION > 40600
 #pragma GCC diagnostic push
 #endif
 #pragma GCC diagnostic ignored "-Wunused-local-typedefs"
 #endif
 
 /* -------------------------------------------------------------------------- */
 #include "parser.hh"
 #include "parser_grammar_tmpl.hh"
 /* -------------------------------------------------------------------------- */
 #include "algebraic_parser.hh"
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 Vector<Real> Parser::parseVector(const std::string & value,
                                  const ParserSection & section) {
   using boost::spirit::ascii::space_type;
   parser::VectorGrammar<std::string::const_iterator, space_type> grammar(
       section);
   grammar.name("vector_grammar");
   return Parser::parseType<parser::parsable_vector>(value, grammar);
 }
 
 /* -------------------------------------------------------------------------- */
 Matrix<Real> Parser::parseMatrix(const std::string & value,
                                  const ParserSection & section) {
   using boost::spirit::ascii::space_type;
   parser::MatrixGrammar<std::string::const_iterator, space_type> grammar(
       section);
   grammar.name("matrix_grammar");
   return Parser::parseType<parser::parsable_matrix>(value, grammar);
 }
 
 /* -------------------------------------------------------------------------- */
 
 } // akantu
diff --git a/src/mesh/element_group.cc b/src/mesh/element_group.cc
index 9f0158d7a..ded48bb53 100644
--- a/src/mesh/element_group.cc
+++ b/src/mesh/element_group.cc
@@ -1,203 +1,203 @@
 /**
  * @file   element_group.cc
  *
  * @author Dana Christen <dana.christen@gmail.com>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  * @author Marco Vocialta <marco.vocialta@epfl.ch>
  *
  * @date creation: Wed Nov 13 2013
- * @date last modification: Tue Aug 18 2015
+ * @date last modification: Mon Jan 22 2018
  *
  * @brief  Stores information relevent to the notion of domain boundary and
  * surfaces.
  *
  * @section LICENSE
  *
- * Copyright  (©)  2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de Lausanne)
+ * 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
+ * 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
+ * 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_csr.hh"
 #include "dumpable.hh"
 #include "dumpable_inline_impl.hh"
 #include "group_manager.hh"
 #include "group_manager_inline_impl.cc"
 #include "mesh.hh"
 #include "mesh_utils.hh"
 #include <algorithm>
 #include <iterator>
 #include <sstream>
 
 #include "element_group.hh"
 #if defined(AKANTU_USE_IOHELPER)
 #include "dumper_iohelper_paraview.hh"
 #endif
 
 namespace akantu {
 /* -------------------------------------------------------------------------- */
 ElementGroup::ElementGroup(const std::string & group_name, const Mesh & mesh,
                            NodeGroup & node_group, UInt dimension,
                            const std::string & id, const MemoryID & mem_id)
     : Memory(id, mem_id), mesh(mesh), name(group_name),
       elements("elements", id, mem_id), node_group(node_group),
       dimension(dimension) {
   AKANTU_DEBUG_IN();
 
 #if defined(AKANTU_USE_IOHELPER)
   this->registerDumper<DumperParaview>("paraview_" + group_name, group_name,
                                        true);
   this->addDumpFilteredMesh(mesh, elements, node_group.getNodes(), dimension);
 #endif
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void ElementGroup::empty() { elements.free(); }
 
 /* -------------------------------------------------------------------------- */
 void ElementGroup::append(const ElementGroup & other_group) {
   AKANTU_DEBUG_IN();
 
   node_group.append(other_group.node_group);
 
   /// loop on all element types in all dimensions
   for (ghost_type_t::iterator gt = ghost_type_t::begin();
        gt != ghost_type_t::end(); ++gt) {
 
     GhostType ghost_type = *gt;
 
     type_iterator it =
         other_group.firstType(_all_dimensions, ghost_type, _ek_not_defined);
     type_iterator last =
         other_group.lastType(_all_dimensions, ghost_type, _ek_not_defined);
 
     for (; it != last; ++it) {
       ElementType type = *it;
       const Array<UInt> & other_elem_list =
           other_group.elements(type, ghost_type);
       UInt nb_other_elem = other_elem_list.size();
 
       Array<UInt> * elem_list;
       UInt nb_elem = 0;
 
       /// create current type if doesn't exists, otherwise get information
       if (elements.exists(type, ghost_type)) {
         elem_list = &elements(type, ghost_type);
         nb_elem = elem_list->size();
       } else {
         elem_list = &(elements.alloc(0, 1, type, ghost_type));
       }
 
       /// append new elements to current list
       elem_list->resize(nb_elem + nb_other_elem);
       std::copy(other_elem_list.begin(), other_elem_list.end(),
                 elem_list->begin() + nb_elem);
 
       /// remove duplicates
       std::sort(elem_list->begin(), elem_list->end());
       Array<UInt>::iterator<> end =
           std::unique(elem_list->begin(), elem_list->end());
       elem_list->resize(end - elem_list->begin());
     }
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void ElementGroup::printself(std::ostream & stream, int indent) const {
   std::string space;
   for (Int i = 0; i < indent; i++, space += AKANTU_INDENT)
     ;
 
   stream << space << "ElementGroup [" << std::endl;
   stream << space << " + name: " << name << std::endl;
   stream << space << " + dimension: " << dimension << std::endl;
   elements.printself(stream, indent + 1);
   node_group.printself(stream, indent + 1);
   stream << space << "]" << std::endl;
 }
 
 /* -------------------------------------------------------------------------- */
 void ElementGroup::optimize() {
   // increasing the locality of data when iterating on the element of a group
   for (ghost_type_t::iterator gt = ghost_type_t::begin();
        gt != ghost_type_t::end(); ++gt) {
     GhostType ghost_type = *gt;
     ElementList::type_iterator it =
         elements.firstType(_all_dimensions, ghost_type);
     ElementList::type_iterator last =
         elements.lastType(_all_dimensions, ghost_type);
     for (; it != last; ++it) {
       Array<UInt> & els = elements(*it, ghost_type);
       std::sort(els.begin(), els.end());
 
       Array<UInt>::iterator<> end = std::unique(els.begin(), els.end());
       els.resize(end - els.begin());
     }
   }
 
   node_group.optimize();
 }
 
 /* -------------------------------------------------------------------------- */
 void ElementGroup::fillFromNodeGroup() {
   CSR<Element> node_to_elem;
   MeshUtils::buildNode2Elements(this->mesh, node_to_elem, this->dimension);
 
   std::set<Element> seen;
 
   Array<UInt>::const_iterator<> itn = this->node_group.begin();
   Array<UInt>::const_iterator<> endn = this->node_group.end();
   for (; itn != endn; ++itn) {
     CSR<Element>::iterator ite = node_to_elem.begin(*itn);
     CSR<Element>::iterator ende = node_to_elem.end(*itn);
     for (; ite != ende; ++ite) {
       const Element & elem = *ite;
       if (this->dimension != _all_dimensions &&
           this->dimension != Mesh::getSpatialDimension(elem.type))
         continue;
       if (seen.find(elem) != seen.end())
         continue;
 
       UInt nb_nodes_per_element = Mesh::getNbNodesPerElement(elem.type);
       Array<UInt>::const_iterator<Vector<UInt>> conn_it =
           this->mesh.getConnectivity(elem.type, elem.ghost_type)
               .begin(nb_nodes_per_element);
       const Vector<UInt> & conn = conn_it[elem.element];
 
       UInt count = 0;
       for (UInt n = 0; n < conn.size(); ++n) {
         count +=
             (this->node_group.getNodes().find(conn(n)) != UInt(-1) ? 1 : 0);
       }
 
       if (count == nb_nodes_per_element)
         this->add(elem);
 
       seen.insert(elem);
     }
   }
 
   this->optimize();
 }
 
 /* -------------------------------------------------------------------------- */
 
 } // akantu
diff --git a/src/mesh/element_group.hh b/src/mesh/element_group.hh
index fe47dc7d2..64615adaf 100644
--- a/src/mesh/element_group.hh
+++ b/src/mesh/element_group.hh
@@ -1,190 +1,190 @@
 /**
  * @file   element_group.hh
  *
  * @author Dana Christen <dana.christen@gmail.com>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Fri May 03 2013
- * @date last modification: Tue Aug 18 2015
+ * @date last modification: Wed Nov 08 2017
  *
  * @brief  Stores information relevent to the notion of domain boundary and
  * surfaces.
  *
  * @section LICENSE
  *
- * Copyright  (©)  2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de Lausanne)
+ * 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
+ * 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
+ * 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 "aka_memory.hh"
 #include "dumpable.hh"
 #include "element_type_map.hh"
 #include "node_group.hh"
 /* -------------------------------------------------------------------------- */
 #include <set>
 /* -------------------------------------------------------------------------- */
 
 #ifndef __AKANTU_ELEMENT_GROUP_HH__
 #define __AKANTU_ELEMENT_GROUP_HH__
 
 namespace akantu {
 class Mesh;
 class Element;
 } // namespace akantu
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 class ElementGroup : private Memory, public Dumpable {
 
   /* ------------------------------------------------------------------------ */
   /* Constructors/Destructors                                                 */
   /* ------------------------------------------------------------------------ */
 public:
   ElementGroup(const std::string & name, const Mesh & mesh,
                NodeGroup & node_group, UInt dimension = _all_dimensions,
                const std::string & id = "element_group",
                const MemoryID & memory_id = 0);
 
   /* ------------------------------------------------------------------------ */
   /* Type definitions                                                         */
   /* ------------------------------------------------------------------------ */
 public:
   using ElementList = ElementTypeMapArray<UInt>;
   using NodeList = Array<UInt>;
 
   /* ------------------------------------------------------------------------ */
   /* Element iterator                                                         */
   /* ------------------------------------------------------------------------ */
   using type_iterator = ElementList::type_iterator;
   inline type_iterator firstType(UInt dim = _all_dimensions,
                                  const GhostType & ghost_type = _not_ghost,
                                  const ElementKind & kind = _ek_regular) const;
 
   inline type_iterator lastType(UInt dim = _all_dimensions,
                                 const GhostType & ghost_type = _not_ghost,
                                 const ElementKind & kind = _ek_regular) const;
 
 #ifndef SWIG
   template <typename... pack>
   inline decltype(auto) elementTypes(pack &&... _pack) const {
     return elements.elementTypes(_pack...);
   }
 #endif
 
   using const_element_iterator = Array<UInt>::const_iterator<UInt>;
   inline const_element_iterator
   begin(const ElementType & type,
         const GhostType & ghost_type = _not_ghost) const;
   inline const_element_iterator
   end(const ElementType & type,
       const GhostType & ghost_type = _not_ghost) const;
 
   /* ------------------------------------------------------------------------ */
   /* Methods                                                                  */
   /* ------------------------------------------------------------------------ */
 public:
   /// empty the element group
   void empty();
 
   /// append another group to this group
   /// BE CAREFUL: it doesn't conserve the element order
   void append(const ElementGroup & other_group);
 
   /// add an element to the group. By default the it does not add the nodes to
   /// the group
   inline void add(const Element & el, bool add_nodes = false,
                   bool check_for_duplicate = true);
 
   /// \todo fix the default for add_nodes : make it coherent with the other
   /// method
   inline void add(const ElementType & type, UInt element,
                   const GhostType & ghost_type = _not_ghost,
                   bool add_nodes = true, bool check_for_duplicate = true);
 
   inline void addNode(UInt node_id, bool check_for_duplicate = true);
 
   inline void removeNode(UInt node_id);
 
   /// function to print the contain of the class
   virtual void printself(std::ostream & stream, int indent = 0) const;
 
   /// fill the elements based on the underlying node group.
   virtual void fillFromNodeGroup();
 
   // sort and remove duplicated values
   void optimize();
 
 private:
   inline void addElement(const ElementType & elem_type, UInt elem_id,
                          const GhostType & ghost_type);
 
   friend class GroupManager;
 
   /* ------------------------------------------------------------------------ */
   /* Accessors                                                                */
   /* ------------------------------------------------------------------------ */
 public:
   const Array<UInt> &
   getElements(const ElementType & type,
               const GhostType & ghost_type = _not_ghost) const;
   AKANTU_GET_MACRO(Elements, elements, const ElementTypeMapArray<UInt> &);
   AKANTU_GET_MACRO(Nodes, node_group.getNodes(), const Array<UInt> &);
   AKANTU_GET_MACRO(NodeGroup, node_group, const NodeGroup &);
   AKANTU_GET_MACRO_NOT_CONST(NodeGroup, node_group, NodeGroup &);
   AKANTU_GET_MACRO(Dimension, dimension, UInt);
   AKANTU_GET_MACRO(Name, name, std::string);
   inline UInt getNbNodes() const;
 
   /* ------------------------------------------------------------------------ */
   /* Class Members                                                            */
   /* ------------------------------------------------------------------------ */
 private:
   /// Mesh to which this group belongs
   const Mesh & mesh;
 
   /// name of the group
   std::string name;
 
   /// list of elements composing the group
   ElementList elements;
 
   /// sub list of nodes which are composing the elements
   NodeGroup & node_group;
 
   /// group dimension
   UInt dimension;
 
   /// empty arry for the iterator to work when an element type not present
   Array<UInt> empty_elements;
 };
 
 /// standard output stream operator
 inline std::ostream & operator<<(std::ostream & stream,
                                  const ElementGroup & _this) {
   _this.printself(stream);
   return stream;
 }
 
 } // namespace akantu
 
 #include "element.hh"
 #include "element_group_inline_impl.cc"
 
 #endif /* __AKANTU_ELEMENT_GROUP_HH__ */
diff --git a/src/mesh/element_group_inline_impl.cc b/src/mesh/element_group_inline_impl.cc
index bd084f56c..7ae8b3750 100644
--- a/src/mesh/element_group_inline_impl.cc
+++ b/src/mesh/element_group_inline_impl.cc
@@ -1,146 +1,146 @@
 /**
  * @file   element_group_inline_impl.cc
  *
  * @author Dana Christen <dana.christen@gmail.com>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Wed Nov 13 2013
- * @date last modification: Tue Aug 18 2015
+ * @date last modification: Sun Aug 13 2017
  *
- * @brief Stores information relevent to the notion of domain boundary and
+ * @brief  Stores information relevent to the notion of domain boundary and
  * surfaces.
  *
  * @section LICENSE
  *
- * Copyright  (©)  2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de Lausanne)
+ * 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
+ * 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
+ * A PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 #include "element_group.hh"
 #include "mesh.hh"
 
 /* -------------------------------------------------------------------------- */
 
 #ifndef __AKANTU_ELEMENT_GROUP_INLINE_IMPL_CC__
 #define __AKANTU_ELEMENT_GROUP_INLINE_IMPL_CC__
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 inline void ElementGroup::add(const Element & el, bool add_nodes,
                               bool check_for_duplicate) {
   this->add(el.type, el.element, el.ghost_type, add_nodes, check_for_duplicate);
 }
 
 /* -------------------------------------------------------------------------- */
 
 inline void ElementGroup::add(const ElementType & type, UInt element,
                               const GhostType & ghost_type, bool add_nodes,
                               bool check_for_duplicate) {
 
   addElement(type, element, ghost_type);
 
   if (add_nodes) {
     Array<UInt>::const_vector_iterator it =
         mesh.getConnectivity(type, ghost_type)
             .begin(mesh.getNbNodesPerElement(type)) +
         element;
     const Vector<UInt> & conn = *it;
     for (UInt i = 0; i < conn.size(); ++i)
       addNode(conn[i], check_for_duplicate);
   }
 }
 
 /* -------------------------------------------------------------------------- */
 inline void ElementGroup::addNode(UInt node_id, bool check_for_duplicate) {
   node_group.add(node_id, check_for_duplicate);
 }
 
 /* -------------------------------------------------------------------------- */
 inline void ElementGroup::removeNode(UInt node_id) {
   node_group.remove(node_id);
 }
 
 /* -------------------------------------------------------------------------- */
 inline void ElementGroup::addElement(const ElementType & elem_type,
                                      UInt elem_id,
                                      const GhostType & ghost_type) {
   if (!(elements.exists(elem_type, ghost_type))) {
     elements.alloc(0, 1, elem_type, ghost_type);
   }
 
   elements(elem_type, ghost_type).push_back(elem_id);
   this->dimension = UInt(
       std::max(Int(this->dimension), Int(mesh.getSpatialDimension(elem_type))));
 }
 
 /* -------------------------------------------------------------------------- */
 inline UInt ElementGroup::getNbNodes() const { return node_group.size(); }
 
 /* -------------------------------------------------------------------------- */
 inline ElementGroup::type_iterator
 ElementGroup::firstType(UInt dim, const GhostType & ghost_type,
                         const ElementKind & kind) const {
   return elements.firstType(dim, ghost_type, kind);
 }
 
 /* -------------------------------------------------------------------------- */
 inline ElementGroup::type_iterator
 ElementGroup::lastType(UInt dim, const GhostType & ghost_type,
                        const ElementKind & kind) const {
   return elements.lastType(dim, ghost_type, kind);
 }
 
 /* -------------------------------------------------------------------------- */
 inline ElementGroup::const_element_iterator
 ElementGroup::begin(const ElementType & type,
                     const GhostType & ghost_type) const {
   if (elements.exists(type, ghost_type)) {
     return elements(type, ghost_type).begin();
   } else {
     return empty_elements.begin();
   }
 }
 
 /* -------------------------------------------------------------------------- */
 inline ElementGroup::const_element_iterator
 ElementGroup::end(const ElementType & type,
                   const GhostType & ghost_type) const {
   if (elements.exists(type, ghost_type)) {
     return elements(type, ghost_type).end();
   } else {
     return empty_elements.end();
   }
 }
 
 /* -------------------------------------------------------------------------- */
 inline const Array<UInt> &
 ElementGroup::getElements(const ElementType & type,
                           const GhostType & ghost_type) const {
   if (elements.exists(type, ghost_type)) {
     return elements(type, ghost_type);
   } else {
     return empty_elements;
   }
 }
 
 /* -------------------------------------------------------------------------- */
 
 } // namespace akantu
 
 #endif /* __AKANTU_ELEMENT_GROUP_INLINE_IMPL_CC__ */
diff --git a/src/mesh/element_type_map.cc b/src/mesh/element_type_map.cc
index ee0fc8cca..83fccc3a9 100644
--- a/src/mesh/element_type_map.cc
+++ b/src/mesh/element_type_map.cc
@@ -1,71 +1,73 @@
 /**
  * @file   element_type_map.cc
  *
- * @author Nicolas Richart
+ * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
- * @date creation  Tue Jun 27 2017
+ * @date creation: Fri Jun 18 2010
+ * @date last modification: Tue Feb 20 2018
  *
- * @brief A Documented file.
+ * @brief  A Documented file.
  *
  * @section LICENSE
  *
- * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * 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
+ * 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
+ * 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 "fe_engine.hh"
 #include "mesh.hh"
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 
 FEEngineElementTypeMapArrayInitializer::FEEngineElementTypeMapArrayInitializer(
     const FEEngine & fe_engine, UInt nb_component, UInt spatial_dimension,
     const GhostType & ghost_type, const ElementKind & element_kind)
     : MeshElementTypeMapArrayInitializer(
           fe_engine.getMesh(), nb_component,
           spatial_dimension == UInt(-2)
               ? fe_engine.getMesh().getSpatialDimension()
               : spatial_dimension,
           ghost_type, element_kind, true, false),
       fe_engine(fe_engine) {}
 
 FEEngineElementTypeMapArrayInitializer::FEEngineElementTypeMapArrayInitializer(
     const FEEngine & fe_engine,
     const ElementTypeMapArrayInitializer::CompFunc & nb_component,
     UInt spatial_dimension, const GhostType & ghost_type,
     const ElementKind & element_kind)
     : MeshElementTypeMapArrayInitializer(
           fe_engine.getMesh(), nb_component,
           spatial_dimension == UInt(-2)
               ? fe_engine.getMesh().getSpatialDimension()
               : spatial_dimension,
           ghost_type, element_kind, true, false),
       fe_engine(fe_engine) {}
 
 UInt FEEngineElementTypeMapArrayInitializer::size(
     const ElementType & type) const {
   return MeshElementTypeMapArrayInitializer::size(type) *
          fe_engine.getNbIntegrationPoints(type, this->ghost_type);
 }
 
 FEEngineElementTypeMapArrayInitializer::ElementTypesIteratorHelper
 FEEngineElementTypeMapArrayInitializer::elementTypes() const {
   return this->fe_engine.elementTypes(spatial_dimension, ghost_type,
                                       element_kind);
 }
 } // namespace akantu
diff --git a/src/mesh/element_type_map.hh b/src/mesh/element_type_map.hh
index f3aefd368..4853569a7 100644
--- a/src/mesh/element_type_map.hh
+++ b/src/mesh/element_type_map.hh
@@ -1,449 +1,449 @@
 /**
  * @file   element_type_map.hh
  *
+ * @author Lucas Frerot <lucas.frerot@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Wed Aug 31 2011
- * @date last modification: Fri Oct 02 2015
+ * @date last modification: Tue Feb 20 2018
  *
  * @brief  storage class by element type
  *
  * @section LICENSE
  *
- * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
- * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
- * Solides)
+ * 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
+ * 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
+ * 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_array.hh"
 #include "aka_memory.hh"
 #include "aka_named_argument.hh"
 #include "element.hh"
 /* -------------------------------------------------------------------------- */
 
 #ifndef __AKANTU_ELEMENT_TYPE_MAP_HH__
 #define __AKANTU_ELEMENT_TYPE_MAP_HH__
 
 namespace akantu {
 class FEEngine;
 } // namespace akantu
 
 namespace akantu {
 
 namespace {
   DECLARE_NAMED_ARGUMENT(all_ghost_types);
   DECLARE_NAMED_ARGUMENT(default_value);
   DECLARE_NAMED_ARGUMENT(element_kind);
   DECLARE_NAMED_ARGUMENT(ghost_type);
   DECLARE_NAMED_ARGUMENT(nb_component);
   DECLARE_NAMED_ARGUMENT(nb_component_functor);
   DECLARE_NAMED_ARGUMENT(with_nb_element);
   DECLARE_NAMED_ARGUMENT(with_nb_nodes_per_element);
   DECLARE_NAMED_ARGUMENT(spatial_dimension);
   DECLARE_NAMED_ARGUMENT(do_not_default);
 } // namespace
 
 template <class Stored, typename SupportType = ElementType>
 class ElementTypeMap;
 
 /* -------------------------------------------------------------------------- */
 /* ElementTypeMapBase */
 /* -------------------------------------------------------------------------- */
 /// Common non templated base class for the ElementTypeMap class
 class ElementTypeMapBase {
 public:
   virtual ~ElementTypeMapBase() = default;
 };
 
 /* -------------------------------------------------------------------------- */
 /* ElementTypeMap */
 /* -------------------------------------------------------------------------- */
 
 template <class Stored, typename SupportType>
 class ElementTypeMap : public ElementTypeMapBase {
 
 public:
   ElementTypeMap();
   ~ElementTypeMap() override;
 
   inline static std::string printType(const SupportType & type,
                                       const GhostType & ghost_type);
 
   /*! Tests whether a type is present in the object
    *  @param type the type to check for
    *  @param ghost_type optional: by default, the data map for non-ghost
    *         elements is searched
    *  @return true if the type is present. */
   inline bool exists(const SupportType & type,
                      const GhostType & ghost_type = _not_ghost) const;
 
   /*! get the stored data corresponding to a type
    *  @param type the type to check for
    *  @param ghost_type optional: by default, the data map for non-ghost
    *         elements is searched
    *  @return stored data corresponding to type. */
   inline const Stored &
   operator()(const SupportType & type,
              const GhostType & ghost_type = _not_ghost) const;
 
   /*! get the stored data corresponding to a type
    *  @param type the type to check for
    *  @param ghost_type optional: by default, the data map for non-ghost
    *         elements is searched
    *  @return stored data corresponding to type. */
   inline Stored & operator()(const SupportType & type,
                              const GhostType & ghost_type = _not_ghost);
 
   /*! insert data of a new type (not yet present) into the map. THIS METHOD IS
    *  NOT ARRAY SAFE, when using ElementTypeMapArray, use setArray instead
    *  @param data to insert
    *  @param type type of data (if this type is already present in the map,
    *         an exception is thrown).
    *  @param ghost_type optional: by default, the data map for non-ghost
    *         elements is searched
    *  @return stored data corresponding to type. */
   template <typename U>
   inline Stored & operator()(U && insertee, const SupportType & type,
                              const GhostType & ghost_type = _not_ghost);
 
 public:
   /// print helper
   virtual void printself(std::ostream & stream, int indent = 0) const;
 
   /* ------------------------------------------------------------------------ */
   /* Element type Iterator                                                    */
   /* ------------------------------------------------------------------------ */
   /*! iterator allows to iterate over type-data pairs of the map. The interface
    *  expects the SupportType to be ElementType. */
   using DataMap = std::map<SupportType, Stored>;
   class type_iterator
       : private std::iterator<std::forward_iterator_tag, const SupportType> {
   public:
     using value_type = const SupportType;
     using pointer = const SupportType *;
     using reference = const SupportType &;
 
   protected:
     using DataMapIterator =
         typename ElementTypeMap<Stored>::DataMap::const_iterator;
 
   public:
     type_iterator(DataMapIterator & list_begin, DataMapIterator & list_end,
                   UInt dim, ElementKind ek);
 
     type_iterator(const type_iterator & it);
     type_iterator() = default;
 
     inline reference operator*();
     inline reference operator*() const;
     inline type_iterator & operator++();
     type_iterator operator++(int);
     inline bool operator==(const type_iterator & other) const;
     inline bool operator!=(const type_iterator & other) const;
     type_iterator & operator=(const type_iterator & other);
 
   private:
     DataMapIterator list_begin;
     DataMapIterator list_end;
     UInt dim;
     ElementKind kind;
   };
 
   /// helper class to use in range for constructions
   class ElementTypesIteratorHelper {
   public:
     using Container = ElementTypeMap<Stored, SupportType>;
     using iterator = typename Container::type_iterator;
 
     ElementTypesIteratorHelper(const Container & container, UInt dim,
                                GhostType ghost_type, ElementKind kind)
         : container(std::cref(container)), dim(dim), ghost_type(ghost_type),
           kind(kind) {}
 
     template <typename... pack>
     ElementTypesIteratorHelper(const Container & container, use_named_args_t,
                                pack &&... _pack)
         : ElementTypesIteratorHelper(
               container, OPTIONAL_NAMED_ARG(spatial_dimension, _all_dimensions),
               OPTIONAL_NAMED_ARG(ghost_type, _not_ghost),
               OPTIONAL_NAMED_ARG(element_kind, _ek_regular)) {}
 
     ElementTypesIteratorHelper(const ElementTypesIteratorHelper &) = default;
     ElementTypesIteratorHelper &
     operator=(const ElementTypesIteratorHelper &) = default;
     ElementTypesIteratorHelper &
     operator=(ElementTypesIteratorHelper &&) = default;
 
     iterator begin() {
       return container.get().firstType(dim, ghost_type, kind);
     }
     iterator end() { return container.get().lastType(dim, ghost_type, kind); }
 
   private:
     std::reference_wrapper<const Container> container;
     UInt dim;
     GhostType ghost_type;
     ElementKind kind;
   };
 
 private:
   ElementTypesIteratorHelper
   elementTypesImpl(UInt dim = _all_dimensions,
                    GhostType ghost_type = _not_ghost,
                    ElementKind kind = _ek_regular) const;
 
   template <typename... pack>
   ElementTypesIteratorHelper
   elementTypesImpl(const use_named_args_t & /*unused*/, pack &&... _pack) const;
 
 public:
   /*!
    * \param _spatial_dimension optional: filter for elements of given spatial
    * dimension
    * \param _ghost_type optional: filter for a certain ghost_type
    * \param _element_kind optional: filter for elements of given kind
    */
   template <typename... pack>
   std::enable_if_t<are_named_argument<pack...>::value,
                    ElementTypesIteratorHelper>
   elementTypes(pack &&... _pack) const {
     return elementTypesImpl(use_named_args,
                             std::forward<decltype(_pack)>(_pack)...);
   }
 
   template <typename... pack>
   std::enable_if_t<not are_named_argument<pack...>::value,
                    ElementTypesIteratorHelper>
   elementTypes(pack &&... _pack) const {
     return elementTypesImpl(std::forward<decltype(_pack)>(_pack)...);
   }
 
 public:
   /*! Get an iterator to the beginning of a subset datamap. This method expects
    *  the SupportType to be ElementType.
    *  @param dim optional: iterate over data of dimension dim (e.g. when
    *         iterating over (surface) facets of a 3D mesh, dim would be 2).
    *         by default, all dimensions are considered.
    *  @param ghost_type optional: by default, the data map for non-ghost
    *         elements is iterated over.
    *  @param kind optional: the kind of element to search for (see
    *         aka_common.hh), by default all kinds are considered
    *  @return an iterator to the first stored data matching the filters
    *          or an iterator to the end of the map if none match*/
   inline type_iterator firstType(UInt dim = _all_dimensions,
                                  GhostType ghost_type = _not_ghost,
                                  ElementKind kind = _ek_not_defined) const;
   /*! Get an iterator to the end of a subset datamap. This method expects
    *  the SupportType to be ElementType.
    *  @param dim optional: iterate over data of dimension dim (e.g. when
    *         iterating over (surface) facets of a 3D mesh, dim would be 2).
    *         by default, all dimensions are considered.
    *  @param ghost_type optional: by default, the data map for non-ghost
    *         elements is iterated over.
    *  @param kind optional: the kind of element to search for (see
    *         aka_common.hh), by default all kinds are considered
    *  @return an iterator to the last stored data matching the filters
    *          or an iterator to the end of the map if none match */
   inline type_iterator lastType(UInt dim = _all_dimensions,
                                 GhostType ghost_type = _not_ghost,
                                 ElementKind kind = _ek_not_defined) const;
 
 protected:
   /*! Direct access to the underlying data map. for internal use by daughter
    *  classes only
    *  @param ghost_type whether to return the data map or the ghost_data map
    *  @return the raw map */
   inline DataMap & getData(GhostType ghost_type);
   /*! Direct access to the underlying data map. for internal use by daughter
    *  classes only
    *  @param ghost_type whether to return the data map or the ghost_data map
    *  @return the raw map */
   inline const DataMap & getData(GhostType ghost_type) const;
 
   /* ------------------------------------------------------------------------ */
 protected:
   DataMap data;
   DataMap ghost_data;
 };
 
 /* -------------------------------------------------------------------------- */
 /* Some typedefs                                                              */
 /* -------------------------------------------------------------------------- */
 template <typename T, typename SupportType>
 class ElementTypeMapArray : public ElementTypeMap<Array<T> *, SupportType>,
                             public Memory {
 public:
   using type = T;
   using array_type = Array<T>;
 
 protected:
   using parent = ElementTypeMap<Array<T> *, SupportType>;
   using DataMap = typename parent::DataMap;
 
 public:
   using type_iterator = typename parent::type_iterator;
 
   /// standard assigment (copy) operator
   void operator=(const ElementTypeMapArray &) = delete;
   ElementTypeMapArray(const ElementTypeMapArray &) = delete;
 
   /// explicit copy
   void copy(const ElementTypeMapArray & other);
 
   /*! Constructor
    *  @param id optional: identifier (string)
    *  @param parent_id optional: parent identifier. for organizational purposes
    *         only
    *  @param memory_id optional: choose a specific memory, defaults to memory 0
    */
   ElementTypeMapArray(const ID & id = "by_element_type_array",
                       const ID & parent_id = "no_parent",
                       const MemoryID & memory_id = 0)
       : parent(), Memory(parent_id + ":" + id, memory_id), name(id){};
 
   /*! allocate memory for a new array
    *  @param size number of tuples of the new array
    *  @param nb_component tuple size
    *  @param type the type under which the array is indexed in the map
    *  @param ghost_type whether to add the field to the data map or the
    *         ghost_data map
    *  @return a reference to the allocated array */
   inline Array<T> & alloc(UInt size, UInt nb_component,
                           const SupportType & type,
                           const GhostType & ghost_type,
                           const T & default_value = T());
 
   /*! allocate memory for a new array in both the data and the ghost_data map
    *  @param size number of tuples of the new array
    *  @param nb_component tuple size
    *  @param type the type under which the array is indexed in the map*/
   inline void alloc(UInt size, UInt nb_component, const SupportType & type,
                     const T & default_value = T());
 
   /* get a reference to the array of certain type
    * @param type data filed under type is returned
    * @param ghost_type optional: by default the non-ghost map is searched
    * @return a reference to the array */
   inline const Array<T> &
   operator()(const SupportType & type,
              const GhostType & ghost_type = _not_ghost) const;
 
   /// access the data of an element, this combine the map and array accessor
   inline const T & operator()(const Element & element,
                               UInt component = 0) const;
 
   /// access the data of an element, this combine the map and array accessor
   inline T & operator()(const Element & element, UInt component = 0);
 
   /* get a reference to the array of certain type
    * @param type data filed under type is returned
    * @param ghost_type optional: by default the non-ghost map is searched
    * @return a const reference to the array */
   inline Array<T> & operator()(const SupportType & type,
                                const GhostType & ghost_type = _not_ghost);
 
   /*! insert data of a new type (not yet present) into the map.
    *  @param type type of data (if this type is already present in the map,
    *         an exception is thrown).
    *  @param ghost_type optional: by default, the data map for non-ghost
    *         elements is searched
    *  @param vect the vector to include into the map
    *  @return stored data corresponding to type. */
   inline void setArray(const SupportType & type, const GhostType & ghost_type,
                        const Array<T> & vect);
   /*! frees all memory related to the data*/
   inline void free();
 
   /*! set all values in the ElementTypeMap to zero*/
   inline void clear();
 
   /*! set all values in the ElementTypeMap to value */
   template <typename ST> inline void set(const ST & value);
 
   /*! deletes and reorders entries in the stored arrays
    *  @param new_numbering a ElementTypeMapArray of new indices. UInt(-1)
    * indicates
    *         deleted entries. */
   inline void
   onElementsRemoved(const ElementTypeMapArray<UInt> & new_numbering);
 
   /// text output helper
   void printself(std::ostream & stream, int indent = 0) const override;
 
   /*! set the id
    *  @param id the new name
    */
   inline void setID(const ID & id) { this->id = id; }
 
   ElementTypeMap<UInt>
   getNbComponents(UInt dim = _all_dimensions, GhostType ghost_type = _not_ghost,
                   ElementKind kind = _ek_not_defined) const {
 
     ElementTypeMap<UInt> nb_components;
 
     for (auto & type : this->elementTypes(dim, ghost_type, kind)) {
       UInt nb_comp = (*this)(type, ghost_type).getNbComponent();
       nb_components(type, ghost_type) = nb_comp;
     }
 
     return nb_components;
   }
 
   /* ------------------------------------------------------------------------ */
   /* more evolved allocators                                                  */
   /* ------------------------------------------------------------------------ */
 public:
   /// initialize the arrays in accordance to a functor
   template <class Func>
   void initialize(const Func & f, const T & default_value, bool do_not_default);
 
   /// initialize with sizes and number of components in accordance of a mesh
   /// content
   template <typename... pack>
   void initialize(const Mesh & mesh, pack &&... _pack);
 
   /// initialize with sizes and number of components in accordance of a fe
   /// engine content (aka integration points)
   template <typename... pack>
   void initialize(const FEEngine & fe_engine, pack &&... _pack);
 
   /* ------------------------------------------------------------------------ */
   /* Accesssors                                                               */
   /* ------------------------------------------------------------------------ */
 public:
   /// get the name of the internal field
   AKANTU_GET_MACRO(Name, name, ID);
 
   /// name of the elment type map: e.g. connectivity, grad_u
   ID name;
 };
 
 /// to store data Array<Real> by element type
 using ElementTypeMapReal = ElementTypeMapArray<Real>;
 /// to store data Array<Int> by element type
 using ElementTypeMapInt = ElementTypeMapArray<Int>;
 /// to store data Array<UInt> by element type
 using ElementTypeMapUInt = ElementTypeMapArray<UInt, ElementType>;
 
 /// Map of data of type UInt stored in a mesh
 using UIntDataMap = std::map<std::string, Array<UInt> *>;
 using ElementTypeMapUIntDataMap = ElementTypeMap<UIntDataMap, ElementType>;
 
 } // namespace akantu
 
 #endif /* __AKANTU_ELEMENT_TYPE_MAP_HH__ */
diff --git a/src/mesh/element_type_map_filter.hh b/src/mesh/element_type_map_filter.hh
index 81c6ab58b..834469672 100644
--- a/src/mesh/element_type_map_filter.hh
+++ b/src/mesh/element_type_map_filter.hh
@@ -1,307 +1,307 @@
 /**
  * @file   element_type_map_filter.hh
  *
  * @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Tue Sep 02 2014
- * @date last modification: Fri Dec 18 2015
+ * @date last modification: Sun Dec 03 2017
  *
  * @brief  Filtered version based on a an akantu::ElementGroup of a
  * akantu::ElementTypeMap
  *
  * @section LICENSE
  *
- * Copyright  (©)  2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de Lausanne)
+ * 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
+ * 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
+ * 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_BY_ELEMENT_TYPE_FILTER_HH__
 #define __AKANTU_BY_ELEMENT_TYPE_FILTER_HH__
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 /* ArrayFilter                                                                */
 /* -------------------------------------------------------------------------- */
 
 template <typename T> class ArrayFilter {
 
   /* ------------------------------------------------------------------------ */
   /* Typedefs                                                                 */
   /* ------------------------------------------------------------------------ */
 
 public:
   /// standard iterator
   template <typename R = T> class iterator {
     inline bool operator!=(__attribute__((unused)) iterator<R> & other) {
       throw;
     };
     inline bool operator==(__attribute__((unused)) iterator<R> & other) {
       throw;
     };
 
     inline iterator<R> & operator++() { throw; };
     inline T operator*() {
       throw;
       return T();
     };
   };
 
   /// const iterator
   template <template <class S> class original_iterator, typename Shape,
             typename filter_iterator>
   class const_iterator {
 
   public:
     UInt getCurrentIndex() {
       return (*this->filter_it * this->nb_item_per_elem +
               this->sub_element_counter);
     }
 
     inline const_iterator() = default;
     inline const_iterator(const original_iterator<Shape> & origin_it,
                           const filter_iterator & filter_it,
                           UInt nb_item_per_elem)
         : origin_it(origin_it), filter_it(filter_it),
           nb_item_per_elem(nb_item_per_elem), sub_element_counter(0){};
 
     inline bool operator!=(const_iterator & other) const {
       return !((*this) == other);
     }
     inline bool operator==(const_iterator & other) const {
       return (this->origin_it == other.origin_it &&
               this->filter_it == other.filter_it &&
               this->sub_element_counter == other.sub_element_counter);
     }
 
     inline bool operator!=(const const_iterator & other) const {
       return !((*this) == other);
     }
     inline bool operator==(const const_iterator & other) const {
       return (this->origin_it == other.origin_it &&
               this->filter_it == other.filter_it &&
               this->sub_element_counter == other.sub_element_counter);
     }
 
     inline const_iterator & operator++() {
 
       ++sub_element_counter;
       if (sub_element_counter == nb_item_per_elem) {
         sub_element_counter = 0;
         ++filter_it;
       }
       return *this;
     };
 
     inline Shape operator*() {
       return origin_it[nb_item_per_elem * (*filter_it) + sub_element_counter];
     };
 
   private:
     original_iterator<Shape> origin_it;
     filter_iterator filter_it;
 
     /// the number of item per element
     UInt nb_item_per_elem;
     /// counter for every sub element group
     UInt sub_element_counter;
   };
 
   using vector_iterator = iterator<Vector<T>>;
 
   using array_type = Array<T>;
 
   using const_vector_iterator =
       const_iterator<array_type::template const_iterator, Vector<T>,
                      Array<UInt>::const_iterator<UInt>>;
 
   using value_type = typename array_type::value_type;
 
   /* ------------------------------------------------------------------------ */
   /* Constructors/Destructors                                                 */
   /* ------------------------------------------------------------------------ */
 
 public:
   ArrayFilter(const Array<T> & array, const Array<UInt> & filter,
               UInt nb_item_per_elem)
       : array(array), filter(filter), nb_item_per_elem(nb_item_per_elem){};
 
   /* ------------------------------------------------------------------------ */
   /* Methods                                                                  */
   /* ------------------------------------------------------------------------ */
   const_vector_iterator begin_reinterpret(UInt n, UInt new_size) const {
     AKANTU_DEBUG_ASSERT(
         n * new_size == this->getNbComponent() * this->size(),
         "The new values for size ("
             << new_size << ") and nb_component (" << n
             << ") are not compatible with the one of this array("
             << this->size() << "," << this->getNbComponent() << ")");
     UInt new_full_array_size = this->array.size() * array.getNbComponent() / n;
     UInt new_nb_item_per_elem = this->nb_item_per_elem;
     if (new_size != 0 && n != 0)
       new_nb_item_per_elem = this->array.getNbComponent() *
                              this->filter.size() * this->nb_item_per_elem /
                              (n * new_size);
 
     return const_vector_iterator(
         this->array.begin_reinterpret(n, new_full_array_size),
         this->filter.begin(), new_nb_item_per_elem);
   };
 
   const_vector_iterator end_reinterpret(UInt n, UInt new_size) const {
     AKANTU_DEBUG_ASSERT(
         n * new_size == this->getNbComponent() * this->size(),
         "The new values for size ("
             << new_size << ") and nb_component (" << n
             << ") are not compatible with the one of this array("
             << this->size() << "," << this->getNbComponent() << ")");
     UInt new_full_array_size =
         this->array.size() * this->array.getNbComponent() / n;
     UInt new_nb_item_per_elem = this->nb_item_per_elem;
     if (new_size != 0 && n != 0)
       new_nb_item_per_elem = this->array.getNbComponent() *
                              this->filter.size() * this->nb_item_per_elem /
                              (n * new_size);
 
     return const_vector_iterator(
         this->array.begin_reinterpret(n, new_full_array_size),
         this->filter.end(), new_nb_item_per_elem);
   };
 
   vector_iterator begin_reinterpret(UInt, UInt) { throw; };
 
   vector_iterator end_reinterpret(UInt, UInt) { throw; };
 
   /// return the size of the filtered array which is the filter size
   UInt size() const { return this->filter.size() * this->nb_item_per_elem; };
   /// the number of components of the filtered array
   UInt getNbComponent() const { return this->array.getNbComponent(); };
 
   /* ------------------------------------------------------------------------ */
   /* Class Members                                                            */
   /* ------------------------------------------------------------------------ */
 
 private:
   /// reference to array of data
   const Array<T> & array;
   /// reference to the filter used to select elements
   const Array<UInt> & filter;
   /// the number of item per element
   UInt nb_item_per_elem;
 };
 
 /* -------------------------------------------------------------------------- */
 /* ElementTypeMapFilter */
 /* -------------------------------------------------------------------------- */
 
 template <class T, typename SupportType = ElementType>
 class ElementTypeMapArrayFilter {
 
   /* ------------------------------------------------------------------------ */
   /* Typedefs                                                                 */
   /* ------------------------------------------------------------------------ */
 
 public:
   using type = T;
   using array_type = ArrayFilter<T>;
   using value_type = typename array_type::value_type;
 
   using type_iterator =
       typename ElementTypeMapArray<UInt, SupportType>::type_iterator;
 
   /* ------------------------------------------------------------------------ */
   /* Constructors/Destructors                                                 */
   /* ------------------------------------------------------------------------ */
 public:
   ElementTypeMapArrayFilter(
       const ElementTypeMapArray<T, SupportType> & array,
       const ElementTypeMapArray<UInt, SupportType> & filter,
       const ElementTypeMap<UInt, SupportType> & nb_data_per_elem)
       : array(array), filter(filter), nb_data_per_elem(nb_data_per_elem) {}
 
   ElementTypeMapArrayFilter(
       const ElementTypeMapArray<T, SupportType> & array,
       const ElementTypeMapArray<UInt, SupportType> & filter)
       : array(array), filter(filter) {}
 
   ~ElementTypeMapArrayFilter() = default;
 
   /* ------------------------------------------------------------------------ */
   /* Methods                                                                  */
   /* ------------------------------------------------------------------------ */
 
   inline const ArrayFilter<T>
   operator()(const SupportType & type,
              const GhostType & ghost_type = _not_ghost) const {
     if (filter.exists(type, ghost_type)) {
       if (nb_data_per_elem.exists(type, ghost_type))
         return ArrayFilter<T>(array(type, ghost_type), filter(type, ghost_type),
                               nb_data_per_elem(type, ghost_type) /
                                   array(type, ghost_type).getNbComponent());
       else
         return ArrayFilter<T>(array(type, ghost_type), filter(type, ghost_type),
                               1);
     } else {
       return ArrayFilter<T>(empty_array, empty_filter, 1);
     }
   };
 
   inline type_iterator firstType(UInt dim = _all_dimensions,
                                  GhostType ghost_type = _not_ghost,
                                  ElementKind kind = _ek_not_defined) const {
     return filter.firstType(dim, ghost_type, kind);
   };
 
   inline type_iterator lastType(UInt dim = _all_dimensions,
                                 GhostType ghost_type = _not_ghost,
                                 ElementKind kind = _ek_not_defined) const {
     return filter.lastType(dim, ghost_type, kind);
   };
 
   ElementTypeMap<UInt>
   getNbComponents(UInt dim = _all_dimensions, GhostType ghost_type = _not_ghost,
                   ElementKind kind = _ek_not_defined) const {
     return this->array.getNbComponents(dim, ghost_type, kind);
   };
 
   /* ------------------------------------------------------------------------ */
   /* Accessors                                                                */
   /* ------------------------------------------------------------------------ */
 
   std::string getID() {
     return std::string("filtered:" + this->array().getID());
   }
 
   /* ------------------------------------------------------------------------ */
   /* Class Members                                                            */
   /* ------------------------------------------------------------------------ */
 
 protected:
   const ElementTypeMapArray<T, SupportType> & array;
   const ElementTypeMapArray<UInt, SupportType> & filter;
   ElementTypeMap<UInt> nb_data_per_elem;
 
   /// Empty array to be able to return consistent filtered arrays
   Array<T> empty_array;
   Array<UInt> empty_filter;
 };
 
 } // namespace akantu
 
 #endif /* __AKANTU_BY_ELEMENT_TYPE_FILTER_HH__ */
diff --git a/src/mesh/element_type_map_tmpl.hh b/src/mesh/element_type_map_tmpl.hh
index 6793158a1..2afd4aa37 100644
--- a/src/mesh/element_type_map_tmpl.hh
+++ b/src/mesh/element_type_map_tmpl.hh
@@ -1,747 +1,747 @@
 /**
  * @file   element_type_map_tmpl.hh
  *
+ * @author Lucas Frerot <lucas.frerot@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Wed Aug 31 2011
- * @date last modification: Fri Oct 02 2015
+ * @date last modification: Tue Feb 20 2018
  *
  * @brief  implementation of template functions of the ElementTypeMap and
  * ElementTypeMapArray classes
  *
  * @section LICENSE
  *
- * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
- * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
- * Solides)
+ * 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
+ * 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
+ * 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_static_if.hh"
 #include "element_type_map.hh"
 #include "mesh.hh"
 /* -------------------------------------------------------------------------- */
 #include "element_type_conversion.hh"
 /* -------------------------------------------------------------------------- */
 #include <functional>
 /* -------------------------------------------------------------------------- */
 
 #ifndef __AKANTU_ELEMENT_TYPE_MAP_TMPL_HH__
 #define __AKANTU_ELEMENT_TYPE_MAP_TMPL_HH__
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 /* ElementTypeMap                                                             */
 /* -------------------------------------------------------------------------- */
 template <class Stored, typename SupportType>
 inline std::string
 ElementTypeMap<Stored, SupportType>::printType(const SupportType & type,
                                                const GhostType & ghost_type) {
   std::stringstream sstr;
   sstr << "(" << ghost_type << ":" << type << ")";
   return sstr.str();
 }
 
 /* -------------------------------------------------------------------------- */
 template <class Stored, typename SupportType>
 inline bool ElementTypeMap<Stored, SupportType>::exists(
     const SupportType & type, const GhostType & ghost_type) const {
   return this->getData(ghost_type).find(type) !=
          this->getData(ghost_type).end();
 }
 
 /* -------------------------------------------------------------------------- */
 template <class Stored, typename SupportType>
 inline const Stored & ElementTypeMap<Stored, SupportType>::
 operator()(const SupportType & type, const GhostType & ghost_type) const {
   auto it = this->getData(ghost_type).find(type);
 
   if (it == this->getData(ghost_type).end())
     AKANTU_SILENT_EXCEPTION("No element of type "
                             << ElementTypeMap::printType(type, ghost_type)
                             << " in this ElementTypeMap<"
                             << debug::demangle(typeid(Stored).name())
                             << "> class");
   return it->second;
 }
 
 /* -------------------------------------------------------------------------- */
 template <class Stored, typename SupportType>
 inline Stored & ElementTypeMap<Stored, SupportType>::
 operator()(const SupportType & type, const GhostType & ghost_type) {
   return this->getData(ghost_type)[type];
 }
 
 /* -------------------------------------------------------------------------- */
 template <class Stored, typename SupportType>
 template <typename U>
 inline Stored & ElementTypeMap<Stored, SupportType>::
 operator()(U && insertee, const SupportType & type,
            const GhostType & ghost_type) {
   auto it = this->getData(ghost_type).find(type);
 
   if (it != this->getData(ghost_type).end()) {
     AKANTU_SILENT_EXCEPTION("Element of type "
                             << ElementTypeMap::printType(type, ghost_type)
                             << " already in this ElementTypeMap<"
                             << debug::demangle(typeid(Stored).name())
                             << "> class");
   } else {
     auto & data = this->getData(ghost_type);
     const auto & res =
         data.insert(std::make_pair(type, std::forward<U>(insertee)));
     it = res.first;
   }
 
   return it->second;
 }
 
 /* -------------------------------------------------------------------------- */
 template <class Stored, typename SupportType>
 inline typename ElementTypeMap<Stored, SupportType>::DataMap &
 ElementTypeMap<Stored, SupportType>::getData(GhostType ghost_type) {
   if (ghost_type == _not_ghost)
     return data;
 
   return ghost_data;
 }
 
 /* -------------------------------------------------------------------------- */
 template <class Stored, typename SupportType>
 inline const typename ElementTypeMap<Stored, SupportType>::DataMap &
 ElementTypeMap<Stored, SupportType>::getData(GhostType ghost_type) const {
   if (ghost_type == _not_ghost)
     return data;
 
   return ghost_data;
 }
 
 /* -------------------------------------------------------------------------- */
 /// Works only if stored is a pointer to a class with a printself method
 template <class Stored, typename SupportType>
 void ElementTypeMap<Stored, SupportType>::printself(std::ostream & stream,
                                                     int indent) const {
   std::string space;
   for (Int i = 0; i < indent; i++, space += AKANTU_INDENT)
     ;
 
   stream << space << "ElementTypeMap<" << debug::demangle(typeid(Stored).name())
          << "> [" << std::endl;
   for (auto gt : ghost_types) {
     const DataMap & data = getData(gt);
     for (auto & pair : data) {
       stream << space << space << ElementTypeMap::printType(pair.first, gt)
              << std::endl;
     }
   }
 
   stream << space << "]" << std::endl;
 }
 
 /* -------------------------------------------------------------------------- */
 template <class Stored, typename SupportType>
 ElementTypeMap<Stored, SupportType>::ElementTypeMap() = default;
 
 /* -------------------------------------------------------------------------- */
 template <class Stored, typename SupportType>
 ElementTypeMap<Stored, SupportType>::~ElementTypeMap() = default;
 
 /* -------------------------------------------------------------------------- */
 /* ElementTypeMapArray                                                        */
 /* -------------------------------------------------------------------------- */
 template <typename T, typename SupportType>
 void ElementTypeMapArray<T, SupportType>::copy(
     const ElementTypeMapArray & other) {
   for (auto ghost_type : ghost_types) {
     for (auto type :
          this->elementTypes(_all_dimensions, ghost_types, _ek_not_defined)) {
       const auto & array_to_copy = other(type, ghost_type);
       auto & array =
           this->alloc(0, array_to_copy.getNbComponent(), type, ghost_type);
       array.copy(array_to_copy);
     }
   }
 }
 
 /* -------------------------------------------------------------------------- */
 template <typename T, typename SupportType>
 inline Array<T> & ElementTypeMapArray<T, SupportType>::alloc(
     UInt size, UInt nb_component, const SupportType & type,
     const GhostType & ghost_type, const T & default_value) {
   std::string ghost_id = "";
   if (ghost_type == _ghost)
     ghost_id = ":ghost";
 
   Array<T> * tmp;
 
   auto it = this->getData(ghost_type).find(type);
 
   if (it == this->getData(ghost_type).end()) {
     std::stringstream sstr;
     sstr << this->id << ":" << type << ghost_id;
     tmp = &(Memory::alloc<T>(sstr.str(), size, nb_component, default_value));
     std::stringstream sstrg;
     sstrg << ghost_type;
     // tmp->setTag(sstrg.str());
     this->getData(ghost_type)[type] = tmp;
   } else {
     AKANTU_DEBUG_INFO(
         "The vector "
         << this->id << this->printType(type, ghost_type)
         << " already exists, it is resized instead of allocated.");
     tmp = it->second;
     it->second->resize(size);
   }
 
   return *tmp;
 }
 
 /* -------------------------------------------------------------------------- */
 template <typename T, typename SupportType>
 inline void
 ElementTypeMapArray<T, SupportType>::alloc(UInt size, UInt nb_component,
                                            const SupportType & type,
                                            const T & default_value) {
   this->alloc(size, nb_component, type, _not_ghost, default_value);
   this->alloc(size, nb_component, type, _ghost, default_value);
 }
 
 /* -------------------------------------------------------------------------- */
 template <typename T, typename SupportType>
 inline void ElementTypeMapArray<T, SupportType>::free() {
   AKANTU_DEBUG_IN();
 
   for (auto gt : ghost_types) {
     auto & data = this->getData(gt);
     for (auto & pair : data) {
       dealloc(pair.second->getID());
     }
     data.clear();
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <typename T, typename SupportType>
 inline void ElementTypeMapArray<T, SupportType>::clear() {
   for (auto gt : ghost_types) {
     auto & data = this->getData(gt);
     for (auto & vect : data) {
       vect.second->clear();
     }
   }
 }
 
 /* -------------------------------------------------------------------------- */
 template <typename T, typename SupportType>
 template <typename ST>
 inline void ElementTypeMapArray<T, SupportType>::set(const ST & value) {
   for (auto gt : ghost_types) {
     auto & data = this->getData(gt);
     for (auto & vect : data) {
       vect.second->set(value);
     }
   }
 }
 
 /* -------------------------------------------------------------------------- */
 template <typename T, typename SupportType>
 inline const Array<T> & ElementTypeMapArray<T, SupportType>::
 operator()(const SupportType & type, const GhostType & ghost_type) const {
   auto it = this->getData(ghost_type).find(type);
 
   if (it == this->getData(ghost_type).end())
     AKANTU_SILENT_EXCEPTION("No element of type "
                             << ElementTypeMapArray::printType(type, ghost_type)
                             << " in this const ElementTypeMapArray<"
                             << debug::demangle(typeid(T).name()) << "> class(\""
                             << this->id << "\")");
   return *(it->second);
 }
 
 /* -------------------------------------------------------------------------- */
 template <typename T, typename SupportType>
 inline Array<T> & ElementTypeMapArray<T, SupportType>::
 operator()(const SupportType & type, const GhostType & ghost_type) {
   auto it = this->getData(ghost_type).find(type);
 
   if (it == this->getData(ghost_type).end())
     AKANTU_SILENT_EXCEPTION("No element of type "
                             << ElementTypeMapArray::printType(type, ghost_type)
                             << " in this ElementTypeMapArray<"
                             << debug::demangle(typeid(T).name())
                             << "> class (\"" << this->id << "\")");
 
   return *(it->second);
 }
 
 /* -------------------------------------------------------------------------- */
 template <typename T, typename SupportType>
 inline void
 ElementTypeMapArray<T, SupportType>::setArray(const SupportType & type,
                                               const GhostType & ghost_type,
                                               const Array<T> & vect) {
   auto it = this->getData(ghost_type).find(type);
 
   if (AKANTU_DEBUG_TEST(dblWarning) && it != this->getData(ghost_type).end() &&
       it->second != &vect) {
     AKANTU_DEBUG_WARNING(
         "The Array "
         << this->printType(type, ghost_type)
         << " is already registred, this call can lead to a memory leak.");
   }
 
   this->getData(ghost_type)[type] = &(const_cast<Array<T> &>(vect));
 }
 
 /* -------------------------------------------------------------------------- */
 template <typename T, typename SupportType>
 inline void ElementTypeMapArray<T, SupportType>::onElementsRemoved(
     const ElementTypeMapArray<UInt> & new_numbering) {
   for (auto gt : ghost_types) {
     for (auto & type :
          new_numbering.elementTypes(_all_dimensions, gt, _ek_not_defined)) {
       auto support_type = convertType<ElementType, SupportType>(type);
       if (this->exists(support_type, gt)) {
         const auto & renumbering = new_numbering(type, gt);
         if (renumbering.size() == 0)
           continue;
 
         auto & vect = this->operator()(support_type, gt);
         auto nb_component = vect.getNbComponent();
         Array<T> tmp(renumbering.size(), nb_component);
         UInt new_size = 0;
 
         for (UInt i = 0; i < vect.size(); ++i) {
           UInt new_i = renumbering(i);
           if (new_i != UInt(-1)) {
             memcpy(tmp.storage() + new_i * nb_component,
                    vect.storage() + i * nb_component, nb_component * sizeof(T));
             ++new_size;
           }
         }
         tmp.resize(new_size);
         vect.copy(tmp);
       }
     }
   }
 }
 
 /* -------------------------------------------------------------------------- */
 template <typename T, typename SupportType>
 void ElementTypeMapArray<T, SupportType>::printself(std::ostream & stream,
                                                     int indent) const {
   std::string space;
   for (Int i = 0; i < indent; i++, space += AKANTU_INDENT)
     ;
 
   stream << space << "ElementTypeMapArray<" << debug::demangle(typeid(T).name())
          << "> [" << std::endl;
   for (UInt g = _not_ghost; g <= _ghost; ++g) {
     auto gt = (GhostType)g;
 
     const DataMap & data = this->getData(gt);
     typename DataMap::const_iterator it;
     for (it = data.begin(); it != data.end(); ++it) {
       stream << space << space << ElementTypeMapArray::printType(it->first, gt)
              << " [" << std::endl;
       it->second->printself(stream, indent + 3);
       stream << space << space << " ]" << std::endl;
     }
   }
   stream << space << "]" << std::endl;
 }
 
 /* -------------------------------------------------------------------------- */
 /* SupportType Iterator                                                       */
 /* -------------------------------------------------------------------------- */
 template <class Stored, typename SupportType>
 ElementTypeMap<Stored, SupportType>::type_iterator::type_iterator(
     DataMapIterator & list_begin, DataMapIterator & list_end, UInt dim,
     ElementKind ek)
     : list_begin(list_begin), list_end(list_end), dim(dim), kind(ek) {}
 
 /* -------------------------------------------------------------------------- */
 template <class Stored, typename SupportType>
 ElementTypeMap<Stored, SupportType>::type_iterator::type_iterator(
     const type_iterator & it)
     : list_begin(it.list_begin), list_end(it.list_end), dim(it.dim),
       kind(it.kind) {}
 
 /* -------------------------------------------------------------------------- */
 template <class Stored, typename SupportType>
 typename ElementTypeMap<Stored, SupportType>::type_iterator &
 ElementTypeMap<Stored, SupportType>::type_iterator::
 operator=(const type_iterator & it) {
   if (this != &it) {
     list_begin = it.list_begin;
     list_end = it.list_end;
     dim = it.dim;
     kind = it.kind;
   }
   return *this;
 }
 /* -------------------------------------------------------------------------- */
 template <class Stored, typename SupportType>
 inline typename ElementTypeMap<Stored, SupportType>::type_iterator::reference
     ElementTypeMap<Stored, SupportType>::type_iterator::operator*() {
   return list_begin->first;
 }
 
 /* -------------------------------------------------------------------------- */
 template <class Stored, typename SupportType>
 inline typename ElementTypeMap<Stored, SupportType>::type_iterator::reference
     ElementTypeMap<Stored, SupportType>::type_iterator::operator*() const {
   return list_begin->first;
 }
 
 /* -------------------------------------------------------------------------- */
 template <class Stored, typename SupportType>
 inline typename ElementTypeMap<Stored, SupportType>::type_iterator &
     ElementTypeMap<Stored, SupportType>::type_iterator::operator++() {
   ++list_begin;
   while ((list_begin != list_end) &&
          (((dim != _all_dimensions) &&
            (dim != Mesh::getSpatialDimension(list_begin->first))) ||
           ((kind != _ek_not_defined) &&
            (kind != Mesh::getKind(list_begin->first)))))
     ++list_begin;
   return *this;
 }
 
 /* -------------------------------------------------------------------------- */
 template <class Stored, typename SupportType>
 typename ElementTypeMap<Stored, SupportType>::type_iterator
     ElementTypeMap<Stored, SupportType>::type_iterator::operator++(int) {
   type_iterator tmp(*this);
   operator++();
   return tmp;
 }
 
 /* -------------------------------------------------------------------------- */
 template <class Stored, typename SupportType>
 inline bool ElementTypeMap<Stored, SupportType>::type_iterator::
 operator==(const type_iterator & other) const {
   return this->list_begin == other.list_begin;
 }
 
 /* -------------------------------------------------------------------------- */
 template <class Stored, typename SupportType>
 inline bool ElementTypeMap<Stored, SupportType>::type_iterator::
 operator!=(const type_iterator & other) const {
   return this->list_begin != other.list_begin;
 }
 
 /* -------------------------------------------------------------------------- */
 template <class Stored, typename SupportType>
 typename ElementTypeMap<Stored, SupportType>::ElementTypesIteratorHelper
 ElementTypeMap<Stored, SupportType>::elementTypesImpl(UInt dim,
                                                       GhostType ghost_type,
                                                       ElementKind kind) const {
   return ElementTypesIteratorHelper(*this, dim, ghost_type, kind);
 }
 
 /* -------------------------------------------------------------------------- */
 template <class Stored, typename SupportType>
 template <typename... pack>
 typename ElementTypeMap<Stored, SupportType>::ElementTypesIteratorHelper
 ElementTypeMap<Stored, SupportType>::elementTypesImpl(
     const use_named_args_t & unused, pack &&... _pack) const {
   return ElementTypesIteratorHelper(*this, unused, _pack...);
 }
 
 /* -------------------------------------------------------------------------- */
 template <class Stored, typename SupportType>
 inline typename ElementTypeMap<Stored, SupportType>::type_iterator
 ElementTypeMap<Stored, SupportType>::firstType(UInt dim, GhostType ghost_type,
                                                ElementKind kind) const {
   typename DataMap::const_iterator b, e;
   b = getData(ghost_type).begin();
   e = getData(ghost_type).end();
 
   // loop until the first valid type
   while ((b != e) &&
          (((dim != _all_dimensions) &&
            (dim != Mesh::getSpatialDimension(b->first))) ||
           ((kind != _ek_not_defined) && (kind != Mesh::getKind(b->first)))))
     ++b;
 
   return typename ElementTypeMap<Stored, SupportType>::type_iterator(b, e, dim,
                                                                      kind);
 }
 
 /* -------------------------------------------------------------------------- */
 template <class Stored, typename SupportType>
 inline typename ElementTypeMap<Stored, SupportType>::type_iterator
 ElementTypeMap<Stored, SupportType>::lastType(UInt dim, GhostType ghost_type,
                                               ElementKind kind) const {
   typename DataMap::const_iterator e;
   e = getData(ghost_type).end();
   return typename ElementTypeMap<Stored, SupportType>::type_iterator(e, e, dim,
                                                                      kind);
 }
 
 /* -------------------------------------------------------------------------- */
 
 /// standard output stream operator
 template <class Stored, typename SupportType>
 inline std::ostream &
 operator<<(std::ostream & stream,
            const ElementTypeMap<Stored, SupportType> & _this) {
   _this.printself(stream);
   return stream;
 }
 
 /* -------------------------------------------------------------------------- */
 class ElementTypeMapArrayInitializer {
 protected:
   using CompFunc = std::function<UInt(const ElementType &, const GhostType &)>;
 
 public:
   ElementTypeMapArrayInitializer(const CompFunc & comp_func,
                                  UInt spatial_dimension = _all_dimensions,
                                  const GhostType & ghost_type = _not_ghost,
                                  const ElementKind & element_kind = _ek_regular)
       : comp_func(comp_func), spatial_dimension(spatial_dimension),
         ghost_type(ghost_type), element_kind(element_kind) {}
 
   const GhostType & ghostType() const { return ghost_type; }
 
   virtual UInt nbComponent(const ElementType & type) const {
     return comp_func(type, ghostType());
   }
 
 protected:
   CompFunc comp_func;
   UInt spatial_dimension;
   GhostType ghost_type;
   ElementKind element_kind;
 };
 
 /* -------------------------------------------------------------------------- */
 class MeshElementTypeMapArrayInitializer
     : public ElementTypeMapArrayInitializer {
   using CompFunc = ElementTypeMapArrayInitializer::CompFunc;
 
 public:
   MeshElementTypeMapArrayInitializer(
       const Mesh & mesh, UInt nb_component = 1,
       UInt spatial_dimension = _all_dimensions,
       const GhostType & ghost_type = _not_ghost,
       const ElementKind & element_kind = _ek_regular,
       bool with_nb_element = false, bool with_nb_nodes_per_element = false)
       : MeshElementTypeMapArrayInitializer(
             mesh,
             [nb_component](const ElementType &, const GhostType &) -> UInt {
               return nb_component;
             },
             spatial_dimension, ghost_type, element_kind, with_nb_element,
             with_nb_nodes_per_element) {}
 
   MeshElementTypeMapArrayInitializer(
       const Mesh & mesh, const CompFunc & comp_func,
       UInt spatial_dimension = _all_dimensions,
       const GhostType & ghost_type = _not_ghost,
       const ElementKind & element_kind = _ek_regular,
       bool with_nb_element = false, bool with_nb_nodes_per_element = false)
       : ElementTypeMapArrayInitializer(comp_func, spatial_dimension, ghost_type,
                                        element_kind),
         mesh(mesh), with_nb_element(with_nb_element),
         with_nb_nodes_per_element(with_nb_nodes_per_element) {}
 
   decltype(auto) elementTypes() const {
     return mesh.elementTypes(this->spatial_dimension, this->ghost_type,
                              this->element_kind);
   }
 
   virtual UInt size(const ElementType & type) const {
     if (with_nb_element)
       return mesh.getNbElement(type, this->ghost_type);
 
     return 0;
   }
 
   UInt nbComponent(const ElementType & type) const override {
     UInt res = ElementTypeMapArrayInitializer::nbComponent(type);
     if (with_nb_nodes_per_element)
       return (res * mesh.getNbNodesPerElement(type));
 
     return res;
   }
 
 protected:
   const Mesh & mesh;
   bool with_nb_element;
   bool with_nb_nodes_per_element;
 };
 
 /* -------------------------------------------------------------------------- */
 class FEEngineElementTypeMapArrayInitializer
     : public MeshElementTypeMapArrayInitializer {
 public:
   FEEngineElementTypeMapArrayInitializer(
       const FEEngine & fe_engine, UInt nb_component = 1,
       UInt spatial_dimension = _all_dimensions,
       const GhostType & ghost_type = _not_ghost,
       const ElementKind & element_kind = _ek_regular);
 
   FEEngineElementTypeMapArrayInitializer(
       const FEEngine & fe_engine,
       const ElementTypeMapArrayInitializer::CompFunc & nb_component,
       UInt spatial_dimension = _all_dimensions,
       const GhostType & ghost_type = _not_ghost,
       const ElementKind & element_kind = _ek_regular);
 
   UInt size(const ElementType & type) const override;
 
   using ElementTypesIteratorHelper =
       ElementTypeMapArray<Real, ElementType>::ElementTypesIteratorHelper;
 
   ElementTypesIteratorHelper elementTypes() const;
 
 protected:
   const FEEngine & fe_engine;
 };
 
 /* -------------------------------------------------------------------------- */
 template <typename T, typename SupportType>
 template <class Func>
 void ElementTypeMapArray<T, SupportType>::initialize(const Func & f,
                                                      const T & default_value,
                                                      bool do_not_default) {
   auto ghost_type = f.ghostType();
   for (auto & type : f.elementTypes()) {
     if (not this->exists(type, ghost_type))
       if (do_not_default) {
         auto & array = this->alloc(0, f.nbComponent(type), type, ghost_type);
         array.resize(f.size(type));
       } else {
         this->alloc(f.size(type), f.nbComponent(type), type, ghost_type,
                     default_value);
       }
     else {
       auto & array = this->operator()(type, ghost_type);
       if (not do_not_default)
         array.resize(f.size(type), default_value);
       else
         array.resize(f.size(type));
     }
   }
 }
 
 /* -------------------------------------------------------------------------- */
 /**
  * All parameters are named optionals
  *  \param _nb_component a functor giving the number of components per
  *  (ElementType, GhostType) pair or a scalar giving a unique number of
  * components
  *  regardless of type
  *  \param _spatial_dimension a filter for the elements of a specific dimension
  *  \param _element_kind filter with element kind (_ek_regular, _ek_structural,
  * ...)
  *  \param _with_nb_element allocate the arrays with the number of elements for
  * each
  *  type in the mesh
  *  \param _with_nb_nodes_per_element multiply the number of components by the
  *  number of nodes per element
  *  \param _default_value default inital value
  *  \param _do_not_default do not initialize the allocated arrays
  *  \param _ghost_type filter a type of ghost
  */
 template <typename T, typename SupportType>
 template <typename... pack>
 void ElementTypeMapArray<T, SupportType>::initialize(const Mesh & mesh,
                                                      pack &&... _pack) {
   GhostType requested_ghost_type = OPTIONAL_NAMED_ARG(ghost_type, _casper);
   bool all_ghost_types = requested_ghost_type == _casper;
 
   for (auto ghost_type : ghost_types) {
     if ((not(ghost_type == requested_ghost_type)) and (not all_ghost_types))
       continue;
 
     // This thing should have a UInt or functor type
     auto && nb_components = OPTIONAL_NAMED_ARG(nb_component, 1);
     auto functor = MeshElementTypeMapArrayInitializer(
         mesh, std::forward<decltype(nb_components)>(nb_components),
         OPTIONAL_NAMED_ARG(spatial_dimension, mesh.getSpatialDimension()),
         ghost_type, OPTIONAL_NAMED_ARG(element_kind, _ek_regular),
         OPTIONAL_NAMED_ARG(with_nb_element, false),
         OPTIONAL_NAMED_ARG(with_nb_nodes_per_element, false));
 
     this->initialize(functor, OPTIONAL_NAMED_ARG(default_value, T()),
                      OPTIONAL_NAMED_ARG(do_not_default, false));
   }
 }
 
 /* -------------------------------------------------------------------------- */
 /**
  * All parameters are named optionals
  *  \param _nb_component a functor giving the number of components per
  *  (ElementType, GhostType) pair or a scalar giving a unique number of
  * components
  *  regardless of type
  *  \param _spatial_dimension a filter for the elements of a specific dimension
  *  \param _element_kind filter with element kind (_ek_regular, _ek_structural,
  * ...)
  *  \param _default_value default inital value
  *  \param _do_not_default do not initialize the allocated arrays
  *  \param _ghost_type filter a specific ghost type
  *  \param _all_ghost_types get all ghost types
  */
 template <typename T, typename SupportType>
 template <typename... pack>
 void ElementTypeMapArray<T, SupportType>::initialize(const FEEngine & fe_engine,
                                                      pack &&... _pack) {
   bool all_ghost_types = OPTIONAL_NAMED_ARG(all_ghost_types, true);
   GhostType requested_ghost_type = OPTIONAL_NAMED_ARG(ghost_type, _not_ghost);
 
   for (auto ghost_type : ghost_types) {
     if ((not(ghost_type == requested_ghost_type)) and (not all_ghost_types))
       continue;
 
     auto && nb_components = OPTIONAL_NAMED_ARG(nb_component, 1);
     auto functor = FEEngineElementTypeMapArrayInitializer(
         fe_engine, std::forward<decltype(nb_components)>(nb_components),
         OPTIONAL_NAMED_ARG(spatial_dimension, UInt(-2)), ghost_type,
         OPTIONAL_NAMED_ARG(element_kind, _ek_regular));
 
     this->initialize(functor, OPTIONAL_NAMED_ARG(default_value, T()),
                      OPTIONAL_NAMED_ARG(do_not_default, false));
   }
 }
 
 /* -------------------------------------------------------------------------- */
 template <class T, typename SupportType>
 inline T & ElementTypeMapArray<T, SupportType>::
 operator()(const Element & element, UInt component) {
   return this->operator()(element.type, element.ghost_type)(element.element,
                                                             component);
 }
 
 /* -------------------------------------------------------------------------- */
 template <class T, typename SupportType>
 inline const T & ElementTypeMapArray<T, SupportType>::
 operator()(const Element & element, UInt component) const {
   return this->operator()(element.type, element.ghost_type)(element.element,
                                                             component);
 }
 
 } // namespace akantu
 
 #endif /* __AKANTU_ELEMENT_TYPE_MAP_TMPL_HH__ */
diff --git a/src/mesh/group_manager.cc b/src/mesh/group_manager.cc
index a18c02007..98c067ce4 100644
--- a/src/mesh/group_manager.cc
+++ b/src/mesh/group_manager.cc
@@ -1,1040 +1,1040 @@
 /**
  * @file   group_manager.cc
  *
  * @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
  * @author Dana Christen <dana.christen@gmail.com>
  * @author David Simon Kammer <david.kammer@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  * @author Marco Vocialta <marco.vocialta@epfl.ch>
  *
  * @date creation: Wed Nov 13 2013
- * @date last modification: Mon Aug 17 2015
+ * @date last modification: Tue Feb 20 2018
  *
  * @brief  Stores information about ElementGroup and NodeGroup
  *
  * @section LICENSE
  *
- * Copyright  (©)  2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de Lausanne)
+ * 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
+ * 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
+ * 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 "group_manager.hh"
 #include "aka_csr.hh"
 #include "data_accessor.hh"
 #include "element_group.hh"
 #include "element_synchronizer.hh"
 #include "mesh.hh"
 #include "mesh_accessor.hh"
 #include "mesh_utils.hh"
 #include "node_group.hh"
 /* -------------------------------------------------------------------------- */
 #include <algorithm>
 #include <iterator>
 #include <list>
 #include <numeric>
 #include <queue>
 #include <sstream>
 #include <utility>
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 GroupManager::GroupManager(const Mesh & mesh, const ID & id,
                            const MemoryID & mem_id)
     : id(id), memory_id(mem_id), mesh(mesh) {
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 GroupManager::~GroupManager() {
   auto eit = element_groups.begin();
   auto eend = element_groups.end();
   for (; eit != eend; ++eit)
     delete (eit->second);
 
   auto nit = node_groups.begin();
   auto nend = node_groups.end();
   for (; nit != nend; ++nit)
     delete (nit->second);
 }
 
 /* -------------------------------------------------------------------------- */
 NodeGroup & GroupManager::createNodeGroup(const std::string & group_name,
                                           bool replace_group) {
   AKANTU_DEBUG_IN();
 
   auto it = node_groups.find(group_name);
 
   if (it != node_groups.end()) {
     if (replace_group) {
       it->second->empty();
       AKANTU_DEBUG_OUT();
       return *(it->second);
     } else
       AKANTU_EXCEPTION(
           "Trying to create a node group that already exists:" << group_name);
   }
 
   std::stringstream sstr;
   sstr << this->id << ":" << group_name << "_node_group";
 
   NodeGroup * node_group =
       new NodeGroup(group_name, mesh, sstr.str(), memory_id);
 
   node_groups[group_name] = node_group;
 
   AKANTU_DEBUG_OUT();
 
   return *node_group;
 }
 
 /* -------------------------------------------------------------------------- */
 template <typename T>
 NodeGroup &
 GroupManager::createFilteredNodeGroup(const std::string & group_name,
                                       const NodeGroup & source_node_group,
                                       T & filter) {
   AKANTU_DEBUG_IN();
 
   NodeGroup & node_group = this->createNodeGroup(group_name);
   node_group.append(source_node_group);
   if (T::type == FilterFunctor::_node_filter_functor) {
     node_group.applyNodeFilter(filter);
   } else {
     AKANTU_ERROR("ElementFilter cannot be applied to NodeGroup yet."
                  << " Needs to be implemented.");
   }
 
   AKANTU_DEBUG_OUT();
   return node_group;
 }
 
 /* -------------------------------------------------------------------------- */
 void GroupManager::destroyNodeGroup(const std::string & group_name) {
   AKANTU_DEBUG_IN();
 
   auto nit = node_groups.find(group_name);
   auto nend = node_groups.end();
   if (nit != nend) {
     delete (nit->second);
     node_groups.erase(nit);
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 ElementGroup & GroupManager::createElementGroup(const std::string & group_name,
                                                 UInt dimension,
                                                 bool replace_group) {
   AKANTU_DEBUG_IN();
 
   NodeGroup & new_node_group =
       createNodeGroup(group_name + "_nodes", replace_group);
 
   auto it = element_groups.find(group_name);
 
   if (it != element_groups.end()) {
     if (replace_group) {
       it->second->empty();
       AKANTU_DEBUG_OUT();
       return *(it->second);
     } else
       AKANTU_EXCEPTION("Trying to create a element group that already exists:"
                        << group_name);
   }
 
   std::stringstream sstr;
   sstr << this->id << ":" << group_name << "_element_group";
 
   ElementGroup * element_group = new ElementGroup(
       group_name, mesh, new_node_group, dimension, sstr.str(), memory_id);
 
   std::stringstream sstr_nodes;
   sstr_nodes << group_name << "_nodes";
 
   node_groups[sstr_nodes.str()] = &new_node_group;
   element_groups[group_name] = element_group;
 
   AKANTU_DEBUG_OUT();
 
   return *element_group;
 }
 
 /* -------------------------------------------------------------------------- */
 void GroupManager::destroyElementGroup(const std::string & group_name,
                                        bool destroy_node_group) {
   AKANTU_DEBUG_IN();
 
   auto eit = element_groups.find(group_name);
   auto eend = element_groups.end();
   if (eit != eend) {
     if (destroy_node_group)
       destroyNodeGroup(eit->second->getNodeGroup().getName());
     delete (eit->second);
     element_groups.erase(eit);
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void GroupManager::destroyAllElementGroups(bool destroy_node_groups) {
   AKANTU_DEBUG_IN();
 
   auto eit = element_groups.begin();
   auto eend = element_groups.end();
   for (; eit != eend; ++eit) {
     if (destroy_node_groups)
       destroyNodeGroup(eit->second->getNodeGroup().getName());
     delete (eit->second);
   }
   element_groups.clear();
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 ElementGroup & GroupManager::createElementGroup(const std::string & group_name,
                                                 UInt dimension,
                                                 NodeGroup & node_group) {
   AKANTU_DEBUG_IN();
 
   if (element_groups.find(group_name) != element_groups.end())
     AKANTU_EXCEPTION(
         "Trying to create a element group that already exists:" << group_name);
 
   ElementGroup * element_group =
       new ElementGroup(group_name, mesh, node_group, dimension,
                        id + ":" + group_name + "_element_group", memory_id);
 
   element_groups[group_name] = element_group;
 
   AKANTU_DEBUG_OUT();
 
   return *element_group;
 }
 
 /* -------------------------------------------------------------------------- */
 template <typename T>
 ElementGroup & GroupManager::createFilteredElementGroup(
     const std::string & group_name, UInt dimension,
     const NodeGroup & node_group, T & filter) {
   AKANTU_DEBUG_IN();
 
   ElementGroup * element_group = nullptr;
 
   if (T::type == FilterFunctor::_node_filter_functor) {
     NodeGroup & filtered_node_group = this->createFilteredNodeGroup(
         group_name + "_nodes", node_group, filter);
     element_group =
         &(this->createElementGroup(group_name, dimension, filtered_node_group));
   } else if (T::type == FilterFunctor::_element_filter_functor) {
     AKANTU_ERROR(
         "Cannot handle an ElementFilter yet. Needs to be implemented.");
   }
 
   AKANTU_DEBUG_OUT();
 
   return *element_group;
 }
 
 /* -------------------------------------------------------------------------- */
 class ClusterSynchronizer : public DataAccessor<Element> {
   using DistantIDs = std::set<std::pair<UInt, UInt>>;
 
 public:
   ClusterSynchronizer(GroupManager & group_manager, UInt element_dimension,
                       std::string cluster_name_prefix,
                       ElementTypeMapArray<UInt> & element_to_fragment,
                       const ElementSynchronizer & element_synchronizer,
                       UInt nb_cluster)
       : group_manager(group_manager), element_dimension(element_dimension),
         cluster_name_prefix(std::move(cluster_name_prefix)),
         element_to_fragment(element_to_fragment),
         element_synchronizer(element_synchronizer), nb_cluster(nb_cluster) {}
 
   UInt synchronize() {
     Communicator & comm = Communicator::getStaticCommunicator();
     UInt rank = comm.whoAmI();
     UInt nb_proc = comm.getNbProc();
 
     /// find starting index to renumber local clusters
     Array<UInt> nb_cluster_per_proc(nb_proc);
     nb_cluster_per_proc(rank) = nb_cluster;
     comm.allGather(nb_cluster_per_proc);
 
     starting_index = std::accumulate(nb_cluster_per_proc.begin(),
                                      nb_cluster_per_proc.begin() + rank, 0);
 
     UInt global_nb_fragment =
         std::accumulate(nb_cluster_per_proc.begin() + rank,
                         nb_cluster_per_proc.end(), starting_index);
 
     /// create the local to distant cluster pairs with neighbors
     element_synchronizer.synchronizeOnce(*this, _gst_gm_clusters);
 
     /// count total number of pairs
     Array<int> nb_pairs(nb_proc); // This is potentially a bug for more than
     // 2**31 pairs, but due to a all gatherv after
     // it must be int to match MPI interfaces
     nb_pairs(rank) = distant_ids.size();
     comm.allGather(nb_pairs);
 
     UInt total_nb_pairs = std::accumulate(nb_pairs.begin(), nb_pairs.end(), 0);
 
     /// generate pairs global array
     UInt local_pair_index =
         std::accumulate(nb_pairs.storage(), nb_pairs.storage() + rank, 0);
 
     Array<UInt> total_pairs(total_nb_pairs, 2);
 
     for (auto & ids : distant_ids) {
       total_pairs(local_pair_index, 0) = ids.first;
       total_pairs(local_pair_index, 1) = ids.second;
       ++local_pair_index;
     }
 
     /// communicate pairs to all processors
     nb_pairs *= 2;
     comm.allGatherV(total_pairs, nb_pairs);
 
     /// renumber clusters
 
     /// generate fragment list
     std::vector<std::set<UInt>> global_clusters;
     UInt total_nb_cluster = 0;
 
     Array<bool> is_fragment_in_cluster(global_nb_fragment, 1, false);
     std::queue<UInt> fragment_check_list;
 
     while (total_pairs.size() != 0) {
       /// create a new cluster
       ++total_nb_cluster;
       global_clusters.resize(total_nb_cluster);
       std::set<UInt> & current_cluster = global_clusters[total_nb_cluster - 1];
 
       UInt first_fragment = total_pairs(0, 0);
       UInt second_fragment = total_pairs(0, 1);
       total_pairs.erase(0);
 
       fragment_check_list.push(first_fragment);
       fragment_check_list.push(second_fragment);
 
       while (!fragment_check_list.empty()) {
         UInt current_fragment = fragment_check_list.front();
 
         UInt * total_pairs_end = total_pairs.storage() + total_pairs.size() * 2;
 
         UInt * fragment_found =
             std::find(total_pairs.storage(), total_pairs_end, current_fragment);
 
         if (fragment_found != total_pairs_end) {
           UInt position = fragment_found - total_pairs.storage();
           UInt pair = position / 2;
           UInt other_index = (position + 1) % 2;
           fragment_check_list.push(total_pairs(pair, other_index));
           total_pairs.erase(pair);
         } else {
           fragment_check_list.pop();
           current_cluster.insert(current_fragment);
           is_fragment_in_cluster(current_fragment) = true;
         }
       }
     }
 
     /// add to FragmentToCluster all local fragments
     for (UInt c = 0; c < global_nb_fragment; ++c) {
       if (!is_fragment_in_cluster(c)) {
         ++total_nb_cluster;
         global_clusters.resize(total_nb_cluster);
         std::set<UInt> & current_cluster =
             global_clusters[total_nb_cluster - 1];
 
         current_cluster.insert(c);
       }
     }
 
     /// reorganize element groups to match global clusters
     for (UInt c = 0; c < global_clusters.size(); ++c) {
 
       /// create new element group corresponding to current cluster
       std::stringstream sstr;
       sstr << cluster_name_prefix << "_" << c;
       ElementGroup & cluster =
           group_manager.createElementGroup(sstr.str(), element_dimension, true);
 
       auto it = global_clusters[c].begin();
       auto end = global_clusters[c].end();
 
       /// append to current element group all fragments that belong to
       /// the same cluster if they exist
       for (; it != end; ++it) {
         Int local_index = *it - starting_index;
 
         if (local_index < 0 || local_index >= Int(nb_cluster))
           continue;
 
         std::stringstream tmp_sstr;
         tmp_sstr << "tmp_" << cluster_name_prefix << "_" << local_index;
         auto eg_it = group_manager.element_group_find(tmp_sstr.str());
 
         AKANTU_DEBUG_ASSERT(eg_it != group_manager.element_group_end(),
                             "Temporary fragment \"" << tmp_sstr.str()
                                                     << "\" not found");
 
         cluster.append(*(eg_it->second));
         group_manager.destroyElementGroup(tmp_sstr.str(), true);
       }
     }
 
     return total_nb_cluster;
   }
 
 private:
   /// functions for parallel communications
   inline UInt getNbData(const Array<Element> & elements,
                         const SynchronizationTag & tag) const override {
     if (tag == _gst_gm_clusters)
       return elements.size() * sizeof(UInt);
 
     return 0;
   }
 
   inline void packData(CommunicationBuffer & buffer,
                        const Array<Element> & elements,
                        const SynchronizationTag & tag) const override {
     if (tag != _gst_gm_clusters)
       return;
 
     Array<Element>::const_iterator<> el_it = elements.begin();
     Array<Element>::const_iterator<> el_end = elements.end();
 
     for (; el_it != el_end; ++el_it) {
 
       const Element & el = *el_it;
 
       /// for each element pack its global cluster index
       buffer << element_to_fragment(el.type, el.ghost_type)(el.element) +
                     starting_index;
     }
   }
 
   inline void unpackData(CommunicationBuffer & buffer,
                          const Array<Element> & elements,
                          const SynchronizationTag & tag) override {
     if (tag != _gst_gm_clusters)
       return;
 
     Array<Element>::const_iterator<> el_it = elements.begin();
     Array<Element>::const_iterator<> el_end = elements.end();
 
     for (; el_it != el_end; ++el_it) {
       UInt distant_cluster;
 
       buffer >> distant_cluster;
 
       const Element & el = *el_it;
       UInt local_cluster =
           element_to_fragment(el.type, el.ghost_type)(el.element) +
           starting_index;
 
       distant_ids.insert(std::make_pair(local_cluster, distant_cluster));
     }
   }
 
 private:
   GroupManager & group_manager;
   UInt element_dimension;
   std::string cluster_name_prefix;
   ElementTypeMapArray<UInt> & element_to_fragment;
   const ElementSynchronizer & element_synchronizer;
 
   UInt nb_cluster;
   DistantIDs distant_ids;
 
   UInt starting_index;
 };
 
 /* -------------------------------------------------------------------------- */
 /// \todo this function doesn't work in 1D
 UInt GroupManager::createBoundaryGroupFromGeometry() {
   UInt spatial_dimension = mesh.getSpatialDimension();
 
   return createClusters(spatial_dimension - 1, "boundary");
 }
 
 /* -------------------------------------------------------------------------- */
 UInt GroupManager::createClusters(
     UInt element_dimension, Mesh & mesh_facets, std::string cluster_name_prefix,
     const GroupManager::ClusteringFilter & filter) {
   return createClusters(element_dimension, std::move(cluster_name_prefix),
                         filter, mesh_facets);
 }
 
 /* -------------------------------------------------------------------------- */
 UInt GroupManager::createClusters(
     UInt element_dimension, std::string cluster_name_prefix,
     const GroupManager::ClusteringFilter & filter) {
   std::unique_ptr<Mesh> mesh_facets;
   if (!mesh_facets && element_dimension > 0) {
     MeshAccessor mesh_accessor(const_cast<Mesh &>(mesh));
     mesh_facets = std::make_unique<Mesh>(mesh.getSpatialDimension(),
                                          mesh_accessor.getNodesSharedPtr(),
                                          "mesh_facets_for_clusters");
 
     mesh_facets->defineMeshParent(mesh);
 
     MeshUtils::buildAllFacets(mesh, *mesh_facets, element_dimension,
                               element_dimension - 1);
   }
 
   return createClusters(element_dimension, std::move(cluster_name_prefix),
                         filter, *mesh_facets);
 }
 
 /* -------------------------------------------------------------------------- */
 //// \todo if needed element list construction can be optimized by
 //// templating the filter class
 UInt GroupManager::createClusters(UInt element_dimension,
                                   const std::string & cluster_name_prefix,
                                   const GroupManager::ClusteringFilter & filter,
                                   Mesh & mesh_facets) {
   AKANTU_DEBUG_IN();
 
   UInt nb_proc = mesh.getCommunicator().getNbProc();
   std::string tmp_cluster_name_prefix = cluster_name_prefix;
 
   ElementTypeMapArray<UInt> * element_to_fragment = nullptr;
 
   if (nb_proc > 1 && mesh.isDistributed()) {
     element_to_fragment =
         new ElementTypeMapArray<UInt>("element_to_fragment", id, memory_id);
 
     element_to_fragment->initialize(
         mesh, _nb_component = 1, _spatial_dimension = element_dimension,
         _element_kind = _ek_not_defined, _with_nb_element = true);
     // mesh.initElementTypeMapArray(*element_to_fragment, 1, element_dimension,
     //                              false, _ek_not_defined, true);
     tmp_cluster_name_prefix = "tmp_" + tmp_cluster_name_prefix;
   }
 
   ElementTypeMapArray<bool> seen_elements("seen_elements", id, memory_id);
   seen_elements.initialize(mesh, _spatial_dimension = element_dimension,
                            _element_kind = _ek_not_defined,
                            _with_nb_element = true);
   // mesh.initElementTypeMapArray(seen_elements, 1, element_dimension, false,
   //                              _ek_not_defined, true);
 
   for (ghost_type_t::iterator gt = ghost_type_t::begin();
        gt != ghost_type_t::end(); ++gt) {
 
     GhostType ghost_type = *gt;
     Element el;
     el.ghost_type = ghost_type;
 
     Mesh::type_iterator type_it =
         mesh.firstType(element_dimension, ghost_type, _ek_not_defined);
     Mesh::type_iterator type_end =
         mesh.lastType(element_dimension, ghost_type, _ek_not_defined);
 
     for (; type_it != type_end; ++type_it) {
       el.type = *type_it;
       UInt nb_element = mesh.getNbElement(*type_it, ghost_type);
       Array<bool> & seen_elements_array = seen_elements(el.type, ghost_type);
 
       for (UInt e = 0; e < nb_element; ++e) {
         el.element = e;
         if (!filter(el))
           seen_elements_array(e) = true;
       }
     }
   }
 
   Array<bool> checked_node(mesh.getNbNodes(), 1, false);
 
   UInt nb_cluster = 0;
 
   /// keep looping until all elements are seen
   for (ghost_type_t::iterator gt = ghost_type_t::begin();
        gt != ghost_type_t::end(); ++gt) {
 
     GhostType ghost_type = *gt;
     Element uns_el;
     uns_el.ghost_type = ghost_type;
 
     Mesh::type_iterator type_it =
         mesh.firstType(element_dimension, ghost_type, _ek_not_defined);
     Mesh::type_iterator type_end =
         mesh.lastType(element_dimension, ghost_type, _ek_not_defined);
 
     for (; type_it != type_end; ++type_it) {
       uns_el.type = *type_it;
       Array<bool> & seen_elements_vec =
           seen_elements(uns_el.type, uns_el.ghost_type);
 
       for (UInt e = 0; e < seen_elements_vec.size(); ++e) {
         // skip elements that have been already seen
         if (seen_elements_vec(e) == true)
           continue;
 
         // set current element
         uns_el.element = e;
         seen_elements_vec(e) = true;
 
         /// create a new cluster
         std::stringstream sstr;
         sstr << tmp_cluster_name_prefix << "_" << nb_cluster;
         ElementGroup & cluster =
             createElementGroup(sstr.str(), element_dimension, true);
         ++nb_cluster;
 
         // point element are cluster by themself
         if (element_dimension == 0) {
           cluster.add(uns_el);
 
           UInt nb_nodes_per_element = Mesh::getNbNodesPerElement(uns_el.type);
           Vector<UInt> connect =
               mesh.getConnectivity(uns_el.type, uns_el.ghost_type)
                   .begin(nb_nodes_per_element)[uns_el.element];
           for (UInt n = 0; n < nb_nodes_per_element; ++n) {
             /// add element's nodes to the cluster
             UInt node = connect[n];
             if (!checked_node(node)) {
               cluster.addNode(node);
               checked_node(node) = true;
             }
           }
 
           continue;
         }
 
         std::queue<Element> element_to_add;
         element_to_add.push(uns_el);
 
         /// keep looping until current cluster is complete (no more
         /// connected elements)
         while (!element_to_add.empty()) {
 
           /// take first element and erase it in the queue
           Element el = element_to_add.front();
           element_to_add.pop();
 
           /// if parallel, store cluster index per element
           if (nb_proc > 1 && mesh.isDistributed())
             (*element_to_fragment)(el.type, el.ghost_type)(el.element) =
                 nb_cluster - 1;
 
           /// add current element to the cluster
           cluster.add(el);
 
           const Array<Element> & element_to_facet =
               mesh_facets.getSubelementToElement(el.type, el.ghost_type);
 
           UInt nb_facet_per_element = element_to_facet.getNbComponent();
 
           for (UInt f = 0; f < nb_facet_per_element; ++f) {
             const Element & facet = element_to_facet(el.element, f);
 
             if (facet == ElementNull)
               continue;
 
             const std::vector<Element> & connected_elements =
                 mesh_facets.getElementToSubelement(
                     facet.type, facet.ghost_type)(facet.element);
 
             for (UInt elem = 0; elem < connected_elements.size(); ++elem) {
               const Element & check_el = connected_elements[elem];
 
               // check if this element has to be skipped
               if (check_el == ElementNull || check_el == el)
                 continue;
 
               Array<bool> & seen_elements_vec_current =
                   seen_elements(check_el.type, check_el.ghost_type);
 
               if (seen_elements_vec_current(check_el.element) == false) {
                 seen_elements_vec_current(check_el.element) = true;
                 element_to_add.push(check_el);
               }
             }
           }
 
           UInt nb_nodes_per_element = Mesh::getNbNodesPerElement(el.type);
           Vector<UInt> connect = mesh.getConnectivity(el.type, el.ghost_type)
                                      .begin(nb_nodes_per_element)[el.element];
           for (UInt n = 0; n < nb_nodes_per_element; ++n) {
             /// add element's nodes to the cluster
             UInt node = connect[n];
             if (!checked_node(node)) {
               cluster.addNode(node, false);
               checked_node(node) = true;
             }
           }
         }
       }
     }
   }
 
   if (nb_proc > 1 && mesh.isDistributed()) {
     ClusterSynchronizer cluster_synchronizer(
         *this, element_dimension, cluster_name_prefix, *element_to_fragment,
         this->mesh.getElementSynchronizer(), nb_cluster);
     nb_cluster = cluster_synchronizer.synchronize();
     delete element_to_fragment;
   }
 
   if (mesh.isDistributed())
     this->synchronizeGroupNames();
 
   AKANTU_DEBUG_OUT();
   return nb_cluster;
 }
 
 /* -------------------------------------------------------------------------- */
 template <typename T>
 void GroupManager::createGroupsFromMeshData(const std::string & dataset_name) {
   std::set<std::string> group_names;
   const ElementTypeMapArray<T> & datas = mesh.getData<T>(dataset_name);
   using type_iterator = typename ElementTypeMapArray<T>::type_iterator;
 
   std::map<std::string, UInt> group_dim;
 
   for (ghost_type_t::iterator gt = ghost_type_t::begin();
        gt != ghost_type_t::end(); ++gt) {
     type_iterator type_it = datas.firstType(_all_dimensions, *gt);
     type_iterator type_end = datas.lastType(_all_dimensions, *gt);
     for (; type_it != type_end; ++type_it) {
       const Array<T> & dataset = datas(*type_it, *gt);
       UInt nb_element = mesh.getNbElement(*type_it, *gt);
       AKANTU_DEBUG_ASSERT(dataset.size() == nb_element,
                           "Not the same number of elements ("
                               << *type_it << ":" << *gt
                               << ") in the map from MeshData ("
                               << dataset.size() << ") " << dataset_name
                               << " and in the mesh (" << nb_element << ")!");
       for (UInt e(0); e < nb_element; ++e) {
         std::stringstream sstr;
         sstr << dataset(e);
         std::string gname = sstr.str();
         group_names.insert(gname);
 
         auto it = group_dim.find(gname);
         if (it == group_dim.end()) {
           group_dim[gname] = mesh.getSpatialDimension(*type_it);
         } else {
           it->second = std::max(it->second, mesh.getSpatialDimension(*type_it));
         }
       }
     }
   }
 
   auto git = group_names.begin();
   auto gend = group_names.end();
   for (; git != gend; ++git)
     createElementGroup(*git, group_dim[*git]);
 
   if (mesh.isDistributed())
     this->synchronizeGroupNames();
 
   Element el;
   for (ghost_type_t::iterator gt = ghost_type_t::begin();
        gt != ghost_type_t::end(); ++gt) {
     el.ghost_type = *gt;
 
     type_iterator type_it = datas.firstType(_all_dimensions, *gt);
     type_iterator type_end = datas.lastType(_all_dimensions, *gt);
     for (; type_it != type_end; ++type_it) {
       el.type = *type_it;
 
       const Array<T> & dataset = datas(*type_it, *gt);
       UInt nb_element = mesh.getNbElement(*type_it, *gt);
       AKANTU_DEBUG_ASSERT(dataset.size() == nb_element,
                           "Not the same number of elements in the map from "
                           "MeshData and in the mesh!");
 
       UInt nb_nodes_per_element = mesh.getNbNodesPerElement(el.type);
 
       Array<UInt>::const_iterator<Vector<UInt>> cit =
           mesh.getConnectivity(*type_it, *gt).begin(nb_nodes_per_element);
 
       for (UInt e(0); e < nb_element; ++e, ++cit) {
         el.element = e;
         std::stringstream sstr;
         sstr << dataset(e);
         ElementGroup & group = getElementGroup(sstr.str());
         group.add(el, false, false);
 
         const Vector<UInt> & connect = *cit;
         for (UInt n = 0; n < nb_nodes_per_element; ++n) {
           UInt node = connect[n];
           group.addNode(node, false);
         }
       }
     }
   }
 
   git = group_names.begin();
   for (; git != gend; ++git) {
     getElementGroup(*git).optimize();
   }
 }
 
 template void GroupManager::createGroupsFromMeshData<std::string>(
     const std::string & dataset_name);
 template void
 GroupManager::createGroupsFromMeshData<UInt>(const std::string & dataset_name);
 
 /* -------------------------------------------------------------------------- */
 void GroupManager::createElementGroupFromNodeGroup(
     const std::string & name, const std::string & node_group_name,
     UInt dimension) {
   NodeGroup & node_group = getNodeGroup(node_group_name);
   ElementGroup & group = createElementGroup(name, dimension, node_group);
 
   group.fillFromNodeGroup();
 }
 
 /* -------------------------------------------------------------------------- */
 void GroupManager::printself(std::ostream & stream, int indent) const {
   std::string space;
   for (Int i = 0; i < indent; i++, space += AKANTU_INDENT)
     ;
 
   stream << space << "GroupManager [" << std::endl;
 
   std::set<std::string> node_group_seen;
   for (auto it(element_group_begin()); it != element_group_end(); ++it) {
     it->second->printself(stream, indent + 1);
     node_group_seen.insert(it->second->getNodeGroup().getName());
   }
 
   for (auto it(node_group_begin()); it != node_group_end(); ++it) {
     if (node_group_seen.find(it->second->getName()) == node_group_seen.end())
       it->second->printself(stream, indent + 1);
   }
 
   stream << space << "]" << std::endl;
 }
 
 /* -------------------------------------------------------------------------- */
 UInt GroupManager::getNbElementGroups(UInt dimension) const {
   if (dimension == _all_dimensions)
     return element_groups.size();
 
   auto it = element_groups.begin();
   auto end = element_groups.end();
   UInt count = 0;
   for (; it != end; ++it)
     count += (it->second->getDimension() == dimension);
   return count;
 }
 
 /* -------------------------------------------------------------------------- */
 void GroupManager::checkAndAddGroups(CommunicationBuffer & buffer) {
   AKANTU_DEBUG_IN();
 
   UInt nb_node_group;
   buffer >> nb_node_group;
   AKANTU_DEBUG_INFO("Received " << nb_node_group << " node group names");
 
   for (UInt ng = 0; ng < nb_node_group; ++ng) {
     std::string node_group_name;
     buffer >> node_group_name;
 
     if (node_groups.find(node_group_name) == node_groups.end()) {
       this->createNodeGroup(node_group_name);
     }
 
     AKANTU_DEBUG_INFO("Received node goup name: " << node_group_name);
   }
 
   UInt nb_element_group;
   buffer >> nb_element_group;
   AKANTU_DEBUG_INFO("Received " << nb_element_group << " element group names");
   for (UInt eg = 0; eg < nb_element_group; ++eg) {
     std::string element_group_name;
     buffer >> element_group_name;
     std::string node_group_name;
     buffer >> node_group_name;
     UInt dim;
     buffer >> dim;
 
     AKANTU_DEBUG_INFO("Received element group name: "
                       << element_group_name << " corresponding to a "
                       << Int(dim) << "D group with node group "
                       << node_group_name);
 
     NodeGroup & node_group = *node_groups[node_group_name];
 
     if (element_groups.find(element_group_name) == element_groups.end()) {
       this->createElementGroup(element_group_name, dim, node_group);
     }
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void GroupManager::fillBufferWithGroupNames(
     DynamicCommunicationBuffer & comm_buffer) const {
   AKANTU_DEBUG_IN();
 
   // packing node group names;
   UInt nb_groups = this->node_groups.size();
   comm_buffer << nb_groups;
   AKANTU_DEBUG_INFO("Sending " << nb_groups << " node group names");
 
   auto nnames_it = node_groups.begin();
   auto nnames_end = node_groups.end();
   for (; nnames_it != nnames_end; ++nnames_it) {
     std::string node_group_name = nnames_it->first;
     comm_buffer << node_group_name;
     AKANTU_DEBUG_INFO("Sending node goupe name: " << node_group_name);
   }
 
   // packing element group names with there associated node group name
   nb_groups = this->element_groups.size();
   comm_buffer << nb_groups;
   AKANTU_DEBUG_INFO("Sending " << nb_groups << " element group names");
   auto gnames_it = this->element_groups.begin();
   auto gnames_end = this->element_groups.end();
   for (; gnames_it != gnames_end; ++gnames_it) {
     ElementGroup & element_group = *(gnames_it->second);
     std::string element_group_name = gnames_it->first;
     std::string node_group_name = element_group.getNodeGroup().getName();
     UInt dim = element_group.getDimension();
 
     comm_buffer << element_group_name;
     comm_buffer << node_group_name;
     comm_buffer << dim;
 
     AKANTU_DEBUG_INFO("Sending element group name: "
                       << element_group_name << " corresponding to a "
                       << Int(dim) << "D group with the node group "
                       << node_group_name);
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void GroupManager::synchronizeGroupNames() {
   AKANTU_DEBUG_IN();
 
   const Communicator & comm = mesh.getCommunicator();
   Int nb_proc = comm.getNbProc();
   Int my_rank = comm.whoAmI();
 
   if (nb_proc == 1)
     return;
 
   if (my_rank == 0) {
     for (Int p = 1; p < nb_proc; ++p) {
       CommunicationStatus status;
       comm.probe<char>(p, p, status);
       AKANTU_DEBUG_INFO("Got " << printMemorySize<char>(status.size())
                                << " from proc " << p);
 
       CommunicationBuffer recv_buffer(status.size());
       comm.receive(recv_buffer, p, p);
 
       this->checkAndAddGroups(recv_buffer);
     }
 
     DynamicCommunicationBuffer comm_buffer;
     this->fillBufferWithGroupNames(comm_buffer);
 
     UInt buffer_size = comm_buffer.size();
 
     comm.broadcast(buffer_size, 0);
 
     AKANTU_DEBUG_INFO("Initiating broadcast with "
                       << printMemorySize<char>(comm_buffer.size()));
     comm.broadcast(comm_buffer, 0);
 
   } else {
     DynamicCommunicationBuffer comm_buffer;
     this->fillBufferWithGroupNames(comm_buffer);
 
     AKANTU_DEBUG_INFO("Sending " << printMemorySize<char>(comm_buffer.size())
                                  << " to proc " << 0);
     comm.send(comm_buffer, 0, my_rank);
 
     UInt buffer_size = 0;
     comm.broadcast(buffer_size, 0);
 
     AKANTU_DEBUG_INFO("Receiving broadcast with "
                       << printMemorySize<char>(comm_buffer.size()));
     CommunicationBuffer recv_buffer(buffer_size);
     comm.broadcast(recv_buffer, 0);
 
     this->checkAndAddGroups(recv_buffer);
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 const ElementGroup &
 GroupManager::getElementGroup(const std::string & name) const {
   auto it = element_group_find(name);
   if (it == element_group_end()) {
     AKANTU_EXCEPTION("There are no element groups named "
                      << name << " associated to the group manager: " << id);
   }
 
   return *(it->second);
 }
 
 /* -------------------------------------------------------------------------- */
 ElementGroup & GroupManager::getElementGroup(const std::string & name) {
   auto it = element_group_find(name);
   if (it == element_group_end()) {
     AKANTU_EXCEPTION("There are no element groups named "
                      << name << " associated to the group manager: " << id);
   }
 
   return *(it->second);
 }
 
 /* -------------------------------------------------------------------------- */
 const NodeGroup & GroupManager::getNodeGroup(const std::string & name) const {
   auto it = node_group_find(name);
   if (it == node_group_end()) {
     AKANTU_EXCEPTION("There are no node groups named "
                      << name << " associated to the group manager: " << id);
   }
 
   return *(it->second);
 }
 
 /* -------------------------------------------------------------------------- */
 NodeGroup & GroupManager::getNodeGroup(const std::string & name) {
   auto it = node_group_find(name);
   if (it == node_group_end()) {
     AKANTU_EXCEPTION("There are no node groups named "
                      << name << " associated to the group manager: " << id);
   }
 
   return *(it->second);
 }
 
 } // namespace akantu
diff --git a/src/mesh/group_manager.hh b/src/mesh/group_manager.hh
index 56998407b..242dd2ef4 100644
--- a/src/mesh/group_manager.hh
+++ b/src/mesh/group_manager.hh
@@ -1,316 +1,316 @@
 /**
  * @file   group_manager.hh
  *
  * @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
  * @author Dana Christen <dana.christen@gmail.com>
  * @author David Simon Kammer <david.kammer@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  * @author Marco Vocialta <marco.vocialta@epfl.ch>
  *
  * @date creation: Wed Nov 13 2013
- * @date last modification: Mon Nov 16 2015
+ * @date last modification: Wed Feb 07 2018
  *
  * @brief  Stores information relevent to the notion of element and nodes
- *groups.
+ * groups.
  *
  * @section LICENSE
  *
- * Copyright  (©)  2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de Lausanne)
+ * 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
+ * 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
+ * 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_GROUP_MANAGER_HH__
 #define __AKANTU_GROUP_MANAGER_HH__
 
 /* -------------------------------------------------------------------------- */
 #include "aka_common.hh"
 #include "element_type_map.hh"
 /* -------------------------------------------------------------------------- */
 #include <set>
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 class ElementGroup;
 class NodeGroup;
 class Mesh;
 class Element;
 class ElementSynchronizer;
 template <bool> class CommunicationBufferTemplated;
 namespace dumper {
   class Field;
 }
 } // namespace akantu
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 class GroupManager {
   /* ------------------------------------------------------------------------ */
   /* Typedefs                                                                 */
   /* ------------------------------------------------------------------------ */
 private:
 #ifdef SWIGPYTHON
 public:
   using ElementGroups = std::map<std::string, ElementGroup *>;
   using NodeGroups = std::map<std::string, NodeGroup *>;
 
 private:
 #else
   using ElementGroups = std::map<std::string, ElementGroup *>;
   using NodeGroups = std::map<std::string, NodeGroup *>;
 #endif
 
 public:
   using GroupManagerTypeSet = std::set<ElementType>;
 
   /* ------------------------------------------------------------------------ */
   /* Constructors/Destructors                                                 */
   /* ------------------------------------------------------------------------ */
 public:
   GroupManager(const Mesh & mesh, const ID & id = "group_manager",
                const MemoryID & memory_id = 0);
   virtual ~GroupManager();
 
   /* ------------------------------------------------------------------------ */
   /* Groups iterators                                                         */
   /* ------------------------------------------------------------------------ */
 public:
   using node_group_iterator = NodeGroups::iterator;
   using element_group_iterator = ElementGroups::iterator;
 
   using const_node_group_iterator = NodeGroups::const_iterator;
   using const_element_group_iterator = ElementGroups::const_iterator;
 
 #ifndef SWIG
 #define AKANTU_GROUP_MANAGER_DEFINE_ITERATOR_FUNCTION(group_type, function,    \
                                                       param_in, param_out)     \
   inline BOOST_PP_CAT(BOOST_PP_CAT(const_, group_type), _iterator)             \
       BOOST_PP_CAT(BOOST_PP_CAT(group_type, _), function)(param_in) const {    \
     return BOOST_PP_CAT(group_type, s).function(param_out);                    \
   };                                                                           \
                                                                                \
   inline BOOST_PP_CAT(group_type, _iterator)                                   \
       BOOST_PP_CAT(BOOST_PP_CAT(group_type, _), function)(param_in) {          \
     return BOOST_PP_CAT(group_type, s).function(param_out);                    \
   }
 
 #define AKANTU_GROUP_MANAGER_DEFINE_ITERATOR_FUNCTION_NP(group_type, function) \
   AKANTU_GROUP_MANAGER_DEFINE_ITERATOR_FUNCTION(                               \
       group_type, function, BOOST_PP_EMPTY(), BOOST_PP_EMPTY())
 
   AKANTU_GROUP_MANAGER_DEFINE_ITERATOR_FUNCTION_NP(node_group, begin);
   AKANTU_GROUP_MANAGER_DEFINE_ITERATOR_FUNCTION_NP(node_group, end);
   AKANTU_GROUP_MANAGER_DEFINE_ITERATOR_FUNCTION_NP(element_group, begin);
   AKANTU_GROUP_MANAGER_DEFINE_ITERATOR_FUNCTION_NP(element_group, end);
   AKANTU_GROUP_MANAGER_DEFINE_ITERATOR_FUNCTION(element_group, find,
                                                 const std::string & name, name);
   AKANTU_GROUP_MANAGER_DEFINE_ITERATOR_FUNCTION(node_group, find,
                                                 const std::string & name, name);
 #endif
 
   /* ------------------------------------------------------------------------ */
   /* Clustering filter                                                        */
   /* ------------------------------------------------------------------------ */
 public:
   class ClusteringFilter {
   public:
     virtual bool operator()(const Element &) const { return true; }
   };
 
   /* ------------------------------------------------------------------------ */
   /* Methods                                                                  */
   /* ------------------------------------------------------------------------ */
 public:
   /// create an empty node group
   NodeGroup & createNodeGroup(const std::string & group_name,
                               bool replace_group = false);
 
   /// create a node group from another node group but filtered
   template <typename T>
   NodeGroup & createFilteredNodeGroup(const std::string & group_name,
                                       const NodeGroup & node_group, T & filter);
 
   /// destroy a node group
   void destroyNodeGroup(const std::string & group_name);
 
   /// create an element group and the associated node group
   ElementGroup & createElementGroup(const std::string & group_name,
                                     UInt dimension = _all_dimensions,
                                     bool replace_group = false);
 
   /// create an element group from another element group but filtered
   template <typename T>
   ElementGroup &
   createFilteredElementGroup(const std::string & group_name, UInt dimension,
                              const NodeGroup & node_group, T & filter);
 
   /// destroy an element group and the associated node group
   void destroyElementGroup(const std::string & group_name,
                            bool destroy_node_group = false);
 
   /// destroy all element groups and the associated node groups
   void destroyAllElementGroups(bool destroy_node_groups = false);
 
   /// create a element group using an existing node group
   ElementGroup & createElementGroup(const std::string & group_name,
                                     UInt dimension, NodeGroup & node_group);
 
   /// create groups based on values stored in a given mesh data
   template <typename T>
   void createGroupsFromMeshData(const std::string & dataset_name);
 
   /// create boundaries group by a clustering algorithm \todo extend to parallel
   UInt createBoundaryGroupFromGeometry();
 
   /// create element clusters for a given dimension
   UInt createClusters(UInt element_dimension, Mesh & mesh_facets,
                       std::string cluster_name_prefix = "cluster",
                       const ClusteringFilter & filter = ClusteringFilter());
 
   /// create element clusters for a given dimension
   UInt createClusters(UInt element_dimension,
                       std::string cluster_name_prefix = "cluster",
                       const ClusteringFilter & filter = ClusteringFilter());
 
 private:
   /// create element clusters for a given dimension
   UInt createClusters(UInt element_dimension,
                       const std::string & cluster_name_prefix,
                       const ClusteringFilter & filter, Mesh & mesh_facets);
 
 public:
   /// Create an ElementGroup based on a NodeGroup
   void createElementGroupFromNodeGroup(const std::string & name,
                                        const std::string & node_group,
                                        UInt dimension = _all_dimensions);
 
   virtual void printself(std::ostream & stream, int indent = 0) const;
 
   /// this function insure that the group names are present on all processors
   /// /!\ it is a SMP call
   void synchronizeGroupNames();
 
 /// register an elemental field to the given group name (overloading for
 /// ElementalPartionField)
 #ifndef SWIG
   template <typename T, template <bool> class dump_type>
   dumper::Field * createElementalField(
       const ElementTypeMapArray<T> & field, const std::string & group_name,
       UInt spatial_dimension, const ElementKind & kind,
       ElementTypeMap<UInt> nb_data_per_elem = ElementTypeMap<UInt>());
 
   /// register an elemental field to the given group name (overloading for
   /// ElementalField)
   template <typename T, template <class> class ret_type,
             template <class, template <class> class, bool> class dump_type>
   dumper::Field * createElementalField(
       const ElementTypeMapArray<T> & field, const std::string & group_name,
       UInt spatial_dimension, const ElementKind & kind,
       ElementTypeMap<UInt> nb_data_per_elem = ElementTypeMap<UInt>());
 
   /// register an elemental field to the given group name (overloading for
   /// MaterialInternalField)
   template <typename T,
             /// type of InternalMaterialField
             template <typename, bool filtered> class dump_type>
   dumper::Field * createElementalField(const ElementTypeMapArray<T> & field,
                                        const std::string & group_name,
                                        UInt spatial_dimension,
                                        const ElementKind & kind,
                                        ElementTypeMap<UInt> nb_data_per_elem);
 
   template <typename type, bool flag, template <class, bool> class ftype>
   dumper::Field * createNodalField(const ftype<type, flag> * field,
                                    const std::string & group_name,
                                    UInt padding_size = 0);
 
   template <typename type, bool flag, template <class, bool> class ftype>
   dumper::Field * createStridedNodalField(const ftype<type, flag> * field,
                                           const std::string & group_name,
                                           UInt size, UInt stride,
                                           UInt padding_size);
 
 protected:
   /// fill a buffer with all the group names
   void fillBufferWithGroupNames(
       CommunicationBufferTemplated<false> & comm_buffer) const;
 
   /// take a buffer and create the missing groups localy
   void checkAndAddGroups(CommunicationBufferTemplated<true> & buffer);
 
   /// register an elemental field to the given group name
   template <class dump_type, typename field_type>
   inline dumper::Field *
   createElementalField(const field_type & field, const std::string & group_name,
                        UInt spatial_dimension, const ElementKind & kind,
                        const ElementTypeMap<UInt> & nb_data_per_elem);
 
   /// register an elemental field to the given group name
   template <class dump_type, typename field_type>
   inline dumper::Field *
   createElementalFilteredField(const field_type & field,
                                const std::string & group_name,
                                UInt spatial_dimension, const ElementKind & kind,
                                ElementTypeMap<UInt> nb_data_per_elem);
 #endif
 
   /* ------------------------------------------------------------------------ */
   /* Accessor                                                                 */
   /* ------------------------------------------------------------------------ */
 public:
   AKANTU_GET_MACRO(ElementGroups, element_groups, const ElementGroups &);
 
   const ElementGroup & getElementGroup(const std::string & name) const;
   const NodeGroup & getNodeGroup(const std::string & name) const;
 
   ElementGroup & getElementGroup(const std::string & name);
   NodeGroup & getNodeGroup(const std::string & name);
 
   UInt getNbElementGroups(UInt dimension = _all_dimensions) const;
   UInt getNbNodeGroups() { return node_groups.size(); };
 
   /* ------------------------------------------------------------------------ */
   /* Class Members                                                            */
   /* ------------------------------------------------------------------------ */
 protected:
   /// id to create element and node groups
   ID id;
   /// memory_id to create element and node groups
   MemoryID memory_id;
 
   /// list of the node groups managed
   NodeGroups node_groups;
 
   /// list of the element groups managed
   ElementGroups element_groups;
 
   /// Mesh to which the element belongs
   const Mesh & mesh;
 };
 
 /// standard output stream operator
 inline std::ostream & operator<<(std::ostream & stream,
                                  const GroupManager & _this) {
   _this.printself(stream);
   return stream;
 }
 
 } // namespace akantu
 
 #endif /* __AKANTU_GROUP_MANAGER_HH__ */
diff --git a/src/mesh/group_manager_inline_impl.cc b/src/mesh/group_manager_inline_impl.cc
index 9629a5279..bfb9d0f6a 100644
--- a/src/mesh/group_manager_inline_impl.cc
+++ b/src/mesh/group_manager_inline_impl.cc
@@ -1,205 +1,205 @@
 /**
  * @file   group_manager_inline_impl.cc
  *
  * @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
  * @author Dana Christen <dana.christen@gmail.com>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Wed Nov 13 2013
- * @date last modification: Tue Dec 08 2015
+ * @date last modification: Sun Dec 03 2017
  *
  * @brief  Stores information relevent to the notion of domain boundary and
  * surfaces.
  *
  * @section LICENSE
  *
- * Copyright  (©)  2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de Lausanne)
+ * 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
+ * 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
+ * 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 "dumper_field.hh"
 #include "element_group.hh"
 #include "element_type_map_filter.hh"
 #ifdef AKANTU_USE_IOHELPER
 #include "dumper_nodal_field.hh"
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 
 template <typename T, template <bool> class dump_type>
 dumper::Field * GroupManager::createElementalField(
     const ElementTypeMapArray<T> & field, const std::string & group_name,
     UInt spatial_dimension, const ElementKind & kind,
     ElementTypeMap<UInt> nb_data_per_elem) {
 
   const ElementTypeMapArray<T> * field_ptr = &field;
   if (field_ptr == nullptr)
     return nullptr;
   if (group_name == "all")
     return this->createElementalField<dump_type<false>>(
         field, group_name, spatial_dimension, kind, nb_data_per_elem);
   else
     return this->createElementalFilteredField<dump_type<true>>(
         field, group_name, spatial_dimension, kind, nb_data_per_elem);
 }
 
 /* -------------------------------------------------------------------------- */
 template <typename T, template <class> class T2,
           template <class, template <class> class, bool> class dump_type>
 dumper::Field * GroupManager::createElementalField(
     const ElementTypeMapArray<T> & field, const std::string & group_name,
     UInt spatial_dimension, const ElementKind & kind,
     ElementTypeMap<UInt> nb_data_per_elem) {
 
   const ElementTypeMapArray<T> * field_ptr = &field;
   if (field_ptr == nullptr)
     return nullptr;
   if (group_name == "all")
     return this->createElementalField<dump_type<T, T2, false>>(
         field, group_name, spatial_dimension, kind, nb_data_per_elem);
   else
     return this->createElementalFilteredField<dump_type<T, T2, true>>(
         field, group_name, spatial_dimension, kind, nb_data_per_elem);
 }
 
 /* -------------------------------------------------------------------------- */
 template <typename T, template <typename T2, bool filtered>
                       class dump_type> ///< type of InternalMaterialField
 dumper::Field *
 GroupManager::createElementalField(const ElementTypeMapArray<T> & field,
                                    const std::string & group_name,
                                    UInt spatial_dimension,
                                    const ElementKind & kind,
                                    ElementTypeMap<UInt> nb_data_per_elem) {
   const ElementTypeMapArray<T> * field_ptr = &field;
 
   if (field_ptr == nullptr)
     return nullptr;
   if (group_name == "all")
     return this->createElementalField<dump_type<T, false>>(
         field, group_name, spatial_dimension, kind, nb_data_per_elem);
   else
     return this->createElementalFilteredField<dump_type<T, true>>(
         field, group_name, spatial_dimension, kind, nb_data_per_elem);
 }
 
 /* -------------------------------------------------------------------------- */
 
 template <typename dump_type, typename field_type>
 dumper::Field * GroupManager::createElementalField(
     const field_type & field, const std::string & group_name,
     UInt spatial_dimension, const ElementKind & kind,
     const ElementTypeMap<UInt> & nb_data_per_elem) {
   const field_type * field_ptr = &field;
   if (field_ptr == nullptr)
     return nullptr;
   if (group_name != "all")
     throw;
 
   dumper::Field * dumper =
       new dump_type(field, spatial_dimension, _not_ghost, kind);
   dumper->setNbDataPerElem(nb_data_per_elem);
   return dumper;
 }
 
 /* -------------------------------------------------------------------------- */
 
 template <typename dump_type, typename field_type>
 dumper::Field * GroupManager::createElementalFilteredField(
     const field_type & field, const std::string & group_name,
     UInt spatial_dimension, const ElementKind & kind,
     ElementTypeMap<UInt> nb_data_per_elem) {
 
   const field_type * field_ptr = &field;
   if (field_ptr == nullptr)
     return nullptr;
   if (group_name == "all")
     throw;
 
   using T = typename field_type::type;
   ElementGroup & group = this->getElementGroup(group_name);
   UInt dim = group.getDimension();
   if (dim != spatial_dimension)
     throw;
   const ElementTypeMapArray<UInt> & elemental_filter = group.getElements();
 
   auto * filtered = new ElementTypeMapArrayFilter<T>(field, elemental_filter,
                                                      nb_data_per_elem);
 
   dumper::Field * dumper = new dump_type(*filtered, dim, _not_ghost, kind);
   dumper->setNbDataPerElem(nb_data_per_elem);
 
   return dumper;
 }
 
 /* -------------------------------------------------------------------------- */
 template <typename type, bool flag, template <class, bool> class ftype>
 dumper::Field * GroupManager::createNodalField(const ftype<type, flag> * field,
                                                const std::string & group_name,
                                                UInt padding_size) {
 
   if (field == nullptr)
     return nullptr;
   if (group_name == "all") {
     using DumpType = typename dumper::NodalField<type, false>;
     auto * dumper = new DumpType(*field, 0, 0, nullptr);
     dumper->setPadding(padding_size);
     return dumper;
   } else {
     ElementGroup & group = this->getElementGroup(group_name);
     const Array<UInt> * nodal_filter = &(group.getNodes());
     using DumpType = typename dumper::NodalField<type, true>;
     auto * dumper = new DumpType(*field, 0, 0, nodal_filter);
     dumper->setPadding(padding_size);
     return dumper;
   }
   return nullptr;
 }
 
 /* -------------------------------------------------------------------------- */
 template <typename type, bool flag, template <class, bool> class ftype>
 dumper::Field *
 GroupManager::createStridedNodalField(const ftype<type, flag> * field,
                                       const std::string & group_name, UInt size,
                                       UInt stride, UInt padding_size) {
 
   if (field == NULL)
     return nullptr;
   if (group_name == "all") {
     using DumpType = typename dumper::NodalField<type, false>;
     auto * dumper = new DumpType(*field, size, stride, NULL);
     dumper->setPadding(padding_size);
     return dumper;
   } else {
     ElementGroup & group = this->getElementGroup(group_name);
     const Array<UInt> * nodal_filter = &(group.getNodes());
     using DumpType = typename dumper::NodalField<type, true>;
     auto * dumper = new DumpType(*field, size, stride, nodal_filter);
     dumper->setPadding(padding_size);
     return dumper;
   }
   return nullptr;
 }
 
 /* -------------------------------------------------------------------------- */
 
 } // namespace akantu
 
 #endif
diff --git a/src/mesh/mesh.cc b/src/mesh/mesh.cc
index bb13d8b62..cc63c5fd2 100644
--- a/src/mesh/mesh.cc
+++ b/src/mesh/mesh.cc
@@ -1,570 +1,569 @@
 /**
  * @file   mesh.cc
  *
  * @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
  * @author David Simon Kammer <david.kammer@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  * @author Marco Vocialta <marco.vocialta@epfl.ch>
  *
  * @date creation: Fri Jun 18 2010
- * @date last modification: Fri Jan 22 2016
+ * @date last modification: Tue Feb 20 2018
  *
  * @brief  class handling meshes
  *
  * @section LICENSE
  *
- * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
- * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
- * Solides)
+ * 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
+ * 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
+ * A PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 #include "aka_config.hh"
 /* -------------------------------------------------------------------------- */
 #include "element_class.hh"
 #include "group_manager_inline_impl.cc"
 #include "mesh.hh"
 #include "mesh_io.hh"
 #include "mesh_iterators.hh"
 #include "mesh_utils.hh"
 /* -------------------------------------------------------------------------- */
 #include "communicator.hh"
 #include "element_synchronizer.hh"
 #include "facet_synchronizer.hh"
 #include "mesh_utils_distribution.hh"
 #include "node_synchronizer.hh"
 /* -------------------------------------------------------------------------- */
 #ifdef AKANTU_USE_IOHELPER
 #include "dumper_field.hh"
 #include "dumper_internal_material_field.hh"
 #endif
 /* -------------------------------------------------------------------------- */
 #include <limits>
 #include <sstream>
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 Mesh::Mesh(UInt spatial_dimension, const ID & id, const MemoryID & memory_id,
            Communicator & communicator)
     : Memory(id, memory_id),
       GroupManager(*this, id + ":group_manager", memory_id),
       nodes_type(0, 1, id + ":nodes_type"),
       connectivities("connectivities", id, memory_id),
       ghosts_counters("ghosts_counters", id, memory_id),
       normals("normals", id, memory_id), spatial_dimension(spatial_dimension),
       lower_bounds(spatial_dimension, 0.), upper_bounds(spatial_dimension, 0.),
       size(spatial_dimension, 0.), local_lower_bounds(spatial_dimension, 0.),
       local_upper_bounds(spatial_dimension, 0.),
       mesh_data("mesh_data", id, memory_id), communicator(&communicator) {
   AKANTU_DEBUG_IN();
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 Mesh::Mesh(UInt spatial_dimension, Communicator & communicator, const ID & id,
            const MemoryID & memory_id)
     : Mesh(spatial_dimension, id, memory_id, communicator) {
   AKANTU_DEBUG_IN();
 
   this->nodes =
       std::make_shared<Array<Real>>(0, spatial_dimension, id + ":coordinates");
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 Mesh::Mesh(UInt spatial_dimension, const ID & id, const MemoryID & memory_id)
     : Mesh(spatial_dimension, Communicator::getStaticCommunicator(), id,
            memory_id) {}
 
 /* -------------------------------------------------------------------------- */
 Mesh::Mesh(UInt spatial_dimension, const std::shared_ptr<Array<Real>> & nodes,
            const ID & id, const MemoryID & memory_id)
     : Mesh(spatial_dimension, id, memory_id,
            Communicator::getStaticCommunicator()) {
   this->nodes = nodes;
 
   this->nb_global_nodes = this->nodes->size();
 
   this->nodes_to_elements.resize(nodes->size());
   for (auto & node_set : nodes_to_elements) {
     node_set = std::make_unique<std::set<Element>>();
   }
 
   this->computeBoundingBox();
 }
 
 /* -------------------------------------------------------------------------- */
 void Mesh::getBarycenters(Array<Real> & barycenter, const ElementType & type,
                           const GhostType & ghost_type) const {
   barycenter.resize(getNbElement(type, ghost_type));
   for (auto && data : enumerate(make_view(barycenter, spatial_dimension))) {
     getBarycenter(Element{type, UInt(std::get<0>(data)), ghost_type},
                   std::get<1>(data));
   }
 }
 
 /* -------------------------------------------------------------------------- */
 Mesh & Mesh::initMeshFacets(const ID & id) {
   AKANTU_DEBUG_IN();
 
   if (!mesh_facets) {
     mesh_facets = std::make_unique<Mesh>(spatial_dimension, this->nodes,
                                          getID() + ":" + id, getMemoryID());
 
     mesh_facets->mesh_parent = this;
     mesh_facets->is_mesh_facets = true;
 
     MeshUtils::buildAllFacets(*this, *mesh_facets, 0);
 
     if (mesh.isDistributed()) {
       mesh_facets->is_distributed = true;
       mesh_facets->element_synchronizer = std::make_unique<FacetSynchronizer>(
           *mesh_facets, mesh.getElementSynchronizer());
     }
 
     /// transfers the the mesh physical names to the mesh facets
     if (not this->hasData("physical_names")) {
       AKANTU_DEBUG_OUT();
       return *mesh_facets;
     }
 
     if (not mesh_facets->hasData("physical_names")) {
       mesh_facets->registerData<std::string>("physical_names");
     }
 
     auto & mesh_phys_data = this->getData<std::string>("physical_names");
     auto & phys_data = mesh_facets->getData<std::string>("physical_names");
     phys_data.initialize(*mesh_facets,
                          _spatial_dimension = spatial_dimension - 1,
                          _with_nb_element = true);
 
     ElementTypeMapArray<Real> barycenters(getID(), "temporary_barycenters");
     barycenters.initialize(*mesh_facets, _nb_component = spatial_dimension,
                            _spatial_dimension = spatial_dimension - 1,
                            _with_nb_element = true);
 
     for (auto && ghost_type : ghost_types) {
       for (auto && type :
            barycenters.elementTypes(spatial_dimension - 1, ghost_type)) {
         mesh_facets->getBarycenters(barycenters(type, ghost_type), type,
                                     ghost_type);
       }
     }
 
     for_each_element(
         mesh,
         [&](auto && element) {
           Vector<Real> barycenter(spatial_dimension);
           mesh.getBarycenter(element, barycenter);
           auto norm_barycenter = barycenter.norm();
           auto tolerance = Math::getTolerance();
           if (norm_barycenter > tolerance)
             tolerance *= norm_barycenter;
 
           const auto & element_to_facet = mesh_facets->getElementToSubelement(
               element.type, element.ghost_type);
 
           Vector<Real> barycenter_facet(spatial_dimension);
 
           auto range =
               enumerate(make_view(barycenters(element.type, element.ghost_type),
                                   spatial_dimension));
 #ifndef AKANTU_NDEBUG
           auto min_dist = std::numeric_limits<Real>::max();
 #endif
           // this is a spacial search coded the most inefficient way.
           auto facet =
               std::find_if(range.begin(), range.end(), [&](auto && data) {
                 auto facet = std::get<0>(data);
                 if (element_to_facet(facet)[1] == ElementNull)
                   return false;
 
                 auto norm_distance = barycenter.distance(std::get<1>(data));
 #ifndef AKANTU_NDEBUG
                 min_dist = std::min(min_dist, norm_distance);
 #endif
                 return (norm_distance < tolerance);
               });
 
           if (facet == range.end()) {
             AKANTU_DEBUG_INFO("The element "
                               << element
                               << " did not find its associated facet in the "
                                  "mesh_facets! Try to decrease math tolerance. "
                                  "The closest element was at a distance of "
                               << min_dist);
             return;
           }
 
           // set physical name
           phys_data(Element{element.type, UInt(std::get<0>(*facet)),
                             element.ghost_type}) = mesh_phys_data(element);
         },
         _spatial_dimension = spatial_dimension - 1);
 
     mesh_facets->createGroupsFromMeshData<std::string>("physical_names");
   }
 
   AKANTU_DEBUG_OUT();
   return *mesh_facets;
 }
 
 /* -------------------------------------------------------------------------- */
 void Mesh::defineMeshParent(const Mesh & mesh) {
   AKANTU_DEBUG_IN();
 
   this->mesh_parent = &mesh;
   this->is_mesh_facets = true;
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 Mesh::~Mesh() = default;
 
 /* -------------------------------------------------------------------------- */
 void Mesh::read(const std::string & filename, const MeshIOType & mesh_io_type) {
   MeshIO mesh_io;
   mesh_io.read(filename, *this, mesh_io_type);
 
   type_iterator it =
       this->firstType(spatial_dimension, _not_ghost, _ek_not_defined);
   type_iterator last =
       this->lastType(spatial_dimension, _not_ghost, _ek_not_defined);
   if (it == last)
     AKANTU_EXCEPTION(
         "The mesh contained in the file "
         << filename << " does not seem to be of the good dimension."
         << " No element of dimension " << spatial_dimension << " where read.");
 
   this->nb_global_nodes = this->nodes->size();
 
   this->computeBoundingBox();
 
   this->nodes_to_elements.resize(nodes->size());
   for (auto & node_set : nodes_to_elements) {
     node_set = std::make_unique<std::set<Element>>();
   }
 }
 
 /* -------------------------------------------------------------------------- */
 void Mesh::write(const std::string & filename,
                  const MeshIOType & mesh_io_type) {
   MeshIO mesh_io;
   mesh_io.write(filename, *this, mesh_io_type);
 }
 
 /* -------------------------------------------------------------------------- */
 void Mesh::printself(std::ostream & stream, int indent) const {
   std::string space;
   for (Int i = 0; i < indent; i++, space += AKANTU_INDENT)
     ;
 
   stream << space << "Mesh [" << std::endl;
   stream << space << " + id                : " << getID() << std::endl;
   stream << space << " + spatial dimension : " << this->spatial_dimension
          << std::endl;
   stream << space << " + nodes [" << std::endl;
   nodes->printself(stream, indent + 2);
   stream << space << " + connectivities [" << std::endl;
   connectivities.printself(stream, indent + 2);
   stream << space << " ]" << std::endl;
 
   GroupManager::printself(stream, indent + 1);
   stream << space << "]" << std::endl;
 }
 
 /* -------------------------------------------------------------------------- */
 void Mesh::computeBoundingBox() {
   AKANTU_DEBUG_IN();
   for (UInt k = 0; k < spatial_dimension; ++k) {
     local_lower_bounds(k) = std::numeric_limits<double>::max();
     local_upper_bounds(k) = -std::numeric_limits<double>::max();
   }
 
   for (UInt i = 0; i < nodes->size(); ++i) {
     //    if(!isPureGhostNode(i))
     for (UInt k = 0; k < spatial_dimension; ++k) {
       local_lower_bounds(k) = std::min(local_lower_bounds[k], (*nodes)(i, k));
       local_upper_bounds(k) = std::max(local_upper_bounds[k], (*nodes)(i, k));
     }
   }
 
   if (this->is_distributed) {
     Matrix<Real> reduce_bounds(spatial_dimension, 2);
     for (UInt k = 0; k < spatial_dimension; ++k) {
       reduce_bounds(k, 0) = local_lower_bounds(k);
       reduce_bounds(k, 1) = -local_upper_bounds(k);
     }
 
     communicator->allReduce(reduce_bounds, SynchronizerOperation::_min);
 
     for (UInt k = 0; k < spatial_dimension; ++k) {
       lower_bounds(k) = reduce_bounds(k, 0);
       upper_bounds(k) = -reduce_bounds(k, 1);
     }
   } else {
     this->lower_bounds = this->local_lower_bounds;
     this->upper_bounds = this->local_upper_bounds;
   }
 
   size = upper_bounds - lower_bounds;
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void Mesh::initNormals() {
   normals.initialize(*this, _nb_component = spatial_dimension,
                      _spatial_dimension = spatial_dimension,
                      _element_kind = _ek_not_defined);
 }
 
 /* -------------------------------------------------------------------------- */
 void Mesh::getGlobalConnectivity(
     ElementTypeMapArray<UInt> & global_connectivity) {
   AKANTU_DEBUG_IN();
 
   for (auto && ghost_type : ghost_types) {
     for (auto type :
          global_connectivity.elementTypes(_spatial_dimension = _all_dimensions,
          _element_kind = _ek_not_defined, _ghost_type = ghost_type)) {
       if (not connectivities.exists(type, ghost_type))
         continue;
 
       auto & local_conn = connectivities(type, ghost_type);
       auto & g_connectivity = global_connectivity(type, ghost_type);
 
       UInt nb_nodes = local_conn.size() * local_conn.getNbComponent();
 
       if (not nodes_global_ids && is_mesh_facets) {
         std::transform(
             local_conn.begin_reinterpret(nb_nodes),
             local_conn.end_reinterpret(nb_nodes),
             g_connectivity.begin_reinterpret(nb_nodes),
             [& node_ids = *mesh_parent->nodes_global_ids](UInt l)->UInt {
               return node_ids(l);
             });
       } else {
         std::transform(local_conn.begin_reinterpret(nb_nodes),
                        local_conn.end_reinterpret(nb_nodes),
                        g_connectivity.begin_reinterpret(nb_nodes),
                        [& node_ids = *nodes_global_ids](UInt l)->UInt {
                          return node_ids(l);
                        });
       }
     }
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 DumperIOHelper & Mesh::getGroupDumper(const std::string & dumper_name,
                                       const std::string & group_name) {
   if (group_name == "all")
     return this->getDumper(dumper_name);
   else
     return element_groups[group_name]->getDumper(dumper_name);
 }
 
 /* -------------------------------------------------------------------------- */
 template <typename T>
 ElementTypeMap<UInt> Mesh::getNbDataPerElem(ElementTypeMapArray<T> & arrays,
                                             const ElementKind & element_kind) {
   ElementTypeMap<UInt> nb_data_per_elem;
 
   for (auto type : elementTypes(spatial_dimension, _not_ghost, element_kind)) {
     UInt nb_elements = this->getNbElement(type);
     auto & array = arrays(type);
 
     nb_data_per_elem(type) = array.getNbComponent() * array.size();
     nb_data_per_elem(type) /= nb_elements;
   }
 
   return nb_data_per_elem;
 }
 
 /* -------------------------------------------------------------------------- */
 template ElementTypeMap<UInt>
 Mesh::getNbDataPerElem(ElementTypeMapArray<Real> & array,
                        const ElementKind & element_kind);
 
 template ElementTypeMap<UInt>
 Mesh::getNbDataPerElem(ElementTypeMapArray<UInt> & array,
                        const ElementKind & element_kind);
 
 /* -------------------------------------------------------------------------- */
 #ifdef AKANTU_USE_IOHELPER
 template <typename T>
 dumper::Field *
 Mesh::createFieldFromAttachedData(const std::string & field_id,
                                   const std::string & group_name,
                                   const ElementKind & element_kind) {
 
   dumper::Field * field = nullptr;
   ElementTypeMapArray<T> * internal = nullptr;
   try {
     internal = &(this->getData<T>(field_id));
   } catch (...) {
     return nullptr;
   }
 
   ElementTypeMap<UInt> nb_data_per_elem =
       this->getNbDataPerElem(*internal, element_kind);
 
   field = this->createElementalField<T, dumper::InternalMaterialField>(
       *internal, group_name, this->spatial_dimension, element_kind,
       nb_data_per_elem);
 
   return field;
 }
 
 template dumper::Field *
 Mesh::createFieldFromAttachedData<Real>(const std::string & field_id,
                                         const std::string & group_name,
                                         const ElementKind & element_kind);
 
 template dumper::Field *
 Mesh::createFieldFromAttachedData<UInt>(const std::string & field_id,
                                         const std::string & group_name,
                                         const ElementKind & element_kind);
 #endif
 
 /* -------------------------------------------------------------------------- */
 void Mesh::distribute() {
   this->distribute(Communicator::getStaticCommunicator());
 }
 
 /* -------------------------------------------------------------------------- */
 void Mesh::distribute(Communicator & communicator) {
   AKANTU_DEBUG_ASSERT(is_distributed == false,
                       "This mesh is already distribute");
   this->communicator = &communicator;
 
   this->element_synchronizer = std::make_unique<ElementSynchronizer>(
       *this, this->getID() + ":element_synchronizer", this->getMemoryID(),
       true);
 
   this->node_synchronizer = std::make_unique<NodeSynchronizer>(
       *this, this->getID() + ":node_synchronizer", this->getMemoryID(), true);
 
   Int psize = this->communicator->getNbProc();
 #ifdef AKANTU_USE_SCOTCH
   Int prank = this->communicator->whoAmI();
   if (prank == 0) {
     MeshPartitionScotch partition(*this, spatial_dimension);
     partition.partitionate(psize);
 
     MeshUtilsDistribution::distributeMeshCentralized(*this, 0, partition);
   } else {
     MeshUtilsDistribution::distributeMeshCentralized(*this, 0);
   }
 #else
   if (!(psize == 1)) {
     AKANTU_ERROR("Cannot distribute a mesh without a partitioning tool");
   }
 #endif
 
   this->is_distributed = true;
   this->computeBoundingBox();
 }
 
 /* -------------------------------------------------------------------------- */
 void Mesh::getAssociatedElements(const Array<UInt> & node_list,
                                  Array<Element> & elements) {
   for (const auto & node : node_list)
     for (const auto & element : *nodes_to_elements[node])
       elements.push_back(element);
 }
 
 /* -------------------------------------------------------------------------- */
 void Mesh::fillNodesToElements() {
   Element e;
 
   UInt nb_nodes = nodes->size();
   for (UInt n = 0; n < nb_nodes; ++n) {
     if (this->nodes_to_elements[n])
       this->nodes_to_elements[n]->clear();
     else
       this->nodes_to_elements[n] = std::make_unique<std::set<Element>>();
   }
 
   for (auto ghost_type : ghost_types) {
     e.ghost_type = ghost_type;
     for (const auto & type :
          elementTypes(spatial_dimension, ghost_type, _ek_not_defined)) {
       e.type = type;
 
       UInt nb_element = this->getNbElement(type, ghost_type);
       Array<UInt>::const_iterator<Vector<UInt>> conn_it =
           connectivities(type, ghost_type)
               .begin(Mesh::getNbNodesPerElement(type));
 
       for (UInt el = 0; el < nb_element; ++el, ++conn_it) {
         e.element = el;
         const Vector<UInt> & conn = *conn_it;
         for (UInt n = 0; n < conn.size(); ++n)
           nodes_to_elements[conn(n)]->insert(e);
       }
     }
   }
 }
 
 /* -------------------------------------------------------------------------- */
 void Mesh::eraseElements(const Array<Element> & elements) {
   ElementTypeMap<UInt> last_element;
 
   RemovedElementsEvent event(*this);
   auto & remove_list = event.getList();
   auto & new_numbering = event.getNewNumbering();
 
   for (auto && el : elements) {
     if (el.ghost_type != _not_ghost) {
       auto & count = ghosts_counters(el);
       --count;
       if (count > 0)
         continue;
     }
 
     remove_list.push_back(el);
     if (not last_element.exists(el.type, el.ghost_type)) {
       UInt nb_element = mesh.getNbElement(el.type, el.ghost_type);
       last_element(nb_element - 1, el.type, el.ghost_type);
       auto & numbering =
           new_numbering.alloc(nb_element, 1, el.type, el.ghost_type);
       for (auto && pair : enumerate(numbering)) {
         std::get<1>(pair) = std::get<0>(pair);
       }
     }
 
     UInt & pos = last_element(el.type, el.ghost_type);
     auto & numbering = new_numbering(el.type, el.ghost_type);
 
     numbering(el.element) = UInt(-1);
     numbering(pos) = el.element;
     --pos;
   }
 
   this->sendEvent(event);
 }
 
 } // namespace akantu
diff --git a/src/mesh/mesh.hh b/src/mesh/mesh.hh
index ffdd11510..c1d47f15e 100644
--- a/src/mesh/mesh.hh
+++ b/src/mesh/mesh.hh
@@ -1,613 +1,612 @@
 /**
  * @file   mesh.hh
  *
  * @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
  * @author Dana Christen <dana.christen@epfl.ch>
  * @author David Simon Kammer <david.kammer@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  * @author Marco Vocialta <marco.vocialta@epfl.ch>
  *
  * @date creation: Fri Jun 18 2010
- * @date last modification: Thu Jan 14 2016
+ * @date last modification: Mon Feb 19 2018
  *
  * @brief  the class representing the meshes
  *
  * @section LICENSE
  *
- * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
- * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
- * Solides)
+ * 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
+ * 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
+ * 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_MESH_HH__
 #define __AKANTU_MESH_HH__
 
 /* -------------------------------------------------------------------------- */
 #include "aka_array.hh"
 #include "aka_event_handler_manager.hh"
 #include "aka_memory.hh"
 #include "dumpable.hh"
 #include "element.hh"
 #include "element_class.hh"
 #include "element_type_map.hh"
 #include "group_manager.hh"
 #include "mesh_data.hh"
 #include "mesh_events.hh"
 /* -------------------------------------------------------------------------- */
 #include <set>
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 class Communicator;
 class ElementSynchronizer;
 class NodeSynchronizer;
 } // namespace akantu
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 /* Mesh                                                                       */
 /* -------------------------------------------------------------------------- */
 
 /**
  * @class  Mesh this  contain the  coordinates of  the nodes  in  the Mesh.nodes
  * Array,  and the  connectivity. The  connectivity  are stored  in by  element
  * types.
  *
  * In order to loop on all element you have to loop on all types like this :
  * @code{.cpp}
  for(auto & type : mesh.elementTypes()) {
    UInt nb_element  = mesh.getNbElement(type);
    const Array<UInt> & conn = mesh.getConnectivity(type);
    for(UInt e = 0; e < nb_element; ++e) {
      ...
    }
  }
 
  or
 
  for_each_element(mesh, [](Element & element) {
     std::cout << element << std::endl
   });
  @endcode
 */
 class Mesh : protected Memory,
              public EventHandlerManager<MeshEventHandler>,
              public GroupManager,
              public Dumpable {
   /* ------------------------------------------------------------------------ */
   /* Constructors/Destructors                                                 */
   /* ------------------------------------------------------------------------ */
 private:
   /// default constructor used for chaining, the last parameter is just to
   /// differentiate constructors
   Mesh(UInt spatial_dimension, const ID & id, const MemoryID & memory_id,
        Communicator & communicator);
 
 public:
   /// constructor that create nodes coordinates array
   Mesh(UInt spatial_dimension, const ID & id = "mesh",
        const MemoryID & memory_id = 0);
 
   /// mesh not distributed and not using the default communicator
   Mesh(UInt spatial_dimension, Communicator & communicator,
        const ID & id = "mesh", const MemoryID & memory_id = 0);
 
   /// constructor that use an existing nodes coordinates array, by knowing its
   /// ID
   // Mesh(UInt spatial_dimension, const ID & nodes_id, const ID & id,
   //      const MemoryID & memory_id = 0);
 
   /**
    * constructor that use an existing nodes coordinates
    * array, by getting the vector of coordinates
    */
   Mesh(UInt spatial_dimension, const std::shared_ptr<Array<Real>> & nodes,
        const ID & id = "mesh", const MemoryID & memory_id = 0);
 
   ~Mesh() override;
 
   /// @typedef ConnectivityTypeList list of the types present in a Mesh
   using ConnectivityTypeList = std::set<ElementType>;
 
   /// read the mesh from a file
   void read(const std::string & filename,
             const MeshIOType & mesh_io_type = _miot_auto);
   /// write the mesh to a file
   void write(const std::string & filename,
              const MeshIOType & mesh_io_type = _miot_auto);
 
 private:
   /// initialize the connectivity to NULL and other stuff
   void init();
 
   /// function that computes the bounding box (fills xmin, xmax)
   void computeBoundingBox();
 
   /* ------------------------------------------------------------------------ */
   /* Methods                                                                  */
   /* ------------------------------------------------------------------------ */
 public:
   /// patitionate the mesh among the processors involved in their computation
   virtual void distribute(Communicator & communicator);
   virtual void distribute();
 
   /// function to print the containt of the class
   void printself(std::ostream & stream, int indent = 0) const override;
 
   /// extract coordinates of nodes from an element
   template <typename T>
   inline void extractNodalValuesFromElement(const Array<T> & nodal_values,
                                             T * elemental_values,
                                             UInt * connectivity, UInt n_nodes,
                                             UInt nb_degree_of_freedom) const;
 
   // /// extract coordinates of nodes from a reversed element
   // inline void extractNodalCoordinatesFromPBCElement(Real * local_coords,
   //                                                   UInt * connectivity,
   //                                                   UInt n_nodes);
 
   /// add a Array of connectivity for the type <type>.
   inline void addConnectivityType(const ElementType & type,
                                   const GhostType & ghost_type = _not_ghost);
 
   /* ------------------------------------------------------------------------ */
   template <class Event> inline void sendEvent(Event & event) {
     //    if(event.getList().size() != 0)
     EventHandlerManager<MeshEventHandler>::sendEvent<Event>(event);
   }
 
   /// prepare the  event to remove the elements listed
   void eraseElements(const Array<Element> & elements);
 
   /* ------------------------------------------------------------------------ */
   template <typename T>
   inline void removeNodesFromArray(Array<T> & vect,
                                    const Array<UInt> & new_numbering);
 
   /// initialize normals
   void initNormals();
 
   /// init facets' mesh
   Mesh & initMeshFacets(const ID & id = "mesh_facets");
 
   /// define parent mesh
   void defineMeshParent(const Mesh & mesh);
 
   /// get global connectivity array
   void getGlobalConnectivity(ElementTypeMapArray<UInt> & global_connectivity);
 
 public:
   void getAssociatedElements(const Array<UInt> & node_list,
                              Array<Element> & elements);
 
 private:
   /// fills the nodes_to_elements structure
   void fillNodesToElements();
 
   /* ------------------------------------------------------------------------ */
   /* Accessors                                                                */
   /* ------------------------------------------------------------------------ */
 public:
   /// get the id of the mesh
   AKANTU_GET_MACRO(ID, Memory::id, const ID &);
 
   /// get the id of the mesh
   AKANTU_GET_MACRO(MemoryID, Memory::memory_id, const MemoryID &);
 
   /// get the spatial dimension of the mesh = number of component of the
   /// coordinates
   AKANTU_GET_MACRO(SpatialDimension, spatial_dimension, UInt);
 
   /// get the nodes Array aka coordinates
   AKANTU_GET_MACRO(Nodes, *nodes, const Array<Real> &);
   AKANTU_GET_MACRO_NOT_CONST(Nodes, *nodes, Array<Real> &);
 
   /// get the normals for the elements
   AKANTU_GET_MACRO_BY_ELEMENT_TYPE(Normals, normals, Real);
 
   /// get the number of nodes
   AKANTU_GET_MACRO(NbNodes, nodes->size(), UInt);
 
   /// get the Array of global ids of the nodes (only used in parallel)
   AKANTU_GET_MACRO(GlobalNodesIds, *nodes_global_ids, const Array<UInt> &);
   AKANTU_GET_MACRO_NOT_CONST(GlobalNodesIds, *nodes_global_ids, Array<UInt> &);
 
   /// get the global id of a node
   inline UInt getNodeGlobalId(UInt local_id) const;
 
   /// get the global id of a node
   inline UInt getNodeLocalId(UInt global_id) const;
 
   /// get the global number of nodes
   inline UInt getNbGlobalNodes() const;
 
   /// get the nodes type Array
   AKANTU_GET_MACRO(NodesType, nodes_type, const Array<NodeType> &);
 
 protected:
   AKANTU_GET_MACRO_NOT_CONST(NodesType, nodes_type, Array<NodeType> &);
 
 public:
   inline NodeType getNodeType(UInt local_id) const;
 
   /// say if a node is a pure ghost node
   inline bool isPureGhostNode(UInt n) const;
 
   /// say if a node is pur local or master node
   inline bool isLocalOrMasterNode(UInt n) const;
 
   inline bool isLocalNode(UInt n) const;
   inline bool isMasterNode(UInt n) const;
   inline bool isSlaveNode(UInt n) const;
 
   AKANTU_GET_MACRO(LowerBounds, lower_bounds, const Vector<Real> &);
   AKANTU_GET_MACRO(UpperBounds, upper_bounds, const Vector<Real> &);
   AKANTU_GET_MACRO(LocalLowerBounds, local_lower_bounds, const Vector<Real> &);
   AKANTU_GET_MACRO(LocalUpperBounds, local_upper_bounds, const Vector<Real> &);
 
   /// get the connectivity Array for a given type
   AKANTU_GET_MACRO_BY_ELEMENT_TYPE_CONST(Connectivity, connectivities, UInt);
   AKANTU_GET_MACRO_BY_ELEMENT_TYPE(Connectivity, connectivities, UInt);
   AKANTU_GET_MACRO(Connectivities, connectivities,
                    const ElementTypeMapArray<UInt> &);
 
   /// get the number of element of a type in the mesh
   inline UInt getNbElement(const ElementType & type,
                            const GhostType & ghost_type = _not_ghost) const;
 
   /// get the number of element for a given ghost_type and a given dimension
   inline UInt getNbElement(const UInt spatial_dimension = _all_dimensions,
                            const GhostType & ghost_type = _not_ghost,
                            const ElementKind & kind = _ek_not_defined) const;
 
   // /// get the connectivity list either for the elements or the ghost elements
   // inline const ConnectivityTypeList &
   // getConnectivityTypeList(const GhostType & ghost_type = _not_ghost) const;
 
   /// compute the barycenter of a given element
 private:
   inline void getBarycenter(UInt element, const ElementType & type,
                             Real * barycenter,
                             GhostType ghost_type = _not_ghost) const;
 
 public:
   inline void getBarycenter(const Element & element,
                             Vector<Real> & barycenter) const;
 
   void getBarycenters(Array<Real> & barycenter, const ElementType & type,
                       const GhostType & ghost_type) const;
 
 #ifndef SWIG
   /// get the element connected to a subelement
   const auto & getElementToSubelement() const;
 
   /// get the element connected to a subelement
   const auto &
   getElementToSubelement(const ElementType & el_type,
                          const GhostType & ghost_type = _not_ghost) const;
 
   /// get the element connected to a subelement
   auto & getElementToSubelement(const ElementType & el_type,
                                 const GhostType & ghost_type = _not_ghost);
 
   /// get the subelement connected to an element
   const auto &
   getSubelementToElement(const ElementType & el_type,
                          const GhostType & ghost_type = _not_ghost) const;
   /// get the subelement connected to an element
   auto & getSubelementToElement(const ElementType & el_type,
                                 const GhostType & ghost_type = _not_ghost);
 
 #endif
 
   /// register a new ElementalTypeMap in the MeshData
   template <typename T>
   inline ElementTypeMapArray<T> & registerData(const std::string & data_name);
 
   template <typename T>
   inline bool hasData(const ID & data_name, const ElementType & el_type,
                       const GhostType & ghost_type = _not_ghost) const;
 
   /// get a name field associated to the mesh
   template <typename T>
   inline const Array<T> &
   getData(const ID & data_name, const ElementType & el_type,
           const GhostType & ghost_type = _not_ghost) const;
 
   /// get a name field associated to the mesh
   template <typename T>
   inline Array<T> & getData(const ID & data_name, const ElementType & el_type,
                             const GhostType & ghost_type = _not_ghost);
 
   /// tells if the data data_name is contained in the mesh or not
   inline bool hasData(const ID & data_name) const;
 
   /// get a name field associated to the mesh
   template <typename T>
   inline const ElementTypeMapArray<T> & getData(const ID & data_name) const;
 
   /// get a name field associated to the mesh
   template <typename T>
   inline ElementTypeMapArray<T> & getData(const ID & data_name);
 
   template <typename T>
   ElementTypeMap<UInt> getNbDataPerElem(ElementTypeMapArray<T> & array,
                                         const ElementKind & element_kind);
 
   template <typename T>
   dumper::Field * createFieldFromAttachedData(const std::string & field_id,
                                               const std::string & group_name,
                                               const ElementKind & element_kind);
 
   /// templated getter returning the pointer to data in MeshData (modifiable)
   template <typename T>
   inline Array<T> &
   getDataPointer(const std::string & data_name, const ElementType & el_type,
                  const GhostType & ghost_type = _not_ghost,
                  UInt nb_component = 1, bool size_to_nb_element = true,
                  bool resize_with_parent = false);
 
   /// Facets mesh accessor
   inline const Mesh & getMeshFacets() const;
   inline Mesh & getMeshFacets();
 
   /// Parent mesh accessor
   inline const Mesh & getMeshParent() const;
 
   inline bool isMeshFacets() const { return this->is_mesh_facets; }
 
   /// defines is the mesh is distributed or not
   inline bool isDistributed() const { return this->is_distributed; }
 
 #ifndef SWIG
   /// return the dumper from a group and and a dumper name
   DumperIOHelper & getGroupDumper(const std::string & dumper_name,
                                   const std::string & group_name);
 #endif
   /* ------------------------------------------------------------------------ */
   /* Wrappers on ElementClass functions                                       */
   /* ------------------------------------------------------------------------ */
 public:
   /// get the number of nodes per element for a given element type
   static inline UInt getNbNodesPerElement(const ElementType & type);
 
   /// get the number of nodes per element for a given element type considered as
   /// a first order element
   static inline ElementType getP1ElementType(const ElementType & type);
 
   /// get the kind of the element type
   static inline ElementKind getKind(const ElementType & type);
 
   /// get spatial dimension of a type of element
   static inline UInt getSpatialDimension(const ElementType & type);
 
   /// get number of facets of a given element type
   static inline UInt getNbFacetsPerElement(const ElementType & type);
 
   /// get number of facets of a given element type
   static inline UInt getNbFacetsPerElement(const ElementType & type, UInt t);
 
 #ifndef SWIG
 
   /// get local connectivity of a facet for a given facet type
   static inline auto getFacetLocalConnectivity(const ElementType & type,
                                                UInt t = 0);
 
   /// get connectivity of facets for a given element
   inline auto getFacetConnectivity(const Element & element, UInt t = 0) const;
 
 #endif
 
   /// get the number of type of the surface element associated to a given
   /// element type
   static inline UInt getNbFacetTypes(const ElementType & type, UInt t = 0);
 
 #ifndef SWIG
 
   /// get the type of the surface element associated to a given element
   static inline constexpr auto getFacetType(const ElementType & type,
                                             UInt t = 0);
 
   /// get all the type of the surface element associated to a given element
   static inline constexpr auto getAllFacetTypes(const ElementType & type);
 
 #endif
 
   /// get the number of nodes in the given element list
   static inline UInt getNbNodesPerElementList(const Array<Element> & elements);
 
   /* ------------------------------------------------------------------------ */
   /* Element type Iterator                                                    */
   /* ------------------------------------------------------------------------ */
   using type_iterator = ElementTypeMapArray<UInt, ElementType>::type_iterator;
   using ElementTypesIteratorHelper =
       ElementTypeMapArray<UInt, ElementType>::ElementTypesIteratorHelper;
 
   template <typename... pack>
   ElementTypesIteratorHelper elementTypes(pack &&... _pack) const;
 
   inline type_iterator firstType(UInt dim = _all_dimensions,
                                  GhostType ghost_type = _not_ghost,
                                  ElementKind kind = _ek_regular) const {
     return connectivities.firstType(dim, ghost_type, kind);
   }
 
   inline type_iterator lastType(UInt dim = _all_dimensions,
                                 GhostType ghost_type = _not_ghost,
                                 ElementKind kind = _ek_regular) const {
     return connectivities.lastType(dim, ghost_type, kind);
   }
 
   AKANTU_GET_MACRO(ElementSynchronizer, *element_synchronizer,
                    const ElementSynchronizer &);
   AKANTU_GET_MACRO_NOT_CONST(ElementSynchronizer, *element_synchronizer,
                              ElementSynchronizer &);
   AKANTU_GET_MACRO(NodeSynchronizer, *node_synchronizer,
                    const NodeSynchronizer &);
   AKANTU_GET_MACRO_NOT_CONST(NodeSynchronizer, *node_synchronizer,
                              NodeSynchronizer &);
 
 // AKANTU_GET_MACRO_NOT_CONST(Communicator, *communicator, StaticCommunicator
 // &);
 #ifndef SWIG
   AKANTU_GET_MACRO(Communicator, *communicator, const auto &);
   AKANTU_GET_MACRO_NOT_CONST(Communicator, *communicator, auto &);
 #endif
   /* ------------------------------------------------------------------------ */
   /* Private methods for friends                                              */
   /* ------------------------------------------------------------------------ */
 private:
   friend class MeshAccessor;
 
   AKANTU_GET_MACRO(NodesPointer, *nodes, Array<Real> &);
 
   /// get a pointer to the nodes_global_ids Array<UInt> and create it if
   /// necessary
   inline Array<UInt> & getNodesGlobalIdsPointer();
 
   /// get a pointer to the nodes_type Array<Int> and create it if necessary
   inline Array<NodeType> & getNodesTypePointer();
 
   /// get a pointer to the connectivity Array for the given type and create it
   /// if necessary
   inline Array<UInt> &
   getConnectivityPointer(const ElementType & type,
                          const GhostType & ghost_type = _not_ghost);
 
   /// get the ghost element counter
   inline Array<UInt> &
   getGhostsCounters(const ElementType & type,
                     const GhostType & ghost_type = _ghost) {
     AKANTU_DEBUG_ASSERT(ghost_type != _not_ghost,
                         "No ghost counter for _not_ghost elements");
     return ghosts_counters(type, ghost_type);
   }
 
   /// get a pointer to the element_to_subelement Array for the given type and
   /// create it if necessary
   inline Array<std::vector<Element>> &
   getElementToSubelementPointer(const ElementType & type,
                                 const GhostType & ghost_type = _not_ghost);
 
   /// get a pointer to the subelement_to_element Array for the given type and
   /// create it if necessary
   inline Array<Element> &
   getSubelementToElementPointer(const ElementType & type,
                                 const GhostType & ghost_type = _not_ghost);
 
   AKANTU_GET_MACRO_NOT_CONST(MeshData, mesh_data, MeshData &);
 
   /* ------------------------------------------------------------------------ */
   /* Class Members                                                            */
   /* ------------------------------------------------------------------------ */
 private:
   /// array of the nodes coordinates
   std::shared_ptr<Array<Real>> nodes;
 
   /// global node ids
   std::unique_ptr<Array<UInt>> nodes_global_ids;
 
   /// node type,  -3 pure ghost, -2  master for the  node, -1 normal node,  i in
   /// [0-N] slave node and master is proc i
   Array<NodeType> nodes_type;
 
   /// global number of nodes;
   UInt nb_global_nodes{0};
 
   /// all class of elements present in this mesh (for heterogenous meshes)
   ElementTypeMapArray<UInt> connectivities;
 
   /// count the references on ghost elements
   ElementTypeMapArray<UInt> ghosts_counters;
 
   /// map to normals for all class of elements present in this mesh
   ElementTypeMapArray<Real> normals;
 
   /// list of all existing types in the mesh
   // ConnectivityTypeList type_set;
 
   /// the spatial dimension of this mesh
   UInt spatial_dimension{0};
 
   /// types offsets
   // Array<UInt> types_offsets;
 
   // /// list of all existing types in the mesh
   // ConnectivityTypeList ghost_type_set;
   // /// ghost types offsets
   // Array<UInt> ghost_types_offsets;
 
   /// min of coordinates
   Vector<Real> lower_bounds;
   /// max of coordinates
   Vector<Real> upper_bounds;
   /// size covered by the mesh on each direction
   Vector<Real> size;
 
   /// local min of coordinates
   Vector<Real> local_lower_bounds;
   /// local max of coordinates
   Vector<Real> local_upper_bounds;
 
   /// Extra data loaded from the mesh file
   MeshData mesh_data;
 
   /// facets' mesh
   std::unique_ptr<Mesh> mesh_facets;
 
   /// parent mesh (this is set for mesh_facets meshes)
   const Mesh * mesh_parent{nullptr};
 
   /// defines if current mesh is mesh_facets or not
   bool is_mesh_facets{false};
 
   /// defines if the mesh is centralized or distributed
   bool is_distributed{false};
 
   /// Communicator on which mesh is distributed
   Communicator * communicator;
 
   /// Element synchronizer
   std::unique_ptr<ElementSynchronizer> element_synchronizer;
 
   /// Node synchronizer
   std::unique_ptr<NodeSynchronizer> node_synchronizer;
 
   using NodesToElements = std::vector<std::unique_ptr<std::set<Element>>>;
 
   /// This info is stored to simplify the dynamic changes
   NodesToElements nodes_to_elements;
 };
 
 /// standard output stream operator
 inline std::ostream & operator<<(std::ostream & stream, const Mesh & _this) {
   _this.printself(stream);
   return stream;
 }
 
 } // namespace akantu
 
 /* -------------------------------------------------------------------------- */
 /* Inline functions                                                           */
 /* -------------------------------------------------------------------------- */
 
 #include "element_type_map_tmpl.hh"
 #include "mesh_inline_impl.cc"
 
 #endif /* __AKANTU_MESH_HH__ */
diff --git a/src/mesh/mesh_accessor.hh b/src/mesh/mesh_accessor.hh
index 402286b60..9ac501700 100644
--- a/src/mesh/mesh_accessor.hh
+++ b/src/mesh/mesh_accessor.hh
@@ -1,135 +1,137 @@
 /**
  * @file   mesh_accessor.hh
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Tue Jun 30 2015
+ * @date last modification: Tue Sep 19 2017
  *
  * @brief  this class allow to access some private member of mesh it is used for
  * IO for examples
  *
  * @section LICENSE
  *
- * Copyright (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne) Laboratory
- * (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * Copyright (©) 2015-2018 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
- * terms  of the  GNU Lesser  General Public  License as  published by  the Free
+ * 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
+ * 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 "mesh.hh"
 /* -------------------------------------------------------------------------- */
 
 #ifndef __AKANTU_MESH_ACCESSOR_HH__
 #define __AKANTU_MESH_ACCESSOR_HH__
 
 namespace akantu {
 class NodeSynchronizer;
 class ElementSynchronizer;
 } // namespace akantu
 
 namespace akantu {
 
 class MeshAccessor {
   /* ------------------------------------------------------------------------ */
   /* Constructors/Destructors                                                 */
   /* ------------------------------------------------------------------------ */
 public:
   explicit MeshAccessor(Mesh & mesh) : _mesh(mesh) {}
   virtual ~MeshAccessor() = default;
 
   /* ------------------------------------------------------------------------ */
   /* Accessors                                                                */
   /* ------------------------------------------------------------------------ */
 public:
   /// get the global number of nodes
   inline UInt getNbGlobalNodes() const { return this->_mesh.nb_global_nodes; }
 
   /// set the global number of nodes
   inline void setNbGlobalNodes(UInt nb_global_nodes) {
     this->_mesh.nb_global_nodes = nb_global_nodes;
   }
 
   /// set the mesh as being distributed
   inline void setDistributed() { this->_mesh.is_distributed = true; }
 
   /// get a pointer to the nodes_global_ids Array<UInt> and create it if
   /// necessary
   inline auto & getNodesGlobalIds() {
     return this->_mesh.getNodesGlobalIdsPointer();
   }
 
   /// get a pointer to the nodes_type Array<Int> and create it if necessary
   inline auto & getNodesType() { return this->_mesh.getNodesTypePointer(); }
 
   /// get a pointer to the coordinates Array
   inline auto & getNodes() { return this->_mesh.getNodesPointer(); }
 
   /// get a pointer to the coordinates Array
   inline auto getNodesSharedPtr() { return this->_mesh.nodes; }
 
   /// get a pointer to the connectivity Array for the given type and create it
   /// if necessary
   inline auto & getConnectivity(const ElementType & type,
                                 const GhostType & ghost_type = _not_ghost) {
     return this->_mesh.getConnectivityPointer(type, ghost_type);
   }
 
   /// get the ghost element counter
   inline auto & getGhostsCounters(const ElementType & type,
                                   const GhostType & ghost_type = _ghost) {
     return this->_mesh.getGhostsCounters(type, ghost_type);
   }
 
   /// get a pointer to the element_to_subelement Array for the given type and
   /// create it if necessary
   inline auto &
   getElementToSubelement(const ElementType & type,
                          const GhostType & ghost_type = _not_ghost) {
     return this->_mesh.getElementToSubelementPointer(type, ghost_type);
   }
 
   /// get a pointer to the subelement_to_element Array for the given type and
   /// create it if necessary
   inline auto &
   getSubelementToElement(const ElementType & type,
                          const GhostType & ghost_type = _not_ghost) {
     return this->_mesh.getSubelementToElementPointer(type, ghost_type);
   }
 
   template <typename T>
   inline auto &
   getData(const std::string & data_name, const ElementType & el_type,
           const GhostType & ghost_type = _not_ghost, UInt nb_component = 1,
           bool size_to_nb_element = true, bool resize_with_parent = false) {
     return this->_mesh.getDataPointer<T>(data_name, el_type, ghost_type,
                                          nb_component, size_to_nb_element,
                                          resize_with_parent);
   }
 
   auto & getMeshData() { return this->_mesh.getMeshData(); }
 
   /// get the node synchonizer
   auto & getNodeSynchronizer() { return *this->_mesh.node_synchronizer; }
 
   /// get the element synchonizer
   auto & getElementSynchronizer() { return *this->_mesh.element_synchronizer; }
 
 private:
   Mesh & _mesh;
 };
 
 } // namespace akantu
 
 #endif /* __AKANTU_MESH_ACCESSOR_HH__ */
diff --git a/src/mesh/mesh_data.cc b/src/mesh/mesh_data.cc
index 88022e988..ead9bcf7c 100644
--- a/src/mesh/mesh_data.cc
+++ b/src/mesh/mesh_data.cc
@@ -1,48 +1,47 @@
 /**
  * @file   mesh_data.cc
  *
  * @author Dana Christen <dana.christen@gmail.com>
  *
  * @date creation: Fri Apr 13 2012
- * @date last modification: Sun Oct 19 2014
+ * @date last modification: Mon Jun 19 2017
  *
  * @brief  Stores generic data loaded from the mesh file
  *
  * @section LICENSE
  *
- * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
- * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
- * Solides)
+ * 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
+ * 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
+ * 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 "mesh_data.hh"
 #include "mesh.hh"
 
 namespace akantu {
 
 MeshData::MeshData(const ID & _id, const ID & parent_id,
                    const MemoryID & mem_id)
     : Memory(parent_id + ":" + _id, mem_id) {}
 
 MeshData::~MeshData() {
   ElementalDataMap::iterator it, end;
   for (it = elemental_data.begin(); it != elemental_data.end(); ++it) {
     delete it->second;
   }
 }
 
 } // akantu
diff --git a/src/mesh/mesh_data.hh b/src/mesh/mesh_data.hh
index 029af4fe9..45650efae 100644
--- a/src/mesh/mesh_data.hh
+++ b/src/mesh/mesh_data.hh
@@ -1,153 +1,153 @@
 /**
  * @file   mesh_data.hh
  *
  * @author Dana Christen <dana.christen@gmail.com>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Fri May 03 2013
- * @date last modification: Thu Nov 05 2015
+ * @date last modification: Mon Dec 18 2017
  *
  * @brief  Stores generic data loaded from the mesh file
  *
  * @section LICENSE
  *
- * Copyright  (©)  2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de Lausanne)
+ * 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
+ * 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
+ * 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_MESH_DATA_HH__
 #define __AKANTU_MESH_DATA_HH__
 
 /* -------------------------------------------------------------------------- */
 #include "aka_memory.hh"
 #include "element_type_map.hh"
 #include <map>
 #include <string>
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 
 #define AKANTU_MESH_DATA_TYPES                                                 \
   ((_tc_int, Int))((_tc_uint, UInt))((_tc_real, Real))(                        \
       (_tc_element, Element))((_tc_std_string, std::string))(                  \
       (_tc_std_vector_element, std::vector<Element>))
 
 #define AKANTU_MESH_DATA_TUPLE_FIRST_ELEM(s, data, elem)                       \
   BOOST_PP_TUPLE_ELEM(2, 0, elem)
 enum MeshDataTypeCode : int {
   BOOST_PP_SEQ_ENUM(BOOST_PP_SEQ_TRANSFORM(AKANTU_MESH_DATA_TUPLE_FIRST_ELEM, ,
                                            AKANTU_MESH_DATA_TYPES)),
   _tc_unknown
 };
 
 class MeshData : public Memory {
 
   /* ------------------------------------------------------------------------ */
   /* Typedefs                                                                 */
   /* ------------------------------------------------------------------------ */
 private:
   using TypeCode = MeshDataTypeCode;
   using ElementalDataMap = std::map<std::string, ElementTypeMapBase *>;
   using StringVector = std::vector<std::string>;
   using TypeCodeMap = std::map<std::string, TypeCode>;
 
   /* ------------------------------------------------------------------------ */
   /* Constructors/Destructors                                                 */
   /* ------------------------------------------------------------------------ */
 public:
   MeshData(const ID & id = "mesh_data", const ID & parent_id = "",
            const MemoryID & memory_id = 0);
   ~MeshData() override;
 
   /* ------------------------------------------------------------------------ */
   /* Methods and accessors                                                    */
   /* ------------------------------------------------------------------------ */
 public:
   ///  Register new elemental data (and alloc data) with check if the name is
   ///  new
   template <typename T> void registerElementalData(const ID & name);
   inline void registerElementalData(const ID & name, TypeCode type);
 
   /// tells if the given array exists
   template <typename T>
   bool hasDataArray(const ID & data_name, const ElementType & el_type,
                     const GhostType & ghost_type = _not_ghost) const;
 
   /// tells if the given data exists
   bool hasData(const ID & data_name) const;
 
   /// Get an existing elemental data array
   template <typename T>
   const Array<T> &
   getElementalDataArray(const ID & data_name, const ElementType & el_type,
                         const GhostType & ghost_type = _not_ghost) const;
   template <typename T>
   Array<T> & getElementalDataArray(const ID & data_name,
                                    const ElementType & el_type,
                                    const GhostType & ghost_type = _not_ghost);
 
   /// Get an elemental data array, if it does not exist: allocate it
   template <typename T>
   Array<T> &
   getElementalDataArrayAlloc(const ID & data_name, const ElementType & el_type,
                              const GhostType & ghost_type = _not_ghost,
                              UInt nb_component = 1);
 
   /// get the names of the data stored in elemental_data
   inline void getTagNames(StringVector & tags, const ElementType & type,
                           const GhostType & ghost_type = _not_ghost) const;
 
   /// get the type of the data stored in elemental_data
   template <typename T> TypeCode getTypeCode() const;
   inline TypeCode getTypeCode(const ID & name) const;
 
   template <typename T>
   inline UInt getNbComponentTemplated(const ID & name,
                                       const ElementType & el_type,
                                       const GhostType & ghost_type) const;
   inline UInt getNbComponent(const ID & name, const ElementType & el_type,
                              const GhostType & ghost_type = _not_ghost) const;
 
   /// Get an existing elemental data
   template <typename T>
   const ElementTypeMapArray<T> & getElementalData(const ID & name) const;
   template <typename T>
   ElementTypeMapArray<T> & getElementalData(const ID & name);
 
 private:
   ///  Register new elemental data (add alloc data)
   template <typename T>
   ElementTypeMapArray<T> * allocElementalData(const ID & name);
 
   /* ------------------------------------------------------------------------ */
   /* Class Members                                                            */
   /* ------------------------------------------------------------------------ */
 private:
   /// Map when elemental data is stored as ElementTypeMap
   ElementalDataMap elemental_data;
   /// Map when elementalType of the data stored in elemental_data
   TypeCodeMap typecode_map;
 };
 
 } // akantu
 
 #include "mesh_data_tmpl.hh"
 #undef AKANTU_MESH_DATA_TUPLE_FIRST_ELEM
 
 #endif /* __AKANTU_MESH_DATA_HH__ */
diff --git a/src/mesh/mesh_data_tmpl.hh b/src/mesh/mesh_data_tmpl.hh
index 6cd581045..7de088649 100644
--- a/src/mesh/mesh_data_tmpl.hh
+++ b/src/mesh/mesh_data_tmpl.hh
@@ -1,275 +1,276 @@
 /**
  * @file   mesh_data_tmpl.hh
  *
  * @author Dana Christen <dana.christen@gmail.com>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Fri May 03 2013
- * @date last modification: Thu Nov 05 2015
+ * @date last modification: Tue Feb 20 2018
  *
  * @brief  Stores generic data loaded from the mesh file
  *
  * @section LICENSE
  *
- * Copyright  (©)  2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de Lausanne)
+ * 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
+ * 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
+ * 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 "mesh_data.hh"
 /* -------------------------------------------------------------------------- */
 
 #ifndef __AKANTU_MESH_DATA_TMPL_HH__
 #define __AKANTU_MESH_DATA_TMPL_HH__
 
 namespace akantu {
 
 #define MESH_DATA_GET_TYPE(r, data, type)                                      \
   template <>                                                                  \
   inline MeshDataTypeCode                                                      \
   MeshData::getTypeCode<BOOST_PP_TUPLE_ELEM(2, 1, type)>() const {             \
     return BOOST_PP_TUPLE_ELEM(2, 0, type);                                    \
   }
 
 /* -------------------------------------------------------------------------- */
 // get the type of the data stored in elemental_data
 template <typename T> inline MeshDataTypeCode MeshData::getTypeCode() const {
   AKANTU_ERROR("Type " << debug::demangle(typeid(T).name())
                        << "not implemented by MeshData.");
 }
 
 /* -------------------------------------------------------------------------- */
 BOOST_PP_SEQ_FOR_EACH(MESH_DATA_GET_TYPE, void, AKANTU_MESH_DATA_TYPES)
 #undef MESH_DATA_GET_TYPE
 
 inline MeshDataTypeCode MeshData::getTypeCode(const ID & name) const {
   auto it = typecode_map.find(name);
   if (it == typecode_map.end())
     AKANTU_EXCEPTION("No dataset named " << name << " found.");
   return it->second;
 }
 
 /* -------------------------------------------------------------------------- */
 //  Register new elemental data templated (and alloc data) with check if the
 //  name is new
 template <typename T> void MeshData::registerElementalData(const ID & name) {
   auto it = elemental_data.find(name);
   if (it == elemental_data.end()) {
     allocElementalData<T>(name);
   } else {
     AKANTU_DEBUG_INFO("Data named " << name << " already registered.");
   }
 }
 
 /* -------------------------------------------------------------------------- */
 //  Register new elemental data of a given MeshDataTypeCode with check if the
 //  name is new
 #define AKANTU_MESH_DATA_CASE_MACRO(r, name, elem)                             \
   case BOOST_PP_TUPLE_ELEM(2, 0, elem): {                                      \
     registerElementalData<BOOST_PP_TUPLE_ELEM(2, 1, elem)>(name);              \
     break;                                                                     \
   }
 
 inline void MeshData::registerElementalData(const ID & name,
                                             MeshDataTypeCode type) {
   switch (type) {
     BOOST_PP_SEQ_FOR_EACH(AKANTU_MESH_DATA_CASE_MACRO, name,
                           AKANTU_MESH_DATA_TYPES)
   default:
     AKANTU_ERROR("Type " << type << "not implemented by MeshData.");
   }
 }
 #undef AKANTU_MESH_DATA_CASE_MACRO
 
 /* -------------------------------------------------------------------------- */
 /// Register new elemental data (and alloc data)
 template <typename T>
 ElementTypeMapArray<T> * MeshData::allocElementalData(const ID & name) {
   auto * dataset = new ElementTypeMapArray<T>(name, id, memory_id);
   elemental_data[name] = dataset;
   typecode_map[name] = getTypeCode<T>();
   return dataset;
 }
 
 /* -------------------------------------------------------------------------- */
 template <typename T>
 const ElementTypeMapArray<T> &
 MeshData::getElementalData(const ID & name) const {
   auto it = elemental_data.find(name);
   if (it == elemental_data.end())
     AKANTU_EXCEPTION("No dataset named " << name << " found.");
   return dynamic_cast<const ElementTypeMapArray<T> &>(*(it->second));
 }
 
 /* -------------------------------------------------------------------------- */
 // Get an existing elemental data
 template <typename T>
 ElementTypeMapArray<T> & MeshData::getElementalData(const ID & name) {
   auto it = elemental_data.find(name);
   if (it == elemental_data.end())
     AKANTU_EXCEPTION("No dataset named " << name << " found.");
   return dynamic_cast<ElementTypeMapArray<T> &>(*(it->second));
 }
 
 /* -------------------------------------------------------------------------- */
 template <typename T>
 bool MeshData::hasDataArray(const ID & name, const ElementType & elem_type,
                             const GhostType & ghost_type) const {
   auto it = elemental_data.find(name);
   if (it == elemental_data.end())
     return false;
 
   auto & elem_map = dynamic_cast<const ElementTypeMapArray<T> &>(*(it->second));
   return elem_map.exists(elem_type, ghost_type);
 }
 
 /* -------------------------------------------------------------------------- */
 inline bool MeshData::hasData(const ID & name) const {
   auto it = elemental_data.find(name);
   return (it != elemental_data.end());
 }
 
 /* -------------------------------------------------------------------------- */
 template <typename T>
 const Array<T> &
 MeshData::getElementalDataArray(const ID & name, const ElementType & elem_type,
                                 const GhostType & ghost_type) const {
   auto it = elemental_data.find(name);
   if (it == elemental_data.end()) {
     AKANTU_EXCEPTION("Data named " << name
                                    << " not registered for type: " << elem_type
                                    << " - ghost_type:" << ghost_type << "!");
   }
   return dynamic_cast<const ElementTypeMapArray<T> &>(*(it->second))(
       elem_type, ghost_type);
 }
 
 template <typename T>
 Array<T> & MeshData::getElementalDataArray(const ID & name,
                                            const ElementType & elem_type,
                                            const GhostType & ghost_type) {
   auto it = elemental_data.find(name);
   if (it == elemental_data.end()) {
     AKANTU_EXCEPTION("Data named " << name
                                    << " not registered for type: " << elem_type
                                    << " - ghost_type:" << ghost_type << "!");
   }
   return dynamic_cast<ElementTypeMapArray<T> &>(*(it->second))(elem_type,
                                                                ghost_type);
 }
 
 /* -------------------------------------------------------------------------- */
 // Get an elemental data array, if it does not exist: allocate it
 template <typename T>
 Array<T> & MeshData::getElementalDataArrayAlloc(const ID & name,
                                                 const ElementType & elem_type,
                                                 const GhostType & ghost_type,
                                                 UInt nb_component) {
   auto it = elemental_data.find(name);
   ElementTypeMapArray<T> * dataset;
   if (it == elemental_data.end()) {
     dataset = allocElementalData<T>(name);
   } else {
     dataset = dynamic_cast<ElementTypeMapArray<T> *>(it->second);
   }
   AKANTU_DEBUG_ASSERT(
       getTypeCode<T>() == typecode_map.find(name)->second,
       "Function getElementalDataArrayAlloc called with the wrong type!");
   if (!(dataset->exists(elem_type, ghost_type))) {
     dataset->alloc(0, nb_component, elem_type, ghost_type);
   }
   return (*dataset)(elem_type, ghost_type);
 }
 
 /* -------------------------------------------------------------------------- */
 #define AKANTU_MESH_DATA_CASE_MACRO(r, name, elem)                             \
   case BOOST_PP_TUPLE_ELEM(2, 0, elem): {                                      \
     nb_comp = getNbComponentTemplated<BOOST_PP_TUPLE_ELEM(2, 1, elem)>(        \
         name, el_type, ghost_type);                                            \
     break;                                                                     \
   }
 
 inline UInt MeshData::getNbComponent(const ID & name,
                                      const ElementType & el_type,
                                      const GhostType & ghost_type) const {
   auto it = typecode_map.find(name);
   UInt nb_comp(0);
   if (it == typecode_map.end()) {
     AKANTU_EXCEPTION("Could not determine the type held in dataset "
                      << name << " for type: " << el_type
                      << " - ghost_type:" << ghost_type << ".");
   }
   MeshDataTypeCode type = it->second;
   switch (type) {
     BOOST_PP_SEQ_FOR_EACH(AKANTU_MESH_DATA_CASE_MACRO, name,
                           AKANTU_MESH_DATA_TYPES)
   default:
     AKANTU_ERROR(
         "Could not call the correct instance of getNbComponentTemplated.");
     break;
   }
   return nb_comp;
 }
 #undef AKANTU_MESH_DATA_CASE_MACRO
 
 /* -------------------------------------------------------------------------- */
 template <typename T>
 inline UInt
 MeshData::getNbComponentTemplated(const ID & name, const ElementType & el_type,
                                   const GhostType & ghost_type) const {
   return getElementalDataArray<T>(name, el_type, ghost_type).getNbComponent();
 }
 
 /* -------------------------------------------------------------------------- */
 // get the names of the data stored in elemental_data
 #define AKANTU_MESH_DATA_CASE_MACRO(r, name, elem)                             \
   case BOOST_PP_TUPLE_ELEM(2, 0, elem): {                                      \
     ElementTypeMapArray<BOOST_PP_TUPLE_ELEM(2, 1, elem)> * dataset;            \
     dataset =                                                                  \
         dynamic_cast<ElementTypeMapArray<BOOST_PP_TUPLE_ELEM(2, 1, elem)> *>(  \
             it->second);                                                       \
     exists = dataset->exists(el_type, ghost_type);                             \
     break;                                                                     \
   }
 
 inline void MeshData::getTagNames(StringVector & tags,
                                   const ElementType & el_type,
                                   const GhostType & ghost_type) const {
   tags.clear();
   bool exists(false);
 
   auto it = elemental_data.begin();
   auto it_end = elemental_data.end();
   for (; it != it_end; ++it) {
     MeshDataTypeCode type = getTypeCode(it->first);
     switch (type) {
       BOOST_PP_SEQ_FOR_EACH(AKANTU_MESH_DATA_CASE_MACRO, ,
                             AKANTU_MESH_DATA_TYPES)
     default:
       AKANTU_ERROR("Could not determine the proper type to (dynamic-)cast.");
       break;
     }
     if (exists) {
       tags.push_back(it->first);
     }
   }
 }
 #undef AKANTU_MESH_DATA_CASE_MACRO
 
 /* -------------------------------------------------------------------------- */
 } // namespace akantu
 
 #endif /* __AKANTU_MESH_DATA_TMPL_HH__ */
diff --git a/src/mesh/mesh_events.hh b/src/mesh/mesh_events.hh
index 53f8f0d9a..a654c4f5e 100644
--- a/src/mesh/mesh_events.hh
+++ b/src/mesh/mesh_events.hh
@@ -1,198 +1,198 @@
 /**
  * @file   mesh_events.hh
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Fri Feb 20 2015
- * @date last modification: Mon Dec 07 2015
+ * @date last modification: Tue Feb 20 2018
  *
  * @brief  Classes corresponding to mesh events type
  *
  * @section LICENSE
  *
- * Copyright (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne) Laboratory
- * (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * Copyright (©) 2015-2018 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
- * terms  of the  GNU Lesser  General Public  License as  published by  the Free
+ * 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
+ * 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 <utility>
 
 #include "aka_array.hh"
 #include "element.hh"
 #include "element_type_map.hh"
 /* -------------------------------------------------------------------------- */
 
 #ifndef __AKANTU_MESH_EVENTS_HH__
 #define __AKANTU_MESH_EVENTS_HH__
 
 namespace akantu {
 
 /// akantu::MeshEvent is the base event for meshes
 template <class Entity> class MeshEvent {
 public:
   virtual ~MeshEvent() = default;
   /// Get the list of entity modified by the event nodes or elements
   const Array<Entity> & getList() const { return list; }
   /// Get the list of entity modified by the event nodes or elements
   Array<Entity> & getList() { return list; }
 
 protected:
   Array<Entity> list;
 };
 
 class Mesh;
 
 /// akantu::MeshEvent related to new nodes in the mesh
 class NewNodesEvent : public MeshEvent<UInt> {
 public:
   ~NewNodesEvent() override = default;
 };
 
 /// akantu::MeshEvent related to nodes removed from the mesh
 class RemovedNodesEvent : public MeshEvent<UInt> {
 public:
   ~RemovedNodesEvent() override = default;
   inline RemovedNodesEvent(const Mesh & mesh);
   /// Get the new numbering following suppression of nodes from nodes arrays
   AKANTU_GET_MACRO_NOT_CONST(NewNumbering, new_numbering, Array<UInt> &);
   /// Get the new numbering following suppression of nodes from nodes arrays
   AKANTU_GET_MACRO(NewNumbering, new_numbering, const Array<UInt> &);
 
 private:
   Array<UInt> new_numbering;
 };
 
 /// akantu::MeshEvent related to new elements in the mesh
 class NewElementsEvent : public MeshEvent<Element> {
 public:
   ~NewElementsEvent() override = default;
 };
 
 /// akantu::MeshEvent related to elements removed from the mesh
 class RemovedElementsEvent : public MeshEvent<Element> {
 public:
   ~RemovedElementsEvent() override = default;
   inline RemovedElementsEvent(const Mesh & mesh,
                               const ID & new_numbering_id = "new_numbering");
   /// Get the new numbering following suppression of elements from elements
   /// arrays
   AKANTU_GET_MACRO(NewNumbering, new_numbering,
                    const ElementTypeMapArray<UInt> &);
   /// Get the new numbering following suppression of elements from elements
   /// arrays
   AKANTU_GET_MACRO_NOT_CONST(NewNumbering, new_numbering,
                              ElementTypeMapArray<UInt> &);
   /// Get the new numbering following suppression of elements from elements
   /// arrays
   AKANTU_GET_MACRO_BY_ELEMENT_TYPE(NewNumbering, new_numbering, UInt);
   /// Get the new numbering following suppression of elements from elements
   /// arrays
   AKANTU_GET_MACRO_BY_ELEMENT_TYPE_CONST(NewNumbering, new_numbering, UInt);
 
 protected:
   ElementTypeMapArray<UInt> new_numbering;
 };
 
 /// akantu::MeshEvent for element that changed in some sort, can be seen as a
 /// combination of removed and added elements
 class ChangedElementsEvent : public RemovedElementsEvent {
 public:
   ~ChangedElementsEvent() override = default;
   inline ChangedElementsEvent(
       const Mesh & mesh, ID new_numbering_id = "changed_event:new_numbering")
       : RemovedElementsEvent(mesh, std::move(new_numbering_id)){};
   AKANTU_GET_MACRO(ListOld, list, const Array<Element> &);
   AKANTU_GET_MACRO_NOT_CONST(ListOld, list, Array<Element> &);
   AKANTU_GET_MACRO(ListNew, new_list, const Array<Element> &);
   AKANTU_GET_MACRO_NOT_CONST(ListNew, new_list, Array<Element> &);
 
 protected:
   Array<Element> new_list;
 };
 
 /* -------------------------------------------------------------------------- */
 
 class MeshEventHandler {
 public:
   virtual ~MeshEventHandler() = default;
   /* ------------------------------------------------------------------------ */
   /* Internal code                                                            */
   /* ------------------------------------------------------------------------ */
 private:
   /// send a akantu::NewNodesEvent
   inline void sendEvent(const NewNodesEvent & event) {
     onNodesAdded(event.getList(), event);
   }
   /// send a akantu::RemovedNodesEvent
   inline void sendEvent(const RemovedNodesEvent & event) {
     onNodesRemoved(event.getList(), event.getNewNumbering(), event);
   }
   /// send a akantu::NewElementsEvent
   inline void sendEvent(const NewElementsEvent & event) {
     onElementsAdded(event.getList(), event);
   }
   /// send a akantu::RemovedElementsEvent
   inline void sendEvent(const RemovedElementsEvent & event) {
     onElementsRemoved(event.getList(), event.getNewNumbering(), event);
   }
   /// send a akantu::ChangedElementsEvent
   inline void sendEvent(const ChangedElementsEvent & event) {
     onElementsChanged(event.getListOld(), event.getListNew(),
                       event.getNewNumbering(), event);
   }
   template <class EventHandler> friend class EventHandlerManager;
 
   /* ------------------------------------------------------------------------ */
   /* Interface                                                                */
   /* ------------------------------------------------------------------------ */
 public:
   /// function to implement to react on  akantu::NewNodesEvent
   virtual void onNodesAdded(const Array<UInt> & /*nodes_list*/,
                             const NewNodesEvent & /*event*/) {
     AKANTU_TO_IMPLEMENT();
   }
   /// function to implement to react on  akantu::RemovedNodesEvent
   virtual void onNodesRemoved(const Array<UInt> & /*nodes_list*/,
                               const Array<UInt> & /*new_numbering*/,
                               const RemovedNodesEvent & /*event*/) {
     AKANTU_TO_IMPLEMENT();
   }
   /// function to implement to react on  akantu::NewElementsEvent
   virtual void onElementsAdded(const Array<Element> & /*elements_list*/,
                                const NewElementsEvent & /*event*/) {
     AKANTU_TO_IMPLEMENT();
   }
   /// function to implement to react on  akantu::RemovedElementsEvent
   virtual void
   onElementsRemoved(const Array<Element> & /*elements_list*/,
                     const ElementTypeMapArray<UInt> & /*new_numbering*/,
                     const RemovedElementsEvent & /*event*/) {
     AKANTU_TO_IMPLEMENT();
   }
   /// function to implement to react on  akantu::ChangedElementsEvent
   virtual void
   onElementsChanged(const Array<Element> & /*old_elements_list*/,
                     const Array<Element> & /*new_elements_list*/,
                     const ElementTypeMapArray<UInt> & /*new_numbering*/,
                     const ChangedElementsEvent & /*event*/) {
     AKANTU_TO_IMPLEMENT();
   }
 };
 
 } // akantu
 
 #endif /* __AKANTU_MESH_EVENTS_HH__ */
diff --git a/src/mesh/mesh_filter.hh b/src/mesh/mesh_filter.hh
index 59420e63d..3607f549d 100644
--- a/src/mesh/mesh_filter.hh
+++ b/src/mesh/mesh_filter.hh
@@ -1,73 +1,72 @@
 /**
  * @file   mesh_filter.hh
  *
  * @author David Simon Kammer <david.kammer@epfl.ch>
  *
  * @date creation: Fri Jun 18 2010
- * @date last modification: Fri Dec 18 2015
+ * @date last modification: Tue Feb 20 2018
  *
  * @brief  the class representing the meshes
  *
  * @section LICENSE
  *
- * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
- * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
- * Solides)
+ * 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
+ * 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
+ * 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_MESH_FILTER_HH__
 #define __AKANTU_MESH_FILTER_HH__
 
 /* -------------------------------------------------------------------------- */
 #include "element.hh"
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 /* Filter Functors                                                            */
 /* -------------------------------------------------------------------------- */
 
 /// struct for the possible filter functors
 struct FilterFunctor {
   enum Type { _node_filter_functor, _element_filter_functor };
 };
 
 /// class (functor) for the node filter
 class NodeFilterFunctor : public FilterFunctor {
 public:
   bool operator()(__attribute__((unused)) UInt node) { AKANTU_TO_IMPLEMENT(); }
 
 public:
   static const Type type = _node_filter_functor;
 };
 
 /// class (functor) for the element filter
 class ElementFilterFunctor : public FilterFunctor {
 public:
   bool operator()(__attribute__((unused)) const Element & element) {
     AKANTU_TO_IMPLEMENT();
   }
 
 public:
   static const Type type = _element_filter_functor;
 };
 
 } // akantu
 
 #endif /* __AKANTU_MESH_FILTER_HH__ */
diff --git a/src/mesh/mesh_inline_impl.cc b/src/mesh/mesh_inline_impl.cc
index fd19d3982..2e4b756b5 100644
--- a/src/mesh/mesh_inline_impl.cc
+++ b/src/mesh/mesh_inline_impl.cc
@@ -1,637 +1,636 @@
 /**
  * @file   mesh_inline_impl.cc
  *
  * @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
  * @author Dana Christen <dana.christen@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  * @author Marco Vocialta <marco.vocialta@epfl.ch>
  *
  * @date creation: Thu Jul 15 2010
- * @date last modification: Thu Jan 21 2016
+ * @date last modification: Mon Dec 18 2017
  *
  * @brief  Implementation of the inline functions of the mesh class
  *
  * @section LICENSE
  *
- * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
- * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
- * Solides)
+ * 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
+ * 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
+ * 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_iterators.hh"
 #include "element_class.hh"
 #include "mesh.hh"
 /* -------------------------------------------------------------------------- */
 
 #ifndef __AKANTU_MESH_INLINE_IMPL_CC__
 #define __AKANTU_MESH_INLINE_IMPL_CC__
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 /* -------------------------------------------------------------------------- */
 inline ElementKind Element::kind() const { return Mesh::getKind(type); }
 
 /* -------------------------------------------------------------------------- */
 /* -------------------------------------------------------------------------- */
 template <typename... pack>
 Mesh::ElementTypesIteratorHelper Mesh::elementTypes(pack &&... _pack) const {
   return connectivities.elementTypes(_pack...);
 }
 
 /* -------------------------------------------------------------------------- */
 inline RemovedNodesEvent::RemovedNodesEvent(const Mesh & mesh)
     : new_numbering(mesh.getNbNodes(), 1, "new_numbering") {}
 
 /* -------------------------------------------------------------------------- */
 inline RemovedElementsEvent::RemovedElementsEvent(const Mesh & mesh,
                                                   const ID & new_numbering_id)
     : new_numbering(new_numbering_id, mesh.getID(), mesh.getMemoryID()) {}
 
 /* -------------------------------------------------------------------------- */
 template <>
 inline void Mesh::sendEvent<NewElementsEvent>(NewElementsEvent & event) {
   this->nodes_to_elements.resize(nodes->size());
   for (const auto & elem : event.getList()) {
     const Array<UInt> & conn = connectivities(elem.type, elem.ghost_type);
 
     UInt nb_nodes_per_elem = this->getNbNodesPerElement(elem.type);
 
     for (UInt n = 0; n < nb_nodes_per_elem; ++n) {
       UInt node = conn(elem.element, n);
       if (not nodes_to_elements[node])
         nodes_to_elements[node] = std::make_unique<std::set<Element>>();
       nodes_to_elements[node]->insert(elem);
     }
   }
 
   EventHandlerManager<MeshEventHandler>::sendEvent(event);
 }
 
 /* -------------------------------------------------------------------------- */
 template <> inline void Mesh::sendEvent<NewNodesEvent>(NewNodesEvent & event) {
   this->computeBoundingBox();
 
   EventHandlerManager<MeshEventHandler>::sendEvent(event);
 }
 
 /* -------------------------------------------------------------------------- */
 template <>
 inline void
 Mesh::sendEvent<RemovedElementsEvent>(RemovedElementsEvent & event) {
   this->connectivities.onElementsRemoved(event.getNewNumbering());
   this->fillNodesToElements();
   this->computeBoundingBox();
 
   EventHandlerManager<MeshEventHandler>::sendEvent(event);
 }
 
 /* -------------------------------------------------------------------------- */
 template <>
 inline void Mesh::sendEvent<RemovedNodesEvent>(RemovedNodesEvent & event) {
   const auto & new_numbering = event.getNewNumbering();
   this->removeNodesFromArray(*nodes, new_numbering);
   if (nodes_global_ids)
     this->removeNodesFromArray(*nodes_global_ids, new_numbering);
   if (nodes_type.size() != 0)
     this->removeNodesFromArray(nodes_type, new_numbering);
 
   if (not nodes_to_elements.empty()) {
     std::vector<std::unique_ptr<std::set<Element>>> tmp(
         nodes_to_elements.size());
     auto it = nodes_to_elements.begin();
 
     UInt new_nb_nodes = 0;
     for (auto new_i : new_numbering) {
       if (new_i != UInt(-1)) {
         tmp[new_i] = std::move(*it);
         ++new_nb_nodes;
       }
       ++it;
     }
 
     tmp.resize(new_nb_nodes);
     std::move(tmp.begin(), tmp.end(), nodes_to_elements.begin());
   }
 
   computeBoundingBox();
 
   EventHandlerManager<MeshEventHandler>::sendEvent(event);
 }
 
 /* -------------------------------------------------------------------------- */
 template <typename T>
 inline void Mesh::removeNodesFromArray(Array<T> & vect,
                                        const Array<UInt> & new_numbering) {
   Array<T> tmp(vect.size(), vect.getNbComponent());
   UInt nb_component = vect.getNbComponent();
   UInt new_nb_nodes = 0;
   for (UInt i = 0; i < new_numbering.size(); ++i) {
     UInt new_i = new_numbering(i);
     if (new_i != UInt(-1)) {
       T * to_copy = vect.storage() + i * nb_component;
       std::uninitialized_copy(to_copy, to_copy + nb_component,
                               tmp.storage() + new_i * nb_component);
       ++new_nb_nodes;
     }
   }
 
   tmp.resize(new_nb_nodes);
   vect.copy(tmp);
 }
 
 /* -------------------------------------------------------------------------- */
 inline Array<UInt> & Mesh::getNodesGlobalIdsPointer() {
   AKANTU_DEBUG_IN();
   if (not nodes_global_ids) {
     nodes_global_ids = std::make_unique<Array<UInt>>(
         nodes->size(), 1, getID() + ":nodes_global_ids");
 
     for (auto && global_ids : enumerate(*nodes_global_ids)) {
       std::get<1>(global_ids) = std::get<0>(global_ids);
     }
   }
 
   AKANTU_DEBUG_OUT();
   return *nodes_global_ids;
 }
 
 /* -------------------------------------------------------------------------- */
 inline Array<NodeType> & Mesh::getNodesTypePointer() {
   AKANTU_DEBUG_IN();
   if (nodes_type.size() == 0) {
     nodes_type.resize(nodes->size());
     nodes_type.set(_nt_normal);
   }
 
   AKANTU_DEBUG_OUT();
   return nodes_type;
 }
 
 /* -------------------------------------------------------------------------- */
 inline Array<UInt> &
 Mesh::getConnectivityPointer(const ElementType & type,
                              const GhostType & ghost_type) {
   if (connectivities.exists(type, ghost_type))
     return connectivities(type, ghost_type);
 
   if (ghost_type != _not_ghost) {
     ghosts_counters.alloc(0, 1, type, ghost_type, 1);
   }
 
   AKANTU_DEBUG_INFO("The connectivity vector for the type " << type
                                                             << " created");
 
   UInt nb_nodes_per_element = Mesh::getNbNodesPerElement(type);
   return connectivities.alloc(0, nb_nodes_per_element, type, ghost_type);
 }
 
 /* -------------------------------------------------------------------------- */
 inline Array<std::vector<Element>> &
 Mesh::getElementToSubelementPointer(const ElementType & type,
                                     const GhostType & ghost_type) {
   return getDataPointer<std::vector<Element>>("element_to_subelement", type,
                                               ghost_type, 1, true);
 }
 
 /* -------------------------------------------------------------------------- */
 inline Array<Element> &
 Mesh::getSubelementToElementPointer(const ElementType & type,
                                     const GhostType & ghost_type) {
   auto & array = getDataPointer<Element>(
       "subelement_to_element", type, ghost_type, getNbFacetsPerElement(type),
       true, is_mesh_facets);
   array.set(ElementNull);
   return array;
 }
 
 /* -------------------------------------------------------------------------- */
 inline const auto & Mesh::getElementToSubelement() const {
   return getData<std::vector<Element>>("element_to_subelement");
 }
 
 /* -------------------------------------------------------------------------- */
 inline const auto &
 Mesh::getElementToSubelement(const ElementType & type,
                              const GhostType & ghost_type) const {
   return getData<std::vector<Element>>("element_to_subelement", type,
                                        ghost_type);
 }
 
 /* -------------------------------------------------------------------------- */
 inline auto & Mesh::getElementToSubelement(const ElementType & type,
                                            const GhostType & ghost_type) {
   return getData<std::vector<Element>>("element_to_subelement", type,
                                        ghost_type);
 }
 
 /* -------------------------------------------------------------------------- */
 inline const auto &
 Mesh::getSubelementToElement(const ElementType & type,
                              const GhostType & ghost_type) const {
   return getData<Element>("subelement_to_element", type, ghost_type);
 }
 
 /* -------------------------------------------------------------------------- */
 inline auto & Mesh::getSubelementToElement(const ElementType & type,
                                            const GhostType & ghost_type) {
   return getData<Element>("subelement_to_element", type, ghost_type);
 }
 
 /* -------------------------------------------------------------------------- */
 template <typename T>
 inline Array<T> &
 Mesh::getDataPointer(const ID & data_name, const ElementType & el_type,
                      const GhostType & ghost_type, UInt nb_component,
                      bool size_to_nb_element, bool resize_with_parent) {
   Array<T> & tmp = mesh_data.getElementalDataArrayAlloc<T>(
       data_name, el_type, ghost_type, nb_component);
 
   if (size_to_nb_element) {
     if (resize_with_parent)
       tmp.resize(mesh_parent->getNbElement(el_type, ghost_type));
     else
       tmp.resize(this->getNbElement(el_type, ghost_type));
   } else {
     tmp.resize(0);
   }
 
   return tmp;
 }
 
 /* -------------------------------------------------------------------------- */
 template <typename T>
 inline bool Mesh::hasData(const ID & data_name, const ElementType & el_type,
                           const GhostType & ghost_type) const {
   return mesh_data.hasDataArray<T>(data_name, el_type, ghost_type);
 }
 
 /* -------------------------------------------------------------------------- */
 template <typename T>
 inline const Array<T> & Mesh::getData(const ID & data_name,
                                       const ElementType & el_type,
                                       const GhostType & ghost_type) const {
   return mesh_data.getElementalDataArray<T>(data_name, el_type, ghost_type);
 }
 
 /* -------------------------------------------------------------------------- */
 template <typename T>
 inline Array<T> & Mesh::getData(const ID & data_name,
                                 const ElementType & el_type,
                                 const GhostType & ghost_type) {
   return mesh_data.getElementalDataArray<T>(data_name, el_type, ghost_type);
 }
 
 /* -------------------------------------------------------------------------- */
 inline bool Mesh::hasData(const ID & data_name) const {
   return mesh_data.hasData(data_name);
 }
 
 /* -------------------------------------------------------------------------- */
 template <typename T>
 inline const ElementTypeMapArray<T> &
 Mesh::getData(const ID & data_name) const {
   return mesh_data.getElementalData<T>(data_name);
 }
 
 /* -------------------------------------------------------------------------- */
 template <typename T>
 inline ElementTypeMapArray<T> & Mesh::getData(const ID & data_name) {
   return mesh_data.getElementalData<T>(data_name);
 }
 
 /* -------------------------------------------------------------------------- */
 template <typename T>
 inline ElementTypeMapArray<T> & Mesh::registerData(const ID & data_name) {
   this->mesh_data.registerElementalData<T>(data_name);
   return this->getData<T>(data_name);
 }
 
 /* -------------------------------------------------------------------------- */
 inline UInt Mesh::getNbElement(const ElementType & type,
                                const GhostType & ghost_type) const {
   try {
 
     const Array<UInt> & conn = connectivities(type, ghost_type);
     return conn.size();
   } catch (...) {
     return 0;
   }
 }
 
 /* -------------------------------------------------------------------------- */
 inline UInt Mesh::getNbElement(const UInt spatial_dimension,
                                const GhostType & ghost_type,
                                const ElementKind & kind) const {
   AKANTU_DEBUG_ASSERT(spatial_dimension <= 3 || spatial_dimension == UInt(-1),
                       "spatial_dimension is " << spatial_dimension
                                               << " and is greater than 3 !");
   UInt nb_element = 0;
 
   for (auto type : elementTypes(spatial_dimension, ghost_type, kind))
     nb_element += getNbElement(type, ghost_type);
 
   return nb_element;
 }
 
 /* -------------------------------------------------------------------------- */
 inline void Mesh::getBarycenter(UInt element, const ElementType & type,
                                 Real * barycenter, GhostType ghost_type) const {
   UInt * conn_val = getConnectivity(type, ghost_type).storage();
   UInt nb_nodes_per_element = getNbNodesPerElement(type);
 
   auto * local_coord = new Real[spatial_dimension * nb_nodes_per_element];
 
   UInt offset = element * nb_nodes_per_element;
   for (UInt n = 0; n < nb_nodes_per_element; ++n) {
     memcpy(local_coord + n * spatial_dimension,
            nodes->storage() + conn_val[offset + n] * spatial_dimension,
            spatial_dimension * sizeof(Real));
   }
 
   Math::barycenter(local_coord, nb_nodes_per_element, spatial_dimension,
                    barycenter);
 
   delete[] local_coord;
 }
 
 /* -------------------------------------------------------------------------- */
 inline void Mesh::getBarycenter(const Element & element,
                                 Vector<Real> & barycenter) const {
   getBarycenter(element.element, element.type, barycenter.storage(),
                 element.ghost_type);
 }
 
 /* -------------------------------------------------------------------------- */
 inline UInt Mesh::getNbNodesPerElement(const ElementType & type) {
   UInt nb_nodes_per_element = 0;
 #define GET_NB_NODES_PER_ELEMENT(type)                                         \
   nb_nodes_per_element = ElementClass<type>::getNbNodesPerElement()
   AKANTU_BOOST_ALL_ELEMENT_SWITCH(GET_NB_NODES_PER_ELEMENT);
 #undef GET_NB_NODES_PER_ELEMENT
   return nb_nodes_per_element;
 }
 
 /* -------------------------------------------------------------------------- */
 inline ElementType Mesh::getP1ElementType(const ElementType & type) {
   ElementType p1_type = _not_defined;
 #define GET_P1_TYPE(type) p1_type = ElementClass<type>::getP1ElementType()
 
   AKANTU_BOOST_ALL_ELEMENT_SWITCH(GET_P1_TYPE);
 #undef GET_P1_TYPE
   return p1_type;
 }
 
 /* -------------------------------------------------------------------------- */
 inline ElementKind Mesh::getKind(const ElementType & type) {
   ElementKind kind = _ek_not_defined;
 #define GET_KIND(type) kind = ElementClass<type>::getKind()
   AKANTU_BOOST_ALL_ELEMENT_SWITCH(GET_KIND);
 #undef GET_KIND
   return kind;
 }
 
 /* -------------------------------------------------------------------------- */
 inline UInt Mesh::getSpatialDimension(const ElementType & type) {
   UInt spatial_dimension = 0;
 #define GET_SPATIAL_DIMENSION(type)                                            \
   spatial_dimension = ElementClass<type>::getSpatialDimension()
   AKANTU_BOOST_ALL_ELEMENT_SWITCH(GET_SPATIAL_DIMENSION);
 #undef GET_SPATIAL_DIMENSION
 
   return spatial_dimension;
 }
 
 /* -------------------------------------------------------------------------- */
 inline UInt Mesh::getNbFacetTypes(const ElementType & type,
                                   __attribute__((unused)) UInt t) {
   UInt nb = 0;
 #define GET_NB_FACET_TYPE(type) nb = ElementClass<type>::getNbFacetTypes()
 
   AKANTU_BOOST_ALL_ELEMENT_SWITCH(GET_NB_FACET_TYPE);
 #undef GET_NB_FACET_TYPE
   return nb;
 }
 
 /* -------------------------------------------------------------------------- */
 inline constexpr auto Mesh::getFacetType(const ElementType & type, UInt t) {
 #define GET_FACET_TYPE(type) return ElementClass<type>::getFacetType(t);
 
   AKANTU_BOOST_ALL_ELEMENT_SWITCH_NO_DEFAULT(GET_FACET_TYPE);
 
 #undef GET_FACET_TYPE
 
   return _not_defined;
 }
 
 /* -------------------------------------------------------------------------- */
 inline constexpr auto Mesh::getAllFacetTypes(const ElementType & type) {
 #define GET_FACET_TYPE(type) return ElementClass<type>::getFacetTypes();
 
   AKANTU_BOOST_ALL_ELEMENT_SWITCH_NO_DEFAULT(GET_FACET_TYPE);
 #undef GET_FACET_TYPE
 
   return ElementClass<_not_defined>::getFacetTypes();
 }
 
 /* -------------------------------------------------------------------------- */
 inline UInt Mesh::getNbFacetsPerElement(const ElementType & type) {
   AKANTU_DEBUG_IN();
 
   UInt n_facet = 0;
 #define GET_NB_FACET(type) n_facet = ElementClass<type>::getNbFacetsPerElement()
 
   AKANTU_BOOST_ALL_ELEMENT_SWITCH(GET_NB_FACET);
 #undef GET_NB_FACET
 
   AKANTU_DEBUG_OUT();
   return n_facet;
 }
 
 /* -------------------------------------------------------------------------- */
 inline UInt Mesh::getNbFacetsPerElement(const ElementType & type, UInt t) {
   AKANTU_DEBUG_IN();
 
   UInt n_facet = 0;
 #define GET_NB_FACET(type)                                                     \
   n_facet = ElementClass<type>::getNbFacetsPerElement(t)
 
   AKANTU_BOOST_ALL_ELEMENT_SWITCH(GET_NB_FACET);
 #undef GET_NB_FACET
 
   AKANTU_DEBUG_OUT();
   return n_facet;
 }
 
 /* -------------------------------------------------------------------------- */
 inline auto Mesh::getFacetLocalConnectivity(const ElementType & type, UInt t) {
   AKANTU_DEBUG_IN();
 
 #define GET_FACET_CON(type)                                                    \
   AKANTU_DEBUG_OUT();                                                          \
   return ElementClass<type>::getFacetLocalConnectivityPerElement(t)
 
   AKANTU_BOOST_ALL_ELEMENT_SWITCH(GET_FACET_CON);
 #undef GET_FACET_CON
 
   AKANTU_DEBUG_OUT();
   return ElementClass<_not_defined>::getFacetLocalConnectivityPerElement(0);
   // This avoid a compilation warning but will certainly
   // also cause a segfault if reached
 }
 
 /* -------------------------------------------------------------------------- */
 inline auto Mesh::getFacetConnectivity(const Element & element, UInt t) const {
   AKANTU_DEBUG_IN();
 
   Matrix<const UInt> local_facets(getFacetLocalConnectivity(element.type, t));
   Matrix<UInt> facets(local_facets.rows(), local_facets.cols());
 
   const Array<UInt> & conn = connectivities(element.type, element.ghost_type);
 
   for (UInt f = 0; f < facets.rows(); ++f) {
     for (UInt n = 0; n < facets.cols(); ++n) {
       facets(f, n) = conn(element.element, local_facets(f, n));
     }
   }
 
   AKANTU_DEBUG_OUT();
   return facets;
 }
 
 /* -------------------------------------------------------------------------- */
 template <typename T>
 inline void Mesh::extractNodalValuesFromElement(
     const Array<T> & nodal_values, T * local_coord, UInt * connectivity,
     UInt n_nodes, UInt nb_degree_of_freedom) const {
   for (UInt n = 0; n < n_nodes; ++n) {
     memcpy(local_coord + n * nb_degree_of_freedom,
            nodal_values.storage() + connectivity[n] * nb_degree_of_freedom,
            nb_degree_of_freedom * sizeof(T));
   }
 }
 
 /* -------------------------------------------------------------------------- */
 inline void Mesh::addConnectivityType(const ElementType & type,
                                       const GhostType & ghost_type) {
   getConnectivityPointer(type, ghost_type);
 }
 
 /* -------------------------------------------------------------------------- */
 inline bool Mesh::isPureGhostNode(UInt n) const {
   return nodes_type.size() ? (nodes_type(n) == _nt_pure_gost) : false;
 }
 
 /* -------------------------------------------------------------------------- */
 inline bool Mesh::isLocalOrMasterNode(UInt n) const {
   return nodes_type.size()
              ? (nodes_type(n) == _nt_master) || (nodes_type(n) == _nt_normal)
              : true;
 }
 
 /* -------------------------------------------------------------------------- */
 inline bool Mesh::isLocalNode(UInt n) const {
   return nodes_type.size() ? nodes_type(n) == _nt_normal : true;
 }
 
 /* -------------------------------------------------------------------------- */
 inline bool Mesh::isMasterNode(UInt n) const {
   return nodes_type.size() ? nodes_type(n) == _nt_master : false;
 }
 
 /* -------------------------------------------------------------------------- */
 inline bool Mesh::isSlaveNode(UInt n) const {
   return nodes_type.size() ? nodes_type(n) >= 0 : false;
 }
 
 /* -------------------------------------------------------------------------- */
 inline NodeType Mesh::getNodeType(UInt local_id) const {
   return nodes_type.size() ? nodes_type(local_id) : _nt_normal;
 }
 
 /* -------------------------------------------------------------------------- */
 inline UInt Mesh::getNodeGlobalId(UInt local_id) const {
   return nodes_global_ids ? (*nodes_global_ids)(local_id) : local_id;
 }
 
 /* -------------------------------------------------------------------------- */
 inline UInt Mesh::getNodeLocalId(UInt global_id) const {
   AKANTU_DEBUG_ASSERT(nodes_global_ids != nullptr,
                       "The global ids are note set.");
   return nodes_global_ids->find(global_id);
 }
 
 /* -------------------------------------------------------------------------- */
 inline UInt Mesh::getNbGlobalNodes() const {
   return nodes_global_ids ? nb_global_nodes : nodes->size();
 }
 
 /* -------------------------------------------------------------------------- */
 inline UInt Mesh::getNbNodesPerElementList(const Array<Element> & elements) {
   UInt nb_nodes_per_element = 0;
   UInt nb_nodes = 0;
   ElementType current_element_type = _not_defined;
 
   Array<Element>::const_iterator<Element> el_it = elements.begin();
   Array<Element>::const_iterator<Element> el_end = elements.end();
 
   for (; el_it != el_end; ++el_it) {
     const Element & el = *el_it;
 
     if (el.type != current_element_type) {
       current_element_type = el.type;
       nb_nodes_per_element = Mesh::getNbNodesPerElement(current_element_type);
     }
 
     nb_nodes += nb_nodes_per_element;
   }
 
   return nb_nodes;
 }
 
 /* -------------------------------------------------------------------------- */
 inline Mesh & Mesh::getMeshFacets() {
   if (!this->mesh_facets)
     AKANTU_SILENT_EXCEPTION(
         "No facet mesh is defined yet! check the buildFacets functions");
 
   return *this->mesh_facets;
 }
 
 /* -------------------------------------------------------------------------- */
 inline const Mesh & Mesh::getMeshFacets() const {
   if (!this->mesh_facets)
     AKANTU_SILENT_EXCEPTION(
         "No facet mesh is defined yet! check the buildFacets functions");
 
   return *this->mesh_facets;
 }
 /* -------------------------------------------------------------------------- */
 inline const Mesh & Mesh::getMeshParent() const {
   if (!this->mesh_parent)
     AKANTU_SILENT_EXCEPTION(
         "No parent mesh is defined! This is only valid in a mesh_facets");
 
   return *this->mesh_parent;
 }
 
 /* -------------------------------------------------------------------------- */
 
 } // namespace akantu
 
 #endif /* __AKANTU_MESH_INLINE_IMPL_CC__ */
diff --git a/src/mesh/mesh_iterators.hh b/src/mesh/mesh_iterators.hh
index 3d040e6a7..270f5a1fc 100644
--- a/src/mesh/mesh_iterators.hh
+++ b/src/mesh/mesh_iterators.hh
@@ -1,302 +1,303 @@
 /**
-
  * @file   mesh_iterators.hh
  *
- * @author Nicolas Richart
+ * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
- * @date creation  Wed Aug 09 2017
+ * @date creation: Thu Jul 16 2015
+ * @date last modification: Wed Jan 31 2018
  *
- * @brief Set of helper classes to have fun with range based for
+ * @brief  Set of helper classes to have fun with range based for
  *
  * @section LICENSE
  *
- * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * Copyright (©) 2015-2018 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
- * terms  of the  GNU Lesser  General Public  License as  published by  the Free
+ * 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
+ * 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_named_argument.hh"
 #include "aka_static_if.hh"
 #include "mesh.hh"
 /* -------------------------------------------------------------------------- */
 
 #ifndef __AKANTU_MESH_ITERATORS_HH__
 #define __AKANTU_MESH_ITERATORS_HH__
 
 namespace akantu {
 
 class MeshElementsByTypes {
   using elements_iterator = Array<Element>::scalar_iterator;
 
 public:
   explicit MeshElementsByTypes(const Array<Element> & elements) {
     this->elements.copy(elements);
     std::sort(this->elements.begin(), this->elements.end());
   }
 
   /* ------------------------------------------------------------------------ */
   class MeshElementsRange {
   public:
     MeshElementsRange() = default;
 
     MeshElementsRange(const elements_iterator & begin,
                       const elements_iterator & end)
         : type((*begin).type), ghost_type((*begin).ghost_type), begin(begin),
           end(end) {}
 
     AKANTU_GET_MACRO(Type, type, const ElementType &);
     AKANTU_GET_MACRO(GhostType, ghost_type, const GhostType &);
 
     const Array<UInt> & getElements() {
       elements.resize(end - begin);
       auto el_it = elements.begin();
       for (auto it = begin; it != end; ++it, ++el_it) {
         *el_it = it->element;
       }
 
       return elements;
     }
 
   private:
     ElementType type{_not_defined};
     GhostType ghost_type{_casper};
     elements_iterator begin;
     elements_iterator end;
     Array<UInt> elements;
   };
 
   /* ------------------------------------------------------------------------ */
   class iterator {
     struct element_comparator {
       bool operator()(const Element & lhs, const Element & rhs) const {
         return ((rhs == ElementNull) ||
                 std::tie(lhs.ghost_type, lhs.type) <
                     std::tie(rhs.ghost_type, rhs.type));
       }
     };
 
   public:
     iterator(const iterator &) = default;
     iterator(const elements_iterator & first, const elements_iterator & last)
         : range(std::equal_range(first, last, *first, element_comparator())),
           first(first), last(last) {}
 
     decltype(auto) operator*() const {
       return MeshElementsRange(range.first, range.second);
     }
 
     iterator operator++() {
       first = range.second;
       range = std::equal_range(first, last, *first, element_comparator());
       return *this;
     }
 
     bool operator==(const iterator & other) const {
       return (first == other.first and last == other.last);
     }
 
     bool operator!=(const iterator & other) const {
       return (not operator==(other));
     }
 
   private:
     std::pair<elements_iterator, elements_iterator> range;
     elements_iterator first;
     elements_iterator last;
   };
 
   iterator begin() { return iterator(elements.begin(), elements.end()); }
   iterator end() { return iterator(elements.end(), elements.end()); }
 
 private:
   Array<Element> elements;
 };
 
 /* -------------------------------------------------------------------------- */
 namespace mesh_iterators {
   namespace details {
     template <class internal_iterator> class delegated_iterator {
     public:
       using value_type = std::remove_pointer_t<
           typename internal_iterator::value_type::second_type>;
       using difference_type = std::ptrdiff_t;
       using pointer = value_type *;
       using reference = value_type &;
       using iterator_category = std::input_iterator_tag;
 
       explicit delegated_iterator(internal_iterator it) : it(std::move(it)) {}
 
       decltype(auto) operator*() {
         return std::forward<decltype(*(it->second))>(*(it->second));
       }
 
       delegated_iterator operator++() {
         ++it;
         return *this;
       }
 
       bool operator==(const delegated_iterator & other) const {
         return other.it == it;
       }
 
       bool operator!=(const delegated_iterator & other) const {
         return other.it != it;
       }
 
     private:
       internal_iterator it;
     };
 
     template <class GroupManager> class ElementGroupsIterable {
     public:
       explicit ElementGroupsIterable(GroupManager && group_manager)
           : group_manager(std::forward<GroupManager>(group_manager)) {}
 
       size_t size() { return group_manager.getNbElementGroups(); }
       decltype(auto) begin() {
         return delegated_iterator<decltype(
             group_manager.element_group_begin())>(
             group_manager.element_group_begin());
       }
 
       decltype(auto) begin() const {
         return delegated_iterator<decltype(
             group_manager.element_group_begin())>(
             group_manager.element_group_begin());
       }
 
       decltype(auto) end() {
         return delegated_iterator<decltype(group_manager.element_group_end())>(
             group_manager.element_group_end());
       }
 
       decltype(auto) end() const {
         return delegated_iterator<decltype(group_manager.element_group_end())>(
             group_manager.element_group_end());
       }
 
     private:
       GroupManager && group_manager;
     };
 
     template <class GroupManager> class NodeGroupsIterable {
     public:
       explicit NodeGroupsIterable(GroupManager && group_manager)
           : group_manager(std::forward<GroupManager>(group_manager)) {}
 
       size_t size() { return group_manager.getNbNodeGroups(); }
       decltype(auto) begin() {
         return delegated_iterator<decltype(group_manager.node_group_begin())>(
             group_manager.node_group_begin());
       }
 
       decltype(auto) begin() const {
         return delegated_iterator<decltype(group_manager.node_group_begin())>(
             group_manager.node_group_begin());
       }
 
       decltype(auto) end() {
         return delegated_iterator<decltype(group_manager.node_group_end())>(
             group_manager.node_group_end());
       }
 
       decltype(auto) end() const {
         return delegated_iterator<decltype(group_manager.node_group_end())>(
             group_manager.node_group_end());
       }
 
     private:
       GroupManager && group_manager;
     };
   } // namespace details
 } // namespace mesh_iterators
 
 template <class GroupManager>
 decltype(auto) ElementGroupsIterable(GroupManager && group_manager) {
   return mesh_iterators::details::ElementGroupsIterable<GroupManager>(
       group_manager);
 }
 
 template <class GroupManager>
 decltype(auto) NodeGroupsIterable(GroupManager && group_manager) {
   return mesh_iterators::details::NodeGroupsIterable<GroupManager>(
       group_manager);
 }
 
 /* -------------------------------------------------------------------------- */
 template <class Func>
 void for_each_element(UInt nb_elements, const Array<UInt> & filter_elements,
                       Func && function) {
   if (filter_elements != empty_filter) {
     std::for_each(filter_elements.begin(), filter_elements.end(),
                   std::forward<Func>(function));
   } else {
     auto && range = arange(nb_elements);
     std::for_each(range.begin(), range.end(), std::forward<Func>(function));
   }
 }
 
 namespace {
   DECLARE_NAMED_ARGUMENT(element_filter);
 }
 
 /* -------------------------------------------------------------------------- */
 template <class Func, typename... pack>
 void for_each_element(const Mesh & mesh, Func && function, pack &&... _pack) {
   auto requested_ghost_type = OPTIONAL_NAMED_ARG(ghost_type, _casper);
   const ElementTypeMapArray<UInt> * filter =
       OPTIONAL_NAMED_ARG(element_filter, nullptr);
 
   bool all_ghost_types = requested_ghost_type == _casper;
 
   auto spatial_dimension =
       OPTIONAL_NAMED_ARG(spatial_dimension, mesh.getSpatialDimension());
   auto element_kind = OPTIONAL_NAMED_ARG(element_kind, _ek_not_defined);
 
   for (auto ghost_type : ghost_types) {
     if ((not(ghost_type == requested_ghost_type)) and (not all_ghost_types))
       continue;
 
     auto element_types =
         mesh.elementTypes(spatial_dimension, ghost_type, element_kind);
 
     if (filter) {
       element_types =
           filter->elementTypes(spatial_dimension, ghost_type, element_kind);
     }
 
     for (auto type : element_types) {
       const Array<UInt> * filter_array;
 
       if (filter) {
         filter_array = &((*filter)(type, ghost_type));
       } else {
         filter_array = &empty_filter;
       }
 
       auto nb_elements = mesh.getNbElement(type, ghost_type);
 
       for_each_element(nb_elements, *filter_array, [&](auto && el) {
         auto element = Element{type, el, ghost_type};
         std::forward<Func>(function)(element);
       });
     }
   }
 }
 
 } // namespace akantu
 
 #endif /* __AKANTU_MESH_ITERATORS_HH__ */
diff --git a/src/mesh/node_group.cc b/src/mesh/node_group.cc
index 45ab104a8..5ece1d1d0 100644
--- a/src/mesh/node_group.cc
+++ b/src/mesh/node_group.cc
@@ -1,99 +1,98 @@
 /**
  * @file   node_group.cc
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Fri Jun 18 2010
- * @date last modification: Tue Dec 08 2015
+ * @date last modification: Thu Feb 01 2018
  *
  * @brief  Implementation of the node group
  *
  * @section LICENSE
  *
- * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
- * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
- * Solides)
+ * 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
+ * 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
+ * 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 "node_group.hh"
 #include "dumpable.hh"
 #include "dumpable_inline_impl.hh"
 #include "mesh.hh"
 #if defined(AKANTU_USE_IOHELPER)
 #include "dumper_iohelper_paraview.hh"
 #endif
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 NodeGroup::NodeGroup(const std::string & name, const Mesh & mesh,
                      const std::string & id, const MemoryID & memory_id)
     : Memory(id, memory_id), name(name),
       node_group(alloc<UInt>(std::string(this->id + ":nodes"), 0, 1)) {
 #if defined(AKANTU_USE_IOHELPER)
   this->registerDumper<DumperParaview>("paraview_" + name, name, true);
   this->getDumper().registerField(
       "positions", new dumper::NodalField<Real, true>(mesh.getNodes(), 0, 0,
                                                       &this->getNodes()));
 #endif
 }
 
 /* -------------------------------------------------------------------------- */
 NodeGroup::~NodeGroup() = default;
 
 /* -------------------------------------------------------------------------- */
 void NodeGroup::empty() { node_group.resize(0); }
 
 /* -------------------------------------------------------------------------- */
 void NodeGroup::optimize() {
   std::sort(node_group.begin(), node_group.end());
   Array<UInt>::iterator<> end =
       std::unique(node_group.begin(), node_group.end());
   node_group.resize(end - node_group.begin());
 }
 
 /* -------------------------------------------------------------------------- */
 void NodeGroup::append(const NodeGroup & other_group) {
   AKANTU_DEBUG_IN();
 
   UInt nb_nodes = node_group.size();
 
   /// append new nodes to current list
   node_group.resize(nb_nodes + other_group.node_group.size());
   std::copy(other_group.node_group.begin(), other_group.node_group.end(),
             node_group.begin() + nb_nodes);
 
   optimize();
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void NodeGroup::printself(std::ostream & stream, int indent) const {
   std::string space;
   for (Int i = 0; i < indent; i++, space += AKANTU_INDENT)
     ;
 
   stream << space << "NodeGroup [" << std::endl;
   stream << space << " + name: " << name << std::endl;
   node_group.printself(stream, indent + 1);
   stream << space << "]" << std::endl;
 }
 
 } // akantu
diff --git a/src/mesh/node_group.hh b/src/mesh/node_group.hh
index 8eb5f5d51..f3b36be81 100644
--- a/src/mesh/node_group.hh
+++ b/src/mesh/node_group.hh
@@ -1,132 +1,131 @@
 /**
  * @file   node_group.hh
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Fri Jun 18 2010
- * @date last modification: Tue Dec 08 2015
+ * @date last modification: Wed Nov 08 2017
  *
  * @brief  Node group definition
  *
  * @section LICENSE
  *
- * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
- * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
- * Solides)
+ * 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
+ * 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
+ * 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_array.hh"
 #include "aka_common.hh"
 #include "aka_memory.hh"
 #include "dumpable.hh"
 #include "mesh_filter.hh"
 /* -------------------------------------------------------------------------- */
 
 #ifndef __AKANTU_NODE_GROUP_HH__
 #define __AKANTU_NODE_GROUP_HH__
 
 namespace akantu {
 
 class NodeGroup : public Memory, public Dumpable {
   /* ------------------------------------------------------------------------ */
   /* Constructors/Destructors                                                 */
   /* ------------------------------------------------------------------------ */
 public:
   NodeGroup(const std::string & name, const Mesh & mesh,
             const std::string & id = "node_group",
             const MemoryID & memory_id = 0);
   ~NodeGroup() override;
 
   /* ------------------------------------------------------------------------ */
   /* Methods                                                                  */
   /* ------------------------------------------------------------------------ */
 public:
   using const_node_iterator = Array<UInt>::const_iterator<UInt>;
 
   /// empty the node group
   void empty();
 
   /// iterator to the beginning of the node group
   inline const_node_iterator begin() const;
   /// iterator to the end of the node group
   inline const_node_iterator end() const;
 
   /// add a node and give the local position through an iterator
   inline const_node_iterator add(UInt node, bool check_for_duplicate = true);
 
   /// remove a node
   inline void remove(UInt node);
 
 #ifndef SWIG
   inline decltype(auto) find(UInt node) const { return node_group.find(node); }
 #endif
   /// remove duplicated nodes
   void optimize();
 
   /// append a group to current one
   void append(const NodeGroup & other_group);
 
   /// apply a filter on current node group
   template <typename T> void applyNodeFilter(T & filter);
 
   /// function to print the contain of the class
   virtual void printself(std::ostream & stream, int indent = 0) const;
 
   /* ------------------------------------------------------------------------ */
   /* Accessors                                                                */
   /* ------------------------------------------------------------------------ */
 public:
   AKANTU_GET_MACRO_NOT_CONST(Nodes, node_group, Array<UInt> &);
   AKANTU_GET_MACRO(Nodes, node_group, const Array<UInt> &);
   AKANTU_GET_MACRO(Name, name, const std::string &);
 
   /// give the number of nodes in the current group
   inline UInt size() const;
 
   UInt * storage() { return node_group.storage(); };
 
   /* ------------------------------------------------------------------------ */
   /* Class Members                                                            */
   /* ------------------------------------------------------------------------ */
 private:
   /// name of the group
   std::string name;
 
   /// list of nodes in the group
   Array<UInt> & node_group;
 
   /// reference to the mesh in question
   // const Mesh & mesh;
 };
 
 /// standard output stream operator
 inline std::ostream & operator<<(std::ostream & stream,
                                  const NodeGroup & _this) {
   _this.printself(stream);
   return stream;
 }
 
 } // akantu
 
 /* -------------------------------------------------------------------------- */
 /* inline functions                                                           */
 /* -------------------------------------------------------------------------- */
 
 #include "node_group_inline_impl.cc"
 
 #endif /* __AKANTU_NODE_GROUP_HH__ */
diff --git a/src/mesh/node_group_inline_impl.cc b/src/mesh/node_group_inline_impl.cc
index c165570f9..49665377d 100644
--- a/src/mesh/node_group_inline_impl.cc
+++ b/src/mesh/node_group_inline_impl.cc
@@ -1,99 +1,98 @@
 /**
  * @file   node_group_inline_impl.cc
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Fri Jun 18 2010
- * @date last modification: Tue Dec 08 2015
+ * @date last modification: Sun Aug 13 2017
  *
  * @brief  Node group inline function definitions
  *
  * @section LICENSE
  *
- * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
- * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
- * Solides)
+ * 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
+ * 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
+ * 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/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 inline NodeGroup::const_node_iterator NodeGroup::begin() const {
   return node_group.begin();
 }
 
 /* -------------------------------------------------------------------------- */
 inline NodeGroup::const_node_iterator NodeGroup::end() const {
   return node_group.end();
 }
 
 /* -------------------------------------------------------------------------- */
 inline NodeGroup::const_node_iterator NodeGroup::add(UInt node,
                                                      bool check_for_duplicate) {
   if (check_for_duplicate) {
     const_node_iterator it = std::find(begin(), end(), node);
     if (it == node_group.end()) {
       node_group.push_back(node);
       return (node_group.end() - 1);
     }
     return it;
   } else {
     node_group.push_back(node);
     return (node_group.end() - 1);
   }
 }
 
 /* -------------------------------------------------------------------------- */
 inline void NodeGroup::remove(UInt node) {
   Array<UInt>::iterator<> it = this->node_group.begin();
   Array<UInt>::iterator<> end = this->node_group.end();
   AKANTU_DEBUG_ASSERT(it != end, "The node group is empty!!");
   for (; it != node_group.end(); ++it) {
     if (*it == node) {
       it = node_group.erase(it);
     }
   }
   AKANTU_DEBUG_ASSERT(it != end, "The node was not found!");
 }
 
 /* -------------------------------------------------------------------------- */
 inline UInt NodeGroup::size() const { return node_group.size(); }
 
 /* -------------------------------------------------------------------------- */
 struct FilterFunctor;
 
 template <typename T> void NodeGroup::applyNodeFilter(T & filter) {
   AKANTU_DEBUG_IN();
 
   AKANTU_DEBUG_ASSERT(T::type == FilterFunctor::_node_filter_functor,
                       "NodeFilter can only apply node filter functor");
 
   Array<UInt>::iterator<> it = this->node_group.begin();
 
   for (; it != node_group.end(); ++it) {
     /// filter == true -> keep node
     if (!filter(*it)) {
       it = node_group.erase(it);
     }
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 } // akantu
diff --git a/src/mesh_utils/cohesive_element_inserter.cc b/src/mesh_utils/cohesive_element_inserter.cc
index 7be630cf2..43a36eacb 100644
--- a/src/mesh_utils/cohesive_element_inserter.cc
+++ b/src/mesh_utils/cohesive_element_inserter.cc
@@ -1,281 +1,282 @@
 /**
  * @file   cohesive_element_inserter.cc
  *
  * @author Marco Vocialta <marco.vocialta@epfl.ch>
  *
  * @date creation: Wed Dec 04 2013
- * @date last modification: Sun Oct 04 2015
+ * @date last modification: Mon Feb 19 2018
  *
  * @brief  Cohesive element inserter functions
  *
  * @section LICENSE
  *
- * Copyright  (©)  2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de Lausanne)
+ * 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
+ * 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
+ * A PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
+
 /* -------------------------------------------------------------------------- */
 #include "cohesive_element_inserter.hh"
 #include "communicator.hh"
 #include "element_group.hh"
 #include "global_ids_updater.hh"
 #include "mesh_iterators.hh"
 /* -------------------------------------------------------------------------- */
 #include <algorithm>
 #include <limits>
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 
 CohesiveElementInserter::CohesiveElementInserter(Mesh & mesh, const ID & id)
     : Parsable(ParserType::_cohesive_inserter), id(id), mesh(mesh),
       mesh_facets(mesh.initMeshFacets()),
       insertion_facets("insertion_facets", id),
       insertion_limits(mesh.getSpatialDimension(), 2),
       check_facets("check_facets", id) {
 
   this->registerParam("cohesive_surfaces", physical_groups, _pat_parsable,
                       "List of groups to consider for insertion");
   this->registerParam("bounding_box", insertion_limits, _pat_parsable,
                       "Global limit for insertion");
 
   UInt spatial_dimension = mesh.getSpatialDimension();
 
   MeshUtils::resetFacetToDouble(mesh_facets);
 
   /// init insertion limits
   for (UInt dim = 0; dim < spatial_dimension; ++dim) {
     insertion_limits(dim, 0) = std::numeric_limits<Real>::max() * Real(-1.);
     insertion_limits(dim, 1) = std::numeric_limits<Real>::max();
   }
 
   insertion_facets.initialize(mesh_facets,
                               _spatial_dimension = spatial_dimension - 1,
                               _with_nb_element = true, _default_value = false);
 }
 
 /* -------------------------------------------------------------------------- */
 CohesiveElementInserter::~CohesiveElementInserter() = default;
 
 /* -------------------------------------------------------------------------- */
 void CohesiveElementInserter::parseSection(const ParserSection & section) {
   Parsable::parseSection(section);
 
   if (is_extrinsic)
     limitCheckFacets(this->check_facets);
 }
 
 /* -------------------------------------------------------------------------- */
 void CohesiveElementInserter::limitCheckFacets() {
   limitCheckFacets(this->check_facets);
 }
 
 /* -------------------------------------------------------------------------- */
 void CohesiveElementInserter::setLimit(SpacialDirection axis, Real first_limit,
                                        Real second_limit) {
   AKANTU_DEBUG_ASSERT(
       axis < mesh.getSpatialDimension(),
       "You are trying to limit insertion in a direction that doesn't exist");
 
   insertion_limits(axis, 0) = std::min(first_limit, second_limit);
   insertion_limits(axis, 1) = std::max(first_limit, second_limit);
 }
 
 /* -------------------------------------------------------------------------- */
 UInt CohesiveElementInserter::insertIntrinsicElements() {
   limitCheckFacets(insertion_facets);
   return insertElements();
 }
 
 /* -------------------------------------------------------------------------- */
 void CohesiveElementInserter::limitCheckFacets(
     ElementTypeMapArray<bool> & check_facets) {
   AKANTU_DEBUG_IN();
 
   UInt spatial_dimension = mesh.getSpatialDimension();
 
   check_facets.initialize(mesh_facets,
                           _spatial_dimension = spatial_dimension - 1,
                           _with_nb_element = true, _default_value = true);
   check_facets.set(true);
 
   // remove the pure ghost elements
   for_each_element(
       mesh_facets,
       [&](auto && facet) {
         const auto & element_to_facet = mesh_facets.getElementToSubelement(
             facet.type, facet.ghost_type)(facet.element);
         auto & left = element_to_facet[0];
         auto & right = element_to_facet[1];
         if (right == ElementNull ||
             (left.ghost_type == _ghost && right.ghost_type == _ghost)) {
           check_facets(facet) = false;
           return;
         }
 
         if (left.kind() == _ek_cohesive or right.kind() == _ek_cohesive) {
           check_facets(facet) = false;
         }
       },
       _spatial_dimension = spatial_dimension - 1);
 
   Vector<Real> bary_facet(spatial_dimension);
   // set the limits to the bounding box
   for_each_element(mesh_facets,
                    [&](auto && facet) {
                      auto & need_check = check_facets(facet);
                      if (not need_check)
                        return;
 
                      mesh_facets.getBarycenter(facet, bary_facet);
                      UInt coord_in_limit = 0;
 
                      while (coord_in_limit < spatial_dimension &&
                             bary_facet(coord_in_limit) >
                                 insertion_limits(coord_in_limit, 0) &&
                             bary_facet(coord_in_limit) <
                                 insertion_limits(coord_in_limit, 1))
                        ++coord_in_limit;
 
                      if (coord_in_limit != spatial_dimension)
                        need_check = false;
                    },
                    _spatial_dimension = spatial_dimension - 1);
 
   if (not mesh_facets.hasData("physical_names")) {
     AKANTU_DEBUG_ASSERT(
         physical_groups.size() == 0,
         "No physical names in the mesh but insertion limited to a group");
     AKANTU_DEBUG_OUT();
     return;
   }
 
   const auto & physical_ids =
       mesh_facets.getData<std::string>("physical_names");
 
   // set the limits to the physical surfaces
   for_each_element(mesh_facets,
                    [&](auto && facet) {
                      auto & need_check = check_facets(facet);
                      if (not need_check)
                        return;
 
                      const auto & physical_id = physical_ids(facet);
                      auto it = find(physical_groups.begin(),
                                     physical_groups.end(), physical_id);
 
                      need_check = (it != physical_groups.end());
                    },
                    _spatial_dimension = spatial_dimension - 1);
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 UInt CohesiveElementInserter::insertElements(bool only_double_facets) {
 
   CohesiveNewNodesEvent node_event;
   NewElementsEvent element_event;
 
   Array<UInt> new_pairs(0, 2);
 
   UInt nb_new_elements = MeshUtils::insertCohesiveElements(
       mesh, mesh_facets, insertion_facets, new_pairs, element_event.getList(),
       only_double_facets);
 
   UInt nb_new_nodes = new_pairs.size();
   node_event.getList().reserve(nb_new_nodes);
   node_event.getOldNodesList().reserve(nb_new_nodes);
   for (UInt n = 0; n < nb_new_nodes; ++n) {
     node_event.getList().push_back(new_pairs(n, 1));
     node_event.getOldNodesList().push_back(new_pairs(n, 0));
   }
 
   if (mesh.isDistributed()) {
 
     /// update nodes type
     updateNodesType(mesh, node_event);
     updateNodesType(mesh_facets, node_event);
 
     /// update global ids
     nb_new_nodes = this->updateGlobalIDs(node_event);
 
     /// compute total number of new elements
     const auto & comm = mesh.getCommunicator();
     comm.allReduce(nb_new_elements, SynchronizerOperation::_sum);
   }
 
   if (nb_new_nodes > 0)
     mesh.sendEvent(node_event);
 
   if (nb_new_elements > 0) {
     updateInsertionFacets();
     // mesh.updateTypesOffsets(_not_ghost);
     mesh.sendEvent(element_event);
     MeshUtils::resetFacetToDouble(mesh_facets);
   }
 
   if (mesh.isDistributed()) {
     /// update global ids
     this->synchronizeGlobalIDs(node_event);
   }
 
   return nb_new_elements;
 }
 
 /* -------------------------------------------------------------------------- */
 void CohesiveElementInserter::updateInsertionFacets() {
   AKANTU_DEBUG_IN();
 
   UInt spatial_dimension = mesh.getSpatialDimension();
 
   for (auto && facet_gt : ghost_types) {
     for (auto && facet_type :
          mesh_facets.elementTypes(spatial_dimension - 1, facet_gt)) {
       auto & ins_facets = insertion_facets(facet_type, facet_gt);
 
       // this is the intrinsic case
       if (not is_extrinsic)
         continue;
 
       auto & f_check = check_facets(facet_type, facet_gt);
       for (auto && pair : zip(ins_facets, f_check)) {
         bool & ins = std::get<0>(pair);
         bool & check = std::get<1>(pair);
         if (ins)
           ins = check = false;
       }
     }
   }
 
   // resize for the newly added facets
   insertion_facets.initialize(mesh_facets,
                               _spatial_dimension = spatial_dimension - 1,
                               _with_nb_element = true, _default_value = false);
 
   // resize for the newly added facets
   if (is_extrinsic) {
     check_facets.initialize(mesh_facets,
                             _spatial_dimension = spatial_dimension - 1,
                             _with_nb_element = true, _default_value = false);
   } else {
     insertion_facets.set(false);
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 } // namespace akantu
diff --git a/src/mesh_utils/cohesive_element_inserter.hh b/src/mesh_utils/cohesive_element_inserter.hh
index faa0481e3..688f1888e 100644
--- a/src/mesh_utils/cohesive_element_inserter.hh
+++ b/src/mesh_utils/cohesive_element_inserter.hh
@@ -1,192 +1,194 @@
 /**
  * @file   cohesive_element_inserter.hh
  *
  * @author Fabian Barras <fabian.barras@epfl.ch>
+ * @author Nicolas Richart <nicolas.richart@epfl.ch>
  * @author Marco Vocialta <marco.vocialta@epfl.ch>
  *
  * @date creation: Wed Dec 04 2013
- * @date last modification: Fri Oct 02 2015
+ * @date last modification: Sun Feb 04 2018
  *
  * @brief  Cohesive element inserter
  *
  * @section LICENSE
  *
- * Copyright  (©)  2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de Lausanne)
+ * 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
+ * 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
+ * A PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
+
 /* -------------------------------------------------------------------------- */
 #include "data_accessor.hh"
 #include "mesh_utils.hh"
 #include "parsable.hh"
 /* -------------------------------------------------------------------------- */
 #include <numeric>
 /* -------------------------------------------------------------------------- */
 
 #ifndef __AKANTU_COHESIVE_ELEMENT_INSERTER_HH__
 #define __AKANTU_COHESIVE_ELEMENT_INSERTER_HH__
 
 namespace akantu {
 class GlobalIdsUpdater;
 class FacetSynchronizer;
 } // akantu
 
 namespace akantu {
 
 class CohesiveElementInserter : public DataAccessor<Element>, public Parsable {
   /* ------------------------------------------------------------------------ */
   /* Constructors/Destructors                                                 */
   /* ------------------------------------------------------------------------ */
 public:
   CohesiveElementInserter(Mesh & mesh,
                           const ID & id = "cohesive_element_inserter");
 
   ~CohesiveElementInserter() override;
 
   /* ------------------------------------------------------------------------ */
   /* Methods                                                                  */
   /* ------------------------------------------------------------------------ */
 public:
   /// set range limitation for intrinsic cohesive element insertion
   void setLimit(SpacialDirection axis, Real first_limit, Real second_limit);
 
   /// insert intrinsic cohesive elements in a predefined range
   UInt insertIntrinsicElements();
 
   /// insert extrinsic cohesive elements (returns the number of new
   /// cohesive elements)
   UInt insertElements(bool only_double_facets = false);
 
   /// limit check facets to match given insertion limits
   void limitCheckFacets();
 
 protected:
   /// init parallel variables
   void initParallel(ElementSynchronizer & element_synchronizer);
 
   void parseSection(const ParserSection & section) override;
 
 protected:
   /// internal version of limitCheckFacets
   void limitCheckFacets(ElementTypeMapArray<bool> & check_facets);
 
   /// update facet insertion arrays after facets doubling
   void updateInsertionFacets();
 
   /// update nodes type and global ids for parallel simulations
   /// (locally, within each processor)
   UInt updateGlobalIDs(NewNodesEvent & node_event);
 
   /// synchronize the global ids among the processors in parallel simulations
   void synchronizeGlobalIDs(NewNodesEvent & node_event);
 
   /// update nodes type
   void updateNodesType(Mesh & mesh, NewNodesEvent & node_event);
 
   /// functions for parallel communications
   inline UInt getNbData(const Array<Element> & elements,
                         const SynchronizationTag & tag) const override;
 
   inline void packData(CommunicationBuffer & buffer,
                        const Array<Element> & elements,
                        const SynchronizationTag & tag) const override;
 
   inline void unpackData(CommunicationBuffer & buffer,
                          const Array<Element> & elements,
                          const SynchronizationTag & tag) override;
 
   template <bool pack_mode>
   inline void
   packUnpackGlobalConnectivity(CommunicationBuffer & buffer,
                                const Array<Element> & elements) const;
 
   template <bool pack_mode>
   inline void
   packUnpackGroupedInsertionData(CommunicationBuffer & buffer,
                                  const Array<Element> & elements) const;
   /* ------------------------------------------------------------------------ */
   /* Accessors                                                                */
   /* ------------------------------------------------------------------------ */
 public:
   AKANTU_GET_MACRO_NOT_CONST(InsertionFacetsByElement, insertion_facets,
                              ElementTypeMapArray<bool> &);
   AKANTU_GET_MACRO(InsertionFacetsByElement, insertion_facets,
                    const ElementTypeMapArray<bool> &);
   AKANTU_GET_MACRO_BY_ELEMENT_TYPE(InsertionFacets, insertion_facets, bool);
 
   AKANTU_GET_MACRO(CheckFacets, check_facets,
                    const ElementTypeMapArray<bool> &);
   AKANTU_GET_MACRO_BY_ELEMENT_TYPE(CheckFacets, check_facets, bool);
   AKANTU_GET_MACRO_BY_ELEMENT_TYPE_CONST(CheckFacets, check_facets, bool);
 
   AKANTU_GET_MACRO(MeshFacets, mesh_facets, const Mesh &);
   AKANTU_GET_MACRO_NOT_CONST(MeshFacets, mesh_facets, Mesh &);
 
   AKANTU_SET_MACRO(IsExtrinsic, is_extrinsic, bool);
 
 public:
   friend class SolidMechanicsModelCohesive;
 
   /* ------------------------------------------------------------------------ */
   /* Class Members                                                            */
   /* ------------------------------------------------------------------------ */
 private:
   /// object id
   ID id;
 
   /// main mesh where to insert cohesive elements
   Mesh & mesh;
 
   /// mesh containing facets
   Mesh & mesh_facets;
 
   /// list of facets where to insert elements
   ElementTypeMapArray<bool> insertion_facets;
 
   /// limits for element insertion
   Matrix<Real> insertion_limits;
 
   /// list of groups to consider for insertion, ignored if empty
   std::vector<ID> physical_groups;
 
   /// vector containing facets in which extrinsic cohesive elements can be
   /// inserted
   ElementTypeMapArray<bool> check_facets;
 
   /// global connectivity ids updater
   std::unique_ptr<GlobalIdsUpdater> global_ids_updater;
 
   /// is this inserter used in extrinsic
   bool is_extrinsic{false};
 };
 
 class CohesiveNewNodesEvent : public NewNodesEvent {
 public:
   CohesiveNewNodesEvent() = default;
   ~CohesiveNewNodesEvent() override = default;
 
   AKANTU_GET_MACRO_NOT_CONST(OldNodesList, old_nodes, Array<UInt> &);
   AKANTU_GET_MACRO(OldNodesList, old_nodes, const Array<UInt> &);
 
 private:
   Array<UInt> old_nodes;
 };
 
 } // akantu
 
 #include "cohesive_element_inserter_inline_impl.cc"
 
 #endif /* __AKANTU_COHESIVE_ELEMENT_INSERTER_HH__ */
diff --git a/src/mesh_utils/cohesive_element_inserter_inline_impl.cc b/src/mesh_utils/cohesive_element_inserter_inline_impl.cc
index 65255ff86..d53f12d16 100644
--- a/src/mesh_utils/cohesive_element_inserter_inline_impl.cc
+++ b/src/mesh_utils/cohesive_element_inserter_inline_impl.cc
@@ -1,105 +1,121 @@
 /**
  * @file   cohesive_element_inserter_inline_impl.cc
  *
  * @author Marco Vocialta <marco.vocialta@epfl.ch>
  *
+ * @date creation: Wed Nov 05 2014
+ * @date last modification: Fri Dec 08 2017
  *
  * @brief  Cohesive element inserter inline functions
  *
  * @section LICENSE
  *
- * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * Copyright (©) 2015-2018 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
+ * Akantu is free  software: you can redistribute it and/or  modify it under the
+ * terms  of the  GNU Lesser  General Public  License as published by  the Free
+ * Software Foundation, either version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * Akantu is  distributed in the  hope that it  will be useful, but  WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
+ * details.
+ *
+ * You should  have received  a copy  of the GNU  Lesser General  Public License
+ * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
+ *
  */
+
 /* -------------------------------------------------------------------------- */
 #include "cohesive_element_inserter.hh"
 /* -------------------------------------------------------------------------- */
 
 #ifndef __AKANTU_COHESIVE_ELEMENT_INSERTER_INLINE_IMPL_CC__
 #define __AKANTU_COHESIVE_ELEMENT_INSERTER_INLINE_IMPL_CC__
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 inline UInt
 CohesiveElementInserter::getNbData(const Array<Element> & elements,
                                    const SynchronizationTag & tag) const {
   AKANTU_DEBUG_IN();
 
   UInt size = 0;
 
   if (tag == _gst_ce_groups) {
     size = elements.size() * (sizeof(bool) + sizeof(unsigned int));
   }
 
   AKANTU_DEBUG_OUT();
   return size;
 }
 
 /* -------------------------------------------------------------------------- */
 inline void
 CohesiveElementInserter::packData(CommunicationBuffer & buffer,
                                   const Array<Element> & elements,
                                   const SynchronizationTag & tag) const {
   AKANTU_DEBUG_IN();
   if (tag == _gst_ce_groups)
     packUnpackGroupedInsertionData<true>(buffer, elements);
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 inline void
 CohesiveElementInserter::unpackData(CommunicationBuffer & buffer,
                                     const Array<Element> & elements,
                                     const SynchronizationTag & tag) {
   AKANTU_DEBUG_IN();
   if (tag == _gst_ce_groups)
     packUnpackGroupedInsertionData<false>(buffer, elements);
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <bool pack_mode>
 inline void CohesiveElementInserter::packUnpackGroupedInsertionData(
     CommunicationBuffer & buffer, const Array<Element> & elements) const {
 
   AKANTU_DEBUG_IN();
 
   auto current_element_type = _not_defined;
   auto current_ghost_type = _casper;
   auto & physical_names = mesh_facets.registerData<UInt>("physical_names");
 
   Array<bool> * vect = nullptr;
   Array<UInt> * vect2 = nullptr;
 
   for (const auto & el : elements) {
     if (el.type != current_element_type ||
         el.ghost_type != current_ghost_type) {
       current_element_type = el.type;
       current_ghost_type = el.ghost_type;
       vect =
           &const_cast<Array<bool> &>(insertion_facets(el.type, el.ghost_type));
       vect2 = &(physical_names(el.type, el.ghost_type));
     }
 
     Vector<bool> data(vect->storage() + el.element, 1);
     Vector<unsigned int> data2(vect2->storage() + el.element, 1);
 
     if (pack_mode) {
       buffer << data;
       buffer << data2;
     } else {
       buffer >> data;
       buffer >> data2;
     }
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 } // namespace akantu
 
 #endif /* __AKANTU_COHESIVE_ELEMENT_INSERTER_INLINE_IMPL_CC__ */
diff --git a/src/mesh_utils/cohesive_element_inserter_parallel.cc b/src/mesh_utils/cohesive_element_inserter_parallel.cc
index a8e5cac48..a61281338 100644
--- a/src/mesh_utils/cohesive_element_inserter_parallel.cc
+++ b/src/mesh_utils/cohesive_element_inserter_parallel.cc
@@ -1,77 +1,93 @@
 /**
  * @file   cohesive_element_inserter_parallel.cc
  *
+ * @author Nicolas Richart <nicolas.richart@epfl.ch>
  * @author Marco Vocialta <marco.vocialta@epfl.ch>
  *
+ * @date creation: Wed Nov 05 2014
+ * @date last modification: Fri Dec 08 2017
  *
  * @brief  Parallel functions for the cohesive element inserter
  *
  * @section LICENSE
  *
- * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * Copyright (©) 2015-2018 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
+ * Akantu is free  software: you can redistribute it and/or  modify it under the
+ * terms  of the  GNU Lesser  General Public  License as published by  the Free
+ * Software Foundation, either version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * Akantu is  distributed in the  hope that it  will be useful, but  WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
+ * details.
+ *
+ * You should  have received  a copy  of the GNU  Lesser General  Public License
+ * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
+ *
  */
 
 /* -------------------------------------------------------------------------- */
 #include "cohesive_element_inserter.hh"
 #include "global_ids_updater.hh"
 #include "mesh_accessor.hh"
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 void CohesiveElementInserter::initParallel(ElementSynchronizer & synchronizer) {
   global_ids_updater = std::make_unique<GlobalIdsUpdater>(mesh, synchronizer);
 }
 
 /* -------------------------------------------------------------------------- */
 void CohesiveElementInserter::updateNodesType(Mesh & mesh,
                                               NewNodesEvent & node_event) {
   AKANTU_DEBUG_IN();
 
   auto & cohesive_node_event =
       dynamic_cast<CohesiveNewNodesEvent &>(node_event);
   auto & new_nodes = cohesive_node_event.getList();
   auto & old_nodes = cohesive_node_event.getOldNodesList();
 
   UInt local_nb_new_nodes = new_nodes.size();
 
   MeshAccessor mesh_accessor(mesh);
   auto & nodes_type = mesh_accessor.getNodesType();
   UInt nb_old_nodes = nodes_type.size();
   nodes_type.resize(nb_old_nodes + local_nb_new_nodes);
 
   for (auto && data : zip(old_nodes, new_nodes)) {
     UInt old_node, new_node;
     std::tie(old_node, new_node) = data;
     nodes_type(new_node) = nodes_type(old_node);
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 UInt CohesiveElementInserter::updateGlobalIDs(NewNodesEvent & node_event) {
   AKANTU_DEBUG_IN();
 
   Array<UInt> & doubled_nodes = node_event.getList();
 
   UInt total_nb_new_nodes =
       global_ids_updater->updateGlobalIDsLocally(doubled_nodes.size());
 
   AKANTU_DEBUG_OUT();
   return total_nb_new_nodes;
 }
 
 void CohesiveElementInserter::synchronizeGlobalIDs(
     NewNodesEvent & /*node_event*/) {
   AKANTU_DEBUG_IN();
 
   global_ids_updater->synchronizeGlobalIDs();
 
   AKANTU_DEBUG_OUT();
 }
 
 } // namespace akantu
diff --git a/src/mesh_utils/global_ids_updater.cc b/src/mesh_utils/global_ids_updater.cc
index bd3ae404d..5f0198e60 100644
--- a/src/mesh_utils/global_ids_updater.cc
+++ b/src/mesh_utils/global_ids_updater.cc
@@ -1,57 +1,56 @@
 /**
  * @file   global_ids_updater.cc
  *
  * @author Marco Vocialta <marco.vocialta@epfl.ch>
  *
  * @date creation: Fri Apr 13 2012
- * @date last modification: Fri Oct 02 2015
+ * @date last modification: Fri Dec 08 2017
  *
  * @brief  Functions of the GlobalIdsUpdater
  *
  * @section LICENSE
  *
- * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
- * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
- * Solides)
+ * 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
+ * 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
+ * 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 "global_ids_updater.hh"
 #include "element_synchronizer.hh"
 #include "mesh_utils.hh"
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 
 UInt GlobalIdsUpdater::updateGlobalIDs(UInt old_nb_nodes) {
   UInt total_nb_new_nodes = this->updateGlobalIDsLocally(old_nb_nodes);
 
   this->synchronizeGlobalIDs();
   return total_nb_new_nodes;
 }
 
 UInt GlobalIdsUpdater::updateGlobalIDsLocally(UInt old_nb_nodes) {
   UInt total_nb_new_nodes =
       MeshUtils::updateLocalMasterGlobalConnectivity(mesh, old_nb_nodes);
   return total_nb_new_nodes;
 }
 
 void GlobalIdsUpdater::synchronizeGlobalIDs() {
   this->synchronizer.synchronizeOnce(*this, _gst_giu_global_conn);
 }
 
 } // akantu
diff --git a/src/mesh_utils/global_ids_updater.hh b/src/mesh_utils/global_ids_updater.hh
index bc2b6199a..5869c99b4 100644
--- a/src/mesh_utils/global_ids_updater.hh
+++ b/src/mesh_utils/global_ids_updater.hh
@@ -1,100 +1,102 @@
 /**
  * @file   global_ids_updater.hh
  *
+ * @author Nicolas Richart <nicolas.richart@epfl.ch>
  * @author Marco Vocialta <marco.vocialta@epfl.ch>
  *
  * @date creation: Fri Oct 02 2015
+ * @date last modification: Fri Dec 08 2017
  *
  * @brief  Class that updates the global ids of new nodes that are
  * inserted in the mesh. The functions in this class must be called
  * after updating the node types
  *
  * @section LICENSE
  *
- * Copyright (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne) Laboratory
- * (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * Copyright (©) 2015-2018 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
- * terms  of the  GNU Lesser  General Public  License as  published by  the Free
+ * 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
+ * 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_GLOBAL_IDS_UPDATER_HH__
 #define __AKANTU_GLOBAL_IDS_UPDATER_HH__
 
 /* -------------------------------------------------------------------------- */
 #include "data_accessor.hh"
 /* -------------------------------------------------------------------------- */
 namespace akantu {
 class ElementSynchronizer;
 } // akantu
 
 namespace akantu {
 
 class GlobalIdsUpdater : public DataAccessor<Element> {
 public:
   GlobalIdsUpdater(Mesh & mesh, ElementSynchronizer & synchronizer)
       : mesh(mesh), synchronizer(synchronizer) {}
 
   /// function to update and synchronize the global connectivity of
   /// new inserted nodes. It must be called after updating the node
   /// types. (It calls in sequence the functions
   /// updateGlobalIDsLocally and synchronizeGlobalIDs)
   UInt updateGlobalIDs(UInt old_nb_nodes);
 
   /// function to update the global connectivity (only locally) of new
   /// inserted nodes. It must be called after updating the node types.
   UInt updateGlobalIDsLocally(UInt old_nb_nodes);
 
   /// function to synchronize the global connectivity of new inserted
   /// nodes among the processors. It must be called after updating the
   /// node types.
   void synchronizeGlobalIDs();
 
   /* ------------------------------------------------------------------------ */
   /* Data Accessor inherited members                                          */
   /* ------------------------------------------------------------------------ */
 public:
   inline UInt getNbData(const Array<Element> & elements,
                         const SynchronizationTag & tag) const override;
 
   inline void packData(CommunicationBuffer & buffer,
                        const Array<Element> & elements,
                        const SynchronizationTag & tag) const override;
 
   inline void unpackData(CommunicationBuffer & buffer,
                          const Array<Element> & elements,
                          const SynchronizationTag & tag) override;
   /* ------------------------------------------------------------------------ */
   template <bool pack_mode>
   inline void
   packUnpackGlobalConnectivity(CommunicationBuffer & buffer,
                                const Array<Element> & elements) const;
 
   /* ------------------------------------------------------------------------ */
   /* Members                                                                  */
   /* ------------------------------------------------------------------------ */
 private:
   /// Reference to the mesh to update
   Mesh & mesh;
 
   /// distributed synchronizer to communicate the connectivity
   ElementSynchronizer & synchronizer;
 };
 
 } // akantu
 
 #include "global_ids_updater_inline_impl.cc"
 
 #endif /* __AKANTU_GLOBAL_IDS_UPDATER_HH__ */
diff --git a/src/mesh_utils/global_ids_updater_inline_impl.cc b/src/mesh_utils/global_ids_updater_inline_impl.cc
index 77a4ffe24..4fc0e7b2b 100644
--- a/src/mesh_utils/global_ids_updater_inline_impl.cc
+++ b/src/mesh_utils/global_ids_updater_inline_impl.cc
@@ -1,132 +1,132 @@
 /**
  * @file   global_ids_updater_inline_impl.cc
  *
  * @author Marco Vocialta <marco.vocialta@epfl.ch>
  *
  * @date creation: Fri Oct 02 2015
- * @date last modification: Sun Oct 04 2015
+ * @date last modification: Sun Aug 13 2017
  *
  * @brief  Implementation of the inline functions of GlobalIdsUpdater
  *
  * @section LICENSE
  *
- * Copyright (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne) Laboratory
- * (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * Copyright (©) 2015-2018 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
- * terms  of the  GNU Lesser  General Public  License as  published by  the Free
+ * 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
+ * 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 "global_ids_updater.hh"
 #include "mesh.hh"
 /* -------------------------------------------------------------------------- */
 
 #ifndef __AKANTU_GLOBAL_IDS_UPDATER_INLINE_IMPL_CC__
 #define __AKANTU_GLOBAL_IDS_UPDATER_INLINE_IMPL_CC__
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 inline UInt GlobalIdsUpdater::getNbData(const Array<Element> & elements,
                                         const SynchronizationTag & tag) const {
   UInt size = 0;
   if (elements.size() == 0)
     return size;
 
   if (tag == _gst_giu_global_conn)
     size += Mesh::getNbNodesPerElementList(elements) * sizeof(UInt);
 
   return size;
 }
 
 /* -------------------------------------------------------------------------- */
 inline void GlobalIdsUpdater::packData(CommunicationBuffer & buffer,
                                        const Array<Element> & elements,
                                        const SynchronizationTag & tag) const {
   if (tag == _gst_giu_global_conn)
     packUnpackGlobalConnectivity<true>(buffer, elements);
 }
 
 /* -------------------------------------------------------------------------- */
 inline void GlobalIdsUpdater::unpackData(CommunicationBuffer & buffer,
                                          const Array<Element> & elements,
                                          const SynchronizationTag & tag) {
   if (tag == _gst_giu_global_conn)
     packUnpackGlobalConnectivity<false>(buffer, elements);
 }
 
 /* -------------------------------------------------------------------------- */
 template <bool pack_mode>
 inline void GlobalIdsUpdater::packUnpackGlobalConnectivity(
     CommunicationBuffer & buffer, const Array<Element> & elements) const {
   AKANTU_DEBUG_IN();
 
   ElementType current_element_type = _not_defined;
   GhostType current_ghost_type = _casper;
 
   Array<UInt>::const_vector_iterator conn_begin;
   UInt nb_nodes_per_elem = 0;
   UInt index;
 
   Array<UInt> & global_nodes_ids = mesh.getGlobalNodesIds();
 
   Array<Element>::const_scalar_iterator it = elements.begin();
   Array<Element>::const_scalar_iterator end = elements.end();
   for (; it != end; ++it) {
     const Element & el = *it;
 
     if (el.type != current_element_type ||
         el.ghost_type != current_ghost_type) {
       current_element_type = el.type;
       current_ghost_type = el.ghost_type;
 
       const Array<UInt> & connectivity =
           mesh.getConnectivity(current_element_type, current_ghost_type);
       nb_nodes_per_elem = connectivity.getNbComponent();
       conn_begin = connectivity.begin(nb_nodes_per_elem);
     }
 
     /// get element connectivity
     const Vector<UInt> current_conn = conn_begin[el.element];
 
     /// loop on all connectivity nodes
     for (UInt n = 0; n < nb_nodes_per_elem; ++n) {
       UInt node = current_conn(n);
 
       if (pack_mode) {
         /// if node is local or master pack its global id, otherwise
         /// dummy data
         if (mesh.isLocalOrMasterNode(node))
           index = global_nodes_ids(node);
         else
           index = UInt(-1);
 
         buffer << index;
       } else {
         buffer >> index;
 
         /// update slave nodes' index
         if (index != UInt(-1) && mesh.isSlaveNode(node))
           global_nodes_ids(node) = index;
       }
     }
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 } // akantu
 
 #endif /* __AKANTU_GLOBAL_IDS_UPDATER_INLINE_IMPL_CC__ */
diff --git a/src/mesh_utils/mesh_partition.cc b/src/mesh_utils/mesh_partition.cc
index d7a27e34f..7bb771e62 100644
--- a/src/mesh_utils/mesh_partition.cc
+++ b/src/mesh_utils/mesh_partition.cc
@@ -1,434 +1,433 @@
 /**
  * @file   mesh_partition.cc
  *
  * @author David Simon Kammer <david.kammer@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Tue Aug 17 2010
- * @date last modification: Fri Jan 22 2016
+ * @date last modification: Wed Jan 24 2018
  *
  * @brief  implementation of common part of all partitioner
  *
  * @section LICENSE
  *
- * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
- * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
- * Solides)
+ * 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
+ * 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
+ * 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 "mesh_partition.hh"
 #include "aka_iterators.hh"
 #include "aka_types.hh"
 #include "mesh_accessor.hh"
 #include "mesh_utils.hh"
 /* -------------------------------------------------------------------------- */
 #include <algorithm>
 #include <numeric>
 #include <unordered_map>
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 MeshPartition::MeshPartition(const Mesh & mesh, UInt spatial_dimension,
                              const ID & id, const MemoryID & memory_id)
     : Memory(id, memory_id), mesh(mesh), spatial_dimension(spatial_dimension),
       partitions("partition", id, memory_id),
       ghost_partitions("ghost_partition", id, memory_id),
       ghost_partitions_offset("ghost_partition_offset", id, memory_id),
       saved_connectivity("saved_connectivity", id, memory_id) {
   AKANTU_DEBUG_IN();
 
   UInt nb_total_element = 0;
   for (auto && type :
        mesh.elementTypes(spatial_dimension, _not_ghost, _ek_not_defined)) {
     linearized_offsets.push_back(std::make_pair(type, nb_total_element));
     nb_total_element += mesh.getConnectivity(type).size();
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 MeshPartition::~MeshPartition() = default;
 
 /* -------------------------------------------------------------------------- */
 UInt MeshPartition::linearized(const Element & element) {
   auto it =
       std::find_if(linearized_offsets.begin(), linearized_offsets.end(),
                    [&element](auto & a) { return a.first == element.type; });
   AKANTU_DEBUG_ASSERT(it != linearized_offsets.end(),
                       "A bug might be crawling around this corner...");
   return (it->second + element.element);
 }
 
 /* -------------------------------------------------------------------------- */
 Element MeshPartition::unlinearized(UInt lin_element) {
   ElementType type{_not_defined};
   UInt offset{0};
   for (auto & pair : linearized_offsets) {
     if (lin_element < pair.second)
       continue;
     std::tie(type, offset) = pair;
   }
 
   return Element{type, lin_element - offset, _not_ghost};
 }
 
 /* -------------------------------------------------------------------------- */
 /**
  * TODO this function should most probably be rewritten in a more modern way
  * conversion in c++ of the GENDUALMETIS (mesh.c) function wrote by George in
  * Metis (University of Minnesota)
  */
 void MeshPartition::buildDualGraph(Array<Int> & dxadj, Array<Int> & dadjncy,
                                    Array<Int> & edge_loads,
                                    const EdgeLoadFunctor & edge_load_func) {
   AKANTU_DEBUG_IN();
 
   std::map<ElementType, std::tuple<const Array<UInt> *, UInt, UInt>>
       connectivities;
   UInt spatial_dimension = mesh.getSpatialDimension();
   UInt nb_total_element{0};
 
   for (auto & type :
        mesh.elementTypes(spatial_dimension, _not_ghost, _ek_not_defined)) {
     auto type_p1 = mesh.getP1ElementType(type);
     auto nb_nodes_per_element_p1 = mesh.getNbNodesPerElement(type_p1);
     auto magic_number = mesh.getNbNodesPerElement(mesh.getFacetType(type_p1));
 
     const auto & conn = mesh.getConnectivity(type, _not_ghost);
     connectivities[type] =
         std::make_tuple(&conn, nb_nodes_per_element_p1, magic_number);
     nb_total_element += conn.size();
   }
 
   CSR<Element> node_to_elem;
   MeshUtils::buildNode2Elements(mesh, node_to_elem);
 
   dxadj.resize(nb_total_element + 1);
   /// initialize the dxadj array
   auto dxadj_it = dxadj.begin();
   for (auto & pair : connectivities) {
     const auto & connectivity = *std::get<0>(pair.second);
     auto nb_nodes_per_element_p1 = std::get<1>(pair.second);
 
     std::fill_n(dxadj_it, connectivity.size(), nb_nodes_per_element_p1);
     dxadj_it += connectivity.size();
   }
 
   /// convert the dxadj_val array in a csr one
   for (UInt i = 1; i < nb_total_element; ++i)
     dxadj(i) += dxadj(i - 1);
   for (UInt i = nb_total_element; i > 0; --i)
     dxadj(i) = dxadj(i - 1);
   dxadj(0) = 0;
 
   dadjncy.resize(2 * dxadj(nb_total_element));
   edge_loads.resize(2 * dxadj(nb_total_element));
 
   /// weight map to determine adjacency
   std::unordered_map<UInt, UInt> weight_map;
 
   for (auto & pair : connectivities) {
     auto type = pair.first;
     const auto & connectivity = *std::get<0>(pair.second);
     auto nb_nodes_per_element = std::get<1>(pair.second);
     auto magic_number = std::get<2>(pair.second);
 
     Element element{type, 0, _not_ghost};
 
     for (const auto & conn :
          make_view(connectivity, connectivity.getNbComponent())) {
       auto linearized_el = linearized(element);
 
       /// fill the weight map
       for (UInt n : arange(nb_nodes_per_element)) {
         auto && node = conn(n);
         for (auto k = node_to_elem.rbegin(node); k != node_to_elem.rend(node);
              --k) {
           auto & current_element = *k;
           auto current_el = linearized(current_element);
           AKANTU_DEBUG_ASSERT(current_el != UInt(-1),
                               "Linearized element not found");
           if (current_el <= linearized_el)
             break;
 
           auto weight_map_insert =
               weight_map.insert(std::make_pair(current_el, 1));
           if (not weight_map_insert.second)
             (weight_map_insert.first->second)++;
         }
       }
 
       /// each element with a weight of the size of a facet are adjacent
       for (auto & weight_pair : weight_map) {
         auto & adjacent_el = weight_pair.first;
         auto magic = weight_pair.second;
         if (magic != magic_number)
           continue;
 
 #if defined(AKANTU_COHESIVE_ELEMENT)
         /// Patch in order to prevent neighboring cohesive elements
         /// from detecting each other
         auto adjacent_element = unlinearized(adjacent_el);
 
         auto el_kind = element.kind();
         auto adjacent_el_kind = adjacent_element.kind();
 
         if (el_kind == adjacent_el_kind && el_kind == _ek_cohesive)
           continue;
 #endif
         UInt index_adj = dxadj(adjacent_el)++;
         UInt index_lin = dxadj(linearized_el)++;
 
         dadjncy(index_lin) = adjacent_el;
         dadjncy(index_adj) = linearized_el;
       }
 
       element.element++;
       weight_map.clear();
     }
   }
 
   Int k_start = 0, linerized_el = 0, j = 0;
   for (auto & pair : connectivities) {
     const auto & connectivity = *std::get<0>(pair.second);
     auto nb_nodes_per_element_p1 = std::get<1>(pair.second);
     auto nb_element = connectivity.size();
 
     for (UInt el = 0; el < nb_element; ++el, ++linerized_el) {
       for (Int k = k_start; k < dxadj(linerized_el); ++k, ++j)
         dadjncy(j) = dadjncy(k);
       dxadj(linerized_el) = j;
       k_start += nb_nodes_per_element_p1;
     }
   }
 
   for (UInt i = nb_total_element; i > 0; --i)
     dxadj(i) = dxadj(i - 1);
   dxadj(0) = 0;
 
   UInt adj = 0;
   for (UInt i = 0; i < nb_total_element; ++i) {
     UInt nb_adj = dxadj(i + 1) - dxadj(i);
     for (UInt j = 0; j < nb_adj; ++j, ++adj) {
       Int el_adj_id = dadjncy(dxadj(i) + j);
       Element el = unlinearized(i);
       Element el_adj = unlinearized(el_adj_id);
 
       Int load = edge_load_func(el, el_adj);
       edge_loads(adj) = load;
     }
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void MeshPartition::fillPartitionInformation(
     const Mesh & mesh, const Int * linearized_partitions) {
   AKANTU_DEBUG_IN();
 
   CSR<Element> node_to_elem;
 
   MeshUtils::buildNode2Elements(mesh, node_to_elem);
 
   UInt linearized_el = 0;
   for (auto & type :
        mesh.elementTypes(spatial_dimension, _not_ghost, _ek_not_defined)) {
     UInt nb_element = mesh.getNbElement(type);
     UInt nb_nodes_per_element = Mesh::getNbNodesPerElement(type);
 
     partitions.alloc(nb_element, 1, type, _not_ghost);
     auto & ghost_part_csr = ghost_partitions_csr(type, _not_ghost);
     ghost_part_csr.resizeRows(nb_element);
 
     ghost_partitions_offset.alloc(nb_element + 1, 1, type, _ghost);
     ghost_partitions.alloc(0, 1, type, _ghost);
 
     const Array<UInt> & connectivity = mesh.getConnectivity(type, _not_ghost);
 
     for (UInt el = 0; el < nb_element; ++el, ++linearized_el) {
       UInt part = linearized_partitions[linearized_el];
 
       partitions(type, _not_ghost)(el) = part;
       std::list<UInt> list_adj_part;
       for (UInt n = 0; n < nb_nodes_per_element; ++n) {
         UInt node = connectivity.storage()[el * nb_nodes_per_element + n];
         CSR<Element>::iterator ne;
         for (ne = node_to_elem.begin(node); ne != node_to_elem.end(node);
              ++ne) {
           const Element & adj_element = *ne;
           UInt adj_el = linearized(adj_element);
           UInt adj_part = linearized_partitions[adj_el];
           if (part != adj_part) {
             list_adj_part.push_back(adj_part);
           }
         }
       }
 
       list_adj_part.sort();
       list_adj_part.unique();
 
       for (auto & adj_part : list_adj_part) {
         ghost_part_csr.getRows().push_back(adj_part);
         ghost_part_csr.rowOffset(el)++;
 
         ghost_partitions(type, _ghost).push_back(adj_part);
         ghost_partitions_offset(type, _ghost)(el)++;
       }
     }
 
     ghost_part_csr.countToCSR();
 
     /// convert the ghost_partitions_offset array in an offset array
     Array<UInt> & ghost_partitions_offset_ptr =
         ghost_partitions_offset(type, _ghost);
     for (UInt i = 1; i < nb_element; ++i)
       ghost_partitions_offset_ptr(i) += ghost_partitions_offset_ptr(i - 1);
     for (UInt i = nb_element; i > 0; --i)
       ghost_partitions_offset_ptr(i) = ghost_partitions_offset_ptr(i - 1);
     ghost_partitions_offset_ptr(0) = 0;
   }
 
   // All Facets
   for (Int sp = spatial_dimension - 1; sp >= 0; --sp) {
     for (auto & type : mesh.elementTypes(sp, _not_ghost, _ek_not_defined)) {
       UInt nb_element = mesh.getNbElement(type);
 
       partitions.alloc(nb_element, 1, type, _not_ghost);
       AKANTU_DEBUG_INFO("Allocating partitions for " << type);
       auto & ghost_part_csr = ghost_partitions_csr(type, _not_ghost);
       ghost_part_csr.resizeRows(nb_element);
 
       ghost_partitions_offset.alloc(nb_element + 1, 1, type, _ghost);
       ghost_partitions.alloc(0, 1, type, _ghost);
       AKANTU_DEBUG_INFO("Allocating ghost_partitions for " << type);
       const Array<std::vector<Element>> & elem_to_subelem =
           mesh.getElementToSubelement(type, _not_ghost);
       for (UInt i(0); i < mesh.getNbElement(type, _not_ghost);
            ++i) { // Facet loop
 
         const std::vector<Element> & adjacent_elems = elem_to_subelem(i);
         if (!adjacent_elems.empty()) {
           Element min_elem{_max_element_type, std::numeric_limits<UInt>::max(),
                            *ghost_type_t::end()};
           UInt min_part(std::numeric_limits<UInt>::max());
           std::set<UInt> adjacent_parts;
 
           for (UInt j(0); j < adjacent_elems.size(); ++j) {
             UInt adjacent_elem_id = adjacent_elems[j].element;
             UInt adjacent_elem_part =
                 partitions(adjacent_elems[j].type,
                            adjacent_elems[j].ghost_type)(adjacent_elem_id);
             if (adjacent_elem_part < min_part) {
               min_part = adjacent_elem_part;
               min_elem = adjacent_elems[j];
             }
             adjacent_parts.insert(adjacent_elem_part);
           }
           partitions(type, _not_ghost)(i) = min_part;
 
           auto git = ghost_partitions_csr(min_elem.type, _not_ghost)
                          .begin(min_elem.element);
           auto gend = ghost_partitions_csr(min_elem.type, _not_ghost)
                           .end(min_elem.element);
           for (; git != gend; ++git) {
 
             adjacent_parts.insert(min_part);
           }
           adjacent_parts.erase(min_part);
           for (auto & part : adjacent_parts) {
             ghost_part_csr.getRows().push_back(part);
             ghost_part_csr.rowOffset(i)++;
             ghost_partitions(type, _ghost).push_back(part);
           }
 
           ghost_partitions_offset(type, _ghost)(i + 1) =
               ghost_partitions_offset(type, _ghost)(i + 1) +
               adjacent_elems.size();
         } else {
           partitions(type, _not_ghost)(i) = 0;
         }
       }
       ghost_part_csr.countToCSR();
     }
   }
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void MeshPartition::tweakConnectivity(const Array<UInt> & pairs) {
   AKANTU_DEBUG_IN();
 
   if (pairs.size() == 0)
     return;
 
   Mesh::type_iterator it =
       mesh.firstType(spatial_dimension, _not_ghost, _ek_not_defined);
   Mesh::type_iterator end =
       mesh.lastType(spatial_dimension, _not_ghost, _ek_not_defined);
 
   for (; it != end; ++it) {
     ElementType type = *it;
 
     Array<UInt> & conn =
         const_cast<Array<UInt> &>(mesh.getConnectivity(type, _not_ghost));
     UInt nb_nodes_per_element = conn.getNbComponent();
     UInt nb_element = conn.size();
 
     Array<UInt> & saved_conn = saved_connectivity.alloc(
         nb_element, nb_nodes_per_element, type, _not_ghost);
     saved_conn.copy(conn);
 
     for (UInt i = 0; i < pairs.size(); ++i) {
       for (UInt el = 0; el < nb_element; ++el) {
         for (UInt n = 0; n < nb_nodes_per_element; ++n) {
           if (pairs(i, 1) == conn(el, n))
             conn(el, n) = pairs(i, 0);
         }
       }
     }
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void MeshPartition::restoreConnectivity() {
   AKANTU_DEBUG_IN();
   MeshAccessor mesh_accessor(const_cast<Mesh &>(mesh));
   for (auto && type : saved_connectivity.elementTypes(
            spatial_dimension, _not_ghost, _ek_not_defined)) {
     auto & conn = mesh_accessor.getConnectivity(type, _not_ghost);
     auto & saved_conn = saved_connectivity(type, _not_ghost);
     conn.copy(saved_conn);
   }
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 bool MeshPartition::hasPartitions(const ElementType & type,
                                   const GhostType & ghost_type) {
   return partitions.exists(type, ghost_type);
 }
 
 /* -------------------------------------------------------------------------- */
 
 } // namespace akantu
diff --git a/src/mesh_utils/mesh_partition.hh b/src/mesh_utils/mesh_partition.hh
index 175c8c1ef..bd1b703f9 100644
--- a/src/mesh_utils/mesh_partition.hh
+++ b/src/mesh_utils/mesh_partition.hh
@@ -1,155 +1,154 @@
 /**
  * @file   mesh_partition.hh
  *
  * @author David Simon Kammer <david.kammer@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Fri Jun 18 2010
- * @date last modification: Tue Sep 01 2015
+ * @date last modification: Tue Jan 23 2018
  *
  * @brief  tools to partitionate a mesh
  *
  * @section LICENSE
  *
- * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
- * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
- * Solides)
+ * 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
+ * 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
+ * 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_MESH_PARTITION_HH__
 #define __AKANTU_MESH_PARTITION_HH__
 
 /* -------------------------------------------------------------------------- */
 #include "aka_csr.hh"
 #include "aka_memory.hh"
 #include "mesh.hh"
 
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 
 class MeshPartition : protected Memory {
   /* ------------------------------------------------------------------------ */
   /* Constructors/Destructors                                                 */
   /* ------------------------------------------------------------------------ */
 public:
   MeshPartition(const Mesh & mesh, UInt spatial_dimension,
                 const ID & id = "MeshPartitioner",
                 const MemoryID & memory_id = 0);
 
   ~MeshPartition() override;
 
   class EdgeLoadFunctor {
   public:
     virtual Int operator()(const Element & el1, const Element & el2) const
         noexcept = 0;
   };
 
   class ConstEdgeLoadFunctor : public EdgeLoadFunctor {
   public:
     inline Int operator()(const Element &, const Element &) const
         noexcept override {
       return 1;
     }
   };
 
   /* ------------------------------------------------------------------------ */
   /* Methods                                                                  */
   /* ------------------------------------------------------------------------ */
 public:
   /// define a partition of the mesh
   virtual void
   partitionate(UInt nb_part,
                const EdgeLoadFunctor & edge_load_func = ConstEdgeLoadFunctor(),
                const Array<UInt> & pairs = Array<UInt>()) = 0;
 
   /// reorder the nodes to reduce the filling during the factorization of a
   /// matrix that has a profil based on the connectivity of the mesh
   virtual void reorder() = 0;
 
   /// fill the partitions array with a given linearized partition information
   void fillPartitionInformation(const Mesh & mesh,
                                 const Int * linearized_partitions);
 
 protected:
   /// build the dual graph of the mesh, for all element of spatial_dimension
   void buildDualGraph(Array<Int> & dxadj, Array<Int> & dadjncy,
                       Array<Int> & edge_loads,
                       const EdgeLoadFunctor & edge_load_func);
 
   /// tweak the mesh to handle the PBC pairs
   void tweakConnectivity(const Array<UInt> & pairs);
   /// restore the mesh that has been tweaked
   void restoreConnectivity();
 
   /* ------------------------------------------------------------------------ */
   /* Accessors                                                                */
   /* ------------------------------------------------------------------------ */
 public:
   bool hasPartitions(const ElementType & type, const GhostType & ghost_type);
   AKANTU_GET_MACRO(Partitions, partitions, const ElementTypeMapArray<UInt> &);
   AKANTU_GET_MACRO_BY_ELEMENT_TYPE_CONST(Partition, partitions, UInt);
 
   AKANTU_GET_MACRO(GhostPartitionCSR, ghost_partitions_csr,
                    const ElementTypeMap<CSR<UInt>> &);
 
   AKANTU_GET_MACRO(NbPartition, nb_partitions, UInt);
   AKANTU_SET_MACRO(NbPartition, nb_partitions, UInt);
 
 protected:
   UInt linearized(const Element & element);
   Element unlinearized(UInt lin_element);
   /* ------------------------------------------------------------------------ */
   /* Class Members                                                            */
   /* ------------------------------------------------------------------------ */
 protected:
   /// id
   std::string id;
 
   /// the mesh to partition
   const Mesh & mesh;
 
   /// dimension of the elements to consider in the mesh
   UInt spatial_dimension;
 
   /// number of partitions
   UInt nb_partitions;
 
   /// partition numbers
   ElementTypeMapArray<UInt> partitions;
 
   ElementTypeMap<CSR<UInt>> ghost_partitions_csr;
   ElementTypeMapArray<UInt> ghost_partitions;
   ElementTypeMapArray<UInt> ghost_partitions_offset;
 
   Array<UInt> * permutation;
 
   ElementTypeMapArray<UInt> saved_connectivity;
 
   // vector of pair to ensure the iteration order
   std::vector<std::pair<ElementType, UInt>> linearized_offsets;
 };
 
 } // namespace akantu
 
 #ifdef AKANTU_USE_SCOTCH
 #include "mesh_partition_scotch.hh"
 #endif
 
 #endif /* __AKANTU_MESH_PARTITION_HH__ */
diff --git a/src/mesh_utils/mesh_partition/mesh_partition_mesh_data.cc b/src/mesh_utils/mesh_partition/mesh_partition_mesh_data.cc
index 78d5990bb..aad595cc1 100644
--- a/src/mesh_utils/mesh_partition/mesh_partition_mesh_data.cc
+++ b/src/mesh_utils/mesh_partition/mesh_partition_mesh_data.cc
@@ -1,141 +1,141 @@
 /**
  * @file   mesh_partition_mesh_data.cc
  *
  * @author Dana Christen <dana.christen@epfl.ch>
  * @author David Simon Kammer <david.kammer@epfl.ch>
  *
  * @date creation: Fri May 03 2013
- * @date last modification: Wed Nov 11 2015
+ * @date last modification: Tue Feb 20 2018
  *
  * @brief  implementation of the MeshPartitionMeshData class
  *
  * @section LICENSE
  *
- * Copyright  (©)  2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de Lausanne)
+ * 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
+ * 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
+ * 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 "mesh_partition_mesh_data.hh"
 #if !defined(AKANTU_NDEBUG)
 #include <set>
 #endif
 
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 MeshPartitionMeshData::MeshPartitionMeshData(const Mesh & mesh,
                                              UInt spatial_dimension,
                                              const ID & id,
                                              const MemoryID & memory_id)
     : MeshPartition(mesh, spatial_dimension, id, memory_id) {
   AKANTU_DEBUG_IN();
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 MeshPartitionMeshData::MeshPartitionMeshData(
     const Mesh & mesh, const ElementTypeMapArray<UInt> & mapping,
     UInt spatial_dimension, const ID & id, const MemoryID & memory_id)
     : MeshPartition(mesh, spatial_dimension, id, memory_id),
       partition_mapping(&mapping) {
   AKANTU_DEBUG_IN();
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void MeshPartitionMeshData::partitionate(UInt nb_part,
                                          __attribute__((unused))
                                          const EdgeLoadFunctor & edge_load_func,
                                          const Array<UInt> & pairs) {
   AKANTU_DEBUG_IN();
 
   tweakConnectivity(pairs);
 
   nb_partitions = nb_part;
   GhostType ghost_type = _not_ghost;
   UInt spatial_dimension = mesh.getSpatialDimension();
   Mesh::type_iterator it =
       mesh.firstType(spatial_dimension, ghost_type, _ek_not_defined);
   Mesh::type_iterator end =
       mesh.lastType(spatial_dimension, ghost_type, _ek_not_defined);
 
   UInt linearized_el = 0;
   UInt nb_elements = mesh.getNbElement(mesh.getSpatialDimension(), ghost_type);
   auto * partition_list = new Int[nb_elements];
 
 #if !defined(AKANTU_NDEBUG)
   std::set<UInt> partitions;
 #endif
   for (; it != end; ++it) {
     ElementType type = *it;
     const Array<UInt> & partition_array =
         (*partition_mapping)(type, ghost_type);
     Array<UInt>::const_iterator<Vector<UInt>> p_it = partition_array.begin(1);
     Array<UInt>::const_iterator<Vector<UInt>> p_end = partition_array.end(1);
     AKANTU_DEBUG_ASSERT(UInt(p_end - p_it) ==
                             mesh.getNbElement(type, ghost_type),
                         "The partition mapping does not have the right number "
                             << "of entries for type " << type
                             << " and ghost type " << ghost_type << "."
                             << " Tags=" << p_end - p_it
                             << " Mesh=" << mesh.getNbElement(type, ghost_type));
     for (; p_it != p_end; ++p_it, ++linearized_el) {
       partition_list[linearized_el] = (*p_it)(0);
 #if !defined(AKANTU_NDEBUG)
       partitions.insert((*p_it)(0));
 #endif
     }
   }
 
 #if !defined(AKANTU_NDEBUG)
   AKANTU_DEBUG_ASSERT(partitions.size() == nb_part,
                       "The number of real partitions does not match with the "
                       "number of asked partitions");
 #endif
 
   fillPartitionInformation(mesh, partition_list);
 
   delete[] partition_list;
 
   restoreConnectivity();
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void MeshPartitionMeshData::reorder() { AKANTU_TO_IMPLEMENT(); }
 
 /* -------------------------------------------------------------------------- */
 void MeshPartitionMeshData::setPartitionMapping(
     const ElementTypeMapArray<UInt> & mapping) {
   partition_mapping = &mapping;
 }
 
 /* -------------------------------------------------------------------------- */
 void MeshPartitionMeshData::setPartitionMappingFromMeshData(
     const std::string & data_name) {
   partition_mapping = &(mesh.getData<UInt>(data_name));
 }
 
 } // akantu
diff --git a/src/mesh_utils/mesh_partition/mesh_partition_mesh_data.hh b/src/mesh_utils/mesh_partition/mesh_partition_mesh_data.hh
index d2405af38..efc3a394c 100644
--- a/src/mesh_utils/mesh_partition/mesh_partition_mesh_data.hh
+++ b/src/mesh_utils/mesh_partition/mesh_partition_mesh_data.hh
@@ -1,94 +1,93 @@
 /**
  * @file   mesh_partition_mesh_data.hh
  *
  * @author Dana Christen <dana.christen@epfl.ch>
  *
  * @date creation: Fri Jun 18 2010
- * @date last modification: Sun Oct 19 2014
+ * @date last modification: Wed Nov 08 2017
  *
  * @brief  mesh partitioning based on data provided in the mesh
  *
  * @section LICENSE
  *
- * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
- * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
- * Solides)
+ * 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
+ * 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
+ * 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_MESH_PARTITION_MESH_DATA_HH__
 #define __AKANTU_MESH_PARTITION_MESH_DATA_HH__
 
 /* -------------------------------------------------------------------------- */
 #include "aka_common.hh"
 #include "mesh_partition.hh"
 
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 
 class MeshPartitionMeshData : public MeshPartition {
 
   /* ------------------------------------------------------------------------ */
   /* Constructors/Destructors                                                 */
   /* ------------------------------------------------------------------------ */
 public:
   MeshPartitionMeshData(const Mesh & mesh, UInt spatial_dimension,
                         const ID & id = "MeshPartitionerMeshData",
                         const MemoryID & memory_id = 0);
 
   MeshPartitionMeshData(const Mesh & mesh,
                         const ElementTypeMapArray<UInt> & mapping,
                         UInt spatial_dimension,
                         const ID & id = "MeshPartitionerMeshData",
                         const MemoryID & memory_id = 0);
 
   /* ------------------------------------------------------------------------ */
   /* Methods                                                                  */
   /* ------------------------------------------------------------------------ */
 public:
   void
   partitionate(UInt nb_part,
                const EdgeLoadFunctor & edge_load_func = ConstEdgeLoadFunctor(),
                const Array<UInt> & pairs = Array<UInt>()) override;
 
   void reorder() override;
 
   void setPartitionMapping(const ElementTypeMapArray<UInt> & mapping);
 
   void setPartitionMappingFromMeshData(const std::string & data_name);
 
 private:
   /* ------------------------------------------------------------------------ */
   /* Accessors                                                                */
   /* ------------------------------------------------------------------------ */
 public:
   /* ------------------------------------------------------------------------ */
   /* Class Members                                                            */
   /* ------------------------------------------------------------------------ */
 private:
   const ElementTypeMapArray<UInt> * partition_mapping;
 };
 
 /* -------------------------------------------------------------------------- */
 /* inline functions                                                           */
 /* -------------------------------------------------------------------------- */
 
 } // akantu
 
 #endif /* __AKANTU_MESH_PARTITION_MESH_DATA_HH__ */
diff --git a/src/mesh_utils/mesh_partition/mesh_partition_scotch.cc b/src/mesh_utils/mesh_partition/mesh_partition_scotch.cc
index 9d0cd28f1..f12652bff 100644
--- a/src/mesh_utils/mesh_partition/mesh_partition_scotch.cc
+++ b/src/mesh_utils/mesh_partition/mesh_partition_scotch.cc
@@ -1,479 +1,479 @@
 /**
  * @file   mesh_partition_scotch.cc
  *
  * @author David Simon Kammer <david.kammer@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Fri Jun 18 2010
- * @date last modification: Fri Jan 22 2016
+ * @date last modification: Tue Feb 20 2018
  *
  * @brief  implementation of the MeshPartitionScotch class
  *
  * @section LICENSE
  *
- * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
- * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
- * Solides)
+ * 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
+ * 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
+ * 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 "mesh_partition_scotch.hh"
 #include "aka_common.hh"
 #include "aka_random_generator.hh"
 #include "aka_static_if.hh"
 #include "mesh_utils.hh"
 /* -------------------------------------------------------------------------- */
 #include <cstdio>
 #include <fstream>
 /* -------------------------------------------------------------------------- */
 
 #if !defined(AKANTU_USE_PTSCOTCH)
 #ifndef AKANTU_SCOTCH_NO_EXTERN
 extern "C" {
 #endif // AKANTU_SCOTCH_NO_EXTERN
 #include <scotch.h>
 #ifndef AKANTU_SCOTCH_NO_EXTERN
 }
 #endif // AKANTU_SCOTCH_NO_EXTERN
 #else  // AKANTU_USE_PTSCOTCH
 #include <ptscotch.h>
 #endif // AKANTU_USE_PTSCOTCH
 
 namespace akantu {
 
 namespace {
   constexpr int scotch_version = int(SCOTCH_VERSION);
 }
 
 /* -------------------------------------------------------------------------- */
 MeshPartitionScotch::MeshPartitionScotch(const Mesh & mesh,
                                          UInt spatial_dimension, const ID & id,
                                          const MemoryID & memory_id)
     : MeshPartition(mesh, spatial_dimension, id, memory_id) {
   AKANTU_DEBUG_IN();
 
   // check if the akantu types and Scotch one are consistent
   static_assert(
       sizeof(Int) == sizeof(SCOTCH_Num),
       "The integer type of Akantu does not match the one from Scotch");
 
   static_if(aka::bool_constant_v<scotch_version >= 6>)
       .then([](auto && y) { SCOTCH_randomSeed(y); })
       .else_([](auto && y) { srandom(y); })(
           std::forward<UInt>(RandomGenerator<UInt>::seed()));
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 static SCOTCH_Mesh * createMesh(const Mesh & mesh) {
   AKANTU_DEBUG_IN();
 
   UInt spatial_dimension = mesh.getSpatialDimension();
   UInt nb_nodes = mesh.getNbNodes();
 
   UInt total_nb_element = 0;
   UInt nb_edge = 0;
 
   Mesh::type_iterator it = mesh.firstType(spatial_dimension);
   Mesh::type_iterator end = mesh.lastType(spatial_dimension);
   for (; it != end; ++it) {
     ElementType type = *it;
 
     UInt nb_element = mesh.getNbElement(type);
     UInt nb_nodes_per_element = Mesh::getNbNodesPerElement(type);
 
     total_nb_element += nb_element;
     nb_edge += nb_element * nb_nodes_per_element;
   }
 
   SCOTCH_Num vnodbas = 0;
   SCOTCH_Num vnodnbr = nb_nodes;
 
   SCOTCH_Num velmbas = vnodnbr;
   SCOTCH_Num velmnbr = total_nb_element;
 
   auto * verttab = new SCOTCH_Num[vnodnbr + velmnbr + 1];
   SCOTCH_Num * vendtab = verttab + 1;
 
   SCOTCH_Num * velotab = nullptr;
   SCOTCH_Num * vnlotab = nullptr;
   SCOTCH_Num * vlbltab = nullptr;
 
   memset(verttab, 0, (vnodnbr + velmnbr + 1) * sizeof(SCOTCH_Num));
 
   it = mesh.firstType(spatial_dimension);
   for (; it != end; ++it) {
     ElementType type = *it;
     if (Mesh::getSpatialDimension(type) != spatial_dimension)
       continue;
 
     UInt nb_element = mesh.getNbElement(type);
     UInt nb_nodes_per_element = Mesh::getNbNodesPerElement(type);
     const Array<UInt> & connectivity = mesh.getConnectivity(type, _not_ghost);
 
     /// count number of occurrence of each node
     for (UInt el = 0; el < nb_element; ++el) {
       UInt * conn_val = connectivity.storage() + el * nb_nodes_per_element;
       for (UInt n = 0; n < nb_nodes_per_element; ++n) {
         verttab[*(conn_val++)]++;
       }
     }
   }
 
   /// convert the occurrence array in a csr one
   for (UInt i = 1; i < nb_nodes; ++i)
     verttab[i] += verttab[i - 1];
   for (UInt i = nb_nodes; i > 0; --i)
     verttab[i] = verttab[i - 1];
   verttab[0] = 0;
 
   /// rearrange element to get the node-element list
   SCOTCH_Num edgenbr = verttab[vnodnbr] + nb_edge;
   auto * edgetab = new SCOTCH_Num[edgenbr];
 
   UInt linearized_el = 0;
 
   it = mesh.firstType(spatial_dimension);
   for (; it != end; ++it) {
     ElementType type = *it;
 
     UInt nb_element = mesh.getNbElement(type);
     UInt nb_nodes_per_element = Mesh::getNbNodesPerElement(type);
     const Array<UInt> & connectivity = mesh.getConnectivity(type, _not_ghost);
 
     for (UInt el = 0; el < nb_element; ++el, ++linearized_el) {
       UInt * conn_val = connectivity.storage() + el * nb_nodes_per_element;
       for (UInt n = 0; n < nb_nodes_per_element; ++n)
         edgetab[verttab[*(conn_val++)]++] = linearized_el + velmbas;
     }
   }
 
   for (UInt i = nb_nodes; i > 0; --i)
     verttab[i] = verttab[i - 1];
   verttab[0] = 0;
 
   SCOTCH_Num * verttab_tmp = verttab + vnodnbr + 1;
   SCOTCH_Num * edgetab_tmp = edgetab + verttab[vnodnbr];
 
   it = mesh.firstType(spatial_dimension);
   for (; it != end; ++it) {
     ElementType type = *it;
 
     UInt nb_element = mesh.getNbElement(type);
     UInt nb_nodes_per_element = Mesh::getNbNodesPerElement(type);
 
     const Array<UInt> & connectivity = mesh.getConnectivity(type, _not_ghost);
 
     for (UInt el = 0; el < nb_element; ++el) {
       *verttab_tmp = *(verttab_tmp - 1) + nb_nodes_per_element;
       verttab_tmp++;
       UInt * conn = connectivity.storage() + el * nb_nodes_per_element;
       for (UInt i = 0; i < nb_nodes_per_element; ++i) {
         *(edgetab_tmp++) = *(conn++) + vnodbas;
       }
     }
   }
 
   auto * meshptr = new SCOTCH_Mesh;
 
   SCOTCH_meshInit(meshptr);
 
   SCOTCH_meshBuild(meshptr, velmbas, vnodbas, velmnbr, vnodnbr, verttab,
                    vendtab, velotab, vnlotab, vlbltab, edgenbr, edgetab);
 
   /// Check the mesh
   AKANTU_DEBUG_ASSERT(SCOTCH_meshCheck(meshptr) == 0,
                       "Scotch mesh is not consistent");
 
 #ifndef AKANTU_NDEBUG
   if (AKANTU_DEBUG_TEST(dblDump)) {
     /// save initial graph
     FILE * fmesh = fopen("ScotchMesh.msh", "w");
     SCOTCH_meshSave(meshptr, fmesh);
     fclose(fmesh);
 
     /// write geometry file
     std::ofstream fgeominit;
     fgeominit.open("ScotchMesh.xyz");
     fgeominit << spatial_dimension << std::endl << nb_nodes << std::endl;
 
     const Array<Real> & nodes = mesh.getNodes();
     Real * nodes_val = nodes.storage();
     for (UInt i = 0; i < nb_nodes; ++i) {
       fgeominit << i << " ";
       for (UInt s = 0; s < spatial_dimension; ++s)
         fgeominit << *(nodes_val++) << " ";
       fgeominit << std::endl;
       ;
     }
     fgeominit.close();
   }
 #endif
 
   AKANTU_DEBUG_OUT();
   return meshptr;
 }
 
 /* -------------------------------------------------------------------------- */
 static void destroyMesh(SCOTCH_Mesh * meshptr) {
   AKANTU_DEBUG_IN();
 
   SCOTCH_Num velmbas, vnodbas, vnodnbr, velmnbr, *verttab, *vendtab, *velotab,
       *vnlotab, *vlbltab, edgenbr, *edgetab, degrptr;
 
   SCOTCH_meshData(meshptr, &velmbas, &vnodbas, &velmnbr, &vnodnbr, &verttab,
                   &vendtab, &velotab, &vnlotab, &vlbltab, &edgenbr, &edgetab,
                   &degrptr);
 
   delete[] verttab;
   delete[] edgetab;
 
   SCOTCH_meshExit(meshptr);
 
   delete meshptr;
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void MeshPartitionScotch::partitionate(UInt nb_part,
                                        const EdgeLoadFunctor & edge_load_func,
                                        const Array<UInt> & pairs) {
   AKANTU_DEBUG_IN();
 
   nb_partitions = nb_part;
 
   tweakConnectivity(pairs);
 
   AKANTU_DEBUG_INFO("Partitioning the mesh " << mesh.getID() << " in "
                                              << nb_part << " parts.");
 
   Array<Int> dxadj;
   Array<Int> dadjncy;
   Array<Int> edge_loads;
   buildDualGraph(dxadj, dadjncy, edge_loads, edge_load_func);
 
   /// variables that will hold our structures in scotch format
   SCOTCH_Graph scotch_graph;
   SCOTCH_Strat scotch_strat;
 
   /// description number and arrays for struct mesh for scotch
   SCOTCH_Num baseval = 0; // base numbering for element and
   // nodes (0 -> C , 1 -> fortran)
   SCOTCH_Num vertnbr = dxadj.size() - 1; // number of vertexes
   SCOTCH_Num * parttab;                  // array of partitions
   SCOTCH_Num edgenbr = dxadj(vertnbr);   // twice  the number  of "edges"
   //(an "edge" bounds two nodes)
   SCOTCH_Num * verttab = dxadj.storage(); // array of start indices in edgetab
   SCOTCH_Num * vendtab = nullptr; // array of after-last indices in edgetab
   SCOTCH_Num * velotab = nullptr; // integer  load  associated with
   // every vertex ( optional )
   SCOTCH_Num * edlotab = edge_loads.storage(); // integer  load  associated with
   // every edge ( optional )
   SCOTCH_Num * edgetab = dadjncy.storage(); // adjacency array of every vertex
   SCOTCH_Num * vlbltab = nullptr;           // vertex label array (optional)
 
   /// Allocate space for Scotch arrays
   parttab = new SCOTCH_Num[vertnbr];
 
   /// Initialize the strategy structure
   SCOTCH_stratInit(&scotch_strat);
 
   /// Initialize the graph structure
   SCOTCH_graphInit(&scotch_graph);
 
   /// Build the graph from the adjacency arrays
   SCOTCH_graphBuild(&scotch_graph, baseval, vertnbr, verttab, vendtab, velotab,
                     vlbltab, edgenbr, edgetab, edlotab);
 
 #ifndef AKANTU_NDEBUG
   if (AKANTU_DEBUG_TEST(dblDump)) {
     /// save initial graph
     FILE * fgraphinit = fopen("GraphIniFile.grf", "w");
     SCOTCH_graphSave(&scotch_graph, fgraphinit);
     fclose(fgraphinit);
 
     /// write geometry file
     std::ofstream fgeominit;
     fgeominit.open("GeomIniFile.xyz");
     fgeominit << spatial_dimension << std::endl << vertnbr << std::endl;
 
     const Array<Real> & nodes = mesh.getNodes();
 
     Mesh::type_iterator f_it =
         mesh.firstType(spatial_dimension, _not_ghost, _ek_not_defined);
     Mesh::type_iterator f_end =
         mesh.lastType(spatial_dimension, _not_ghost, _ek_not_defined);
     auto nodes_it = nodes.begin(spatial_dimension);
 
     UInt out_linerized_el = 0;
     for (; f_it != f_end; ++f_it) {
       ElementType type = *f_it;
 
       UInt nb_element = mesh.getNbElement(*f_it);
       UInt nb_nodes_per_element = Mesh::getNbNodesPerElement(type);
       const Array<UInt> & connectivity = mesh.getConnectivity(type);
 
       Vector<Real> mid(spatial_dimension);
       for (UInt el = 0; el < nb_element; ++el) {
         mid.set(0.);
         for (UInt n = 0; n < nb_nodes_per_element; ++n) {
           UInt node = connectivity.storage()[nb_nodes_per_element * el + n];
           mid += Vector<Real>(nodes_it[node]);
         }
         mid /= nb_nodes_per_element;
 
         fgeominit << out_linerized_el++ << " ";
         for (UInt s = 0; s < spatial_dimension; ++s)
           fgeominit << mid[s] << " ";
 
         fgeominit << std::endl;
         ;
       }
     }
     fgeominit.close();
   }
 #endif
   /// Check the graph
   AKANTU_DEBUG_ASSERT(SCOTCH_graphCheck(&scotch_graph) == 0,
                       "Graph to partition is not consistent");
 
   /// Partition the mesh
   SCOTCH_graphPart(&scotch_graph, nb_part, &scotch_strat, parttab);
 
   /// Check the graph
   AKANTU_DEBUG_ASSERT(SCOTCH_graphCheck(&scotch_graph) == 0,
                       "Partitioned graph is not consistent");
 
 #ifndef AKANTU_NDEBUG
   if (AKANTU_DEBUG_TEST(dblDump)) {
     /// save the partitioned graph
     FILE * fgraph = fopen("GraphFile.grf", "w");
     SCOTCH_graphSave(&scotch_graph, fgraph);
     fclose(fgraph);
 
     /// save the partition map
     std::ofstream fmap;
     fmap.open("MapFile.map");
     fmap << vertnbr << std::endl;
     for (Int i = 0; i < vertnbr; i++)
       fmap << i << "    " << parttab[i] << std::endl;
     fmap.close();
   }
 #endif
 
   /// free the scotch data structures
   SCOTCH_stratExit(&scotch_strat);
   SCOTCH_graphFree(&scotch_graph);
   SCOTCH_graphExit(&scotch_graph);
 
   fillPartitionInformation(mesh, parttab);
 
   delete[] parttab;
 
   restoreConnectivity();
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void MeshPartitionScotch::reorder() {
   AKANTU_DEBUG_IN();
 
   AKANTU_DEBUG_INFO("Reordering the mesh " << mesh.getID());
   SCOTCH_Mesh * scotch_mesh = createMesh(mesh);
 
   UInt nb_nodes = mesh.getNbNodes();
 
   SCOTCH_Strat scotch_strat;
   // SCOTCH_Ordering scotch_order;
 
   auto * permtab = new SCOTCH_Num[nb_nodes];
   SCOTCH_Num * peritab = nullptr;
   SCOTCH_Num cblknbr = 0;
   SCOTCH_Num * rangtab = nullptr;
   SCOTCH_Num * treetab = nullptr;
 
   /// Initialize the strategy structure
   SCOTCH_stratInit(&scotch_strat);
 
   SCOTCH_Graph scotch_graph;
 
   SCOTCH_graphInit(&scotch_graph);
   SCOTCH_meshGraph(scotch_mesh, &scotch_graph);
 
 #ifndef AKANTU_NDEBUG
   if (AKANTU_DEBUG_TEST(dblDump)) {
     FILE * fgraphinit = fopen("ScotchMesh.grf", "w");
     SCOTCH_graphSave(&scotch_graph, fgraphinit);
     fclose(fgraphinit);
   }
 #endif
 
   /// Check the graph
   // AKANTU_DEBUG_ASSERT(SCOTCH_graphCheck(&scotch_graph) == 0,
   //		      "Mesh to Graph is not consistent");
 
   SCOTCH_graphOrder(&scotch_graph, &scotch_strat, permtab, peritab, &cblknbr,
                     rangtab, treetab);
 
   SCOTCH_graphExit(&scotch_graph);
   SCOTCH_stratExit(&scotch_strat);
   destroyMesh(scotch_mesh);
 
   /// Renumbering
   UInt spatial_dimension = mesh.getSpatialDimension();
 
   for (UInt g = _not_ghost; g <= _ghost; ++g) {
     auto gt = (GhostType)g;
 
     Mesh::type_iterator it = mesh.firstType(_all_dimensions, gt);
     Mesh::type_iterator end = mesh.lastType(_all_dimensions, gt);
 
     for (; it != end; ++it) {
       ElementType type = *it;
 
       UInt nb_element = mesh.getNbElement(type, gt);
       UInt nb_nodes_per_element = Mesh::getNbNodesPerElement(type);
 
       const Array<UInt> & connectivity = mesh.getConnectivity(type, gt);
 
       UInt * conn = connectivity.storage();
       for (UInt el = 0; el < nb_element * nb_nodes_per_element; ++el, ++conn) {
         *conn = permtab[*conn];
       }
     }
   }
 
   /// \todo think of a in-place way to do it
   auto * new_coordinates = new Real[spatial_dimension * nb_nodes];
   Real * old_coordinates = mesh.getNodes().storage();
   for (UInt i = 0; i < nb_nodes; ++i) {
     memcpy(new_coordinates + permtab[i] * spatial_dimension,
            old_coordinates + i * spatial_dimension,
            spatial_dimension * sizeof(Real));
   }
   memcpy(old_coordinates, new_coordinates,
          nb_nodes * spatial_dimension * sizeof(Real));
   delete[] new_coordinates;
 
   delete[] permtab;
 
   AKANTU_DEBUG_OUT();
 }
 
 } // namespace akantu
diff --git a/src/mesh_utils/mesh_partition/mesh_partition_scotch.hh b/src/mesh_utils/mesh_partition/mesh_partition_scotch.hh
index 2dc3e385b..abe747b96 100644
--- a/src/mesh_utils/mesh_partition/mesh_partition_scotch.hh
+++ b/src/mesh_utils/mesh_partition/mesh_partition_scotch.hh
@@ -1,78 +1,77 @@
 /**
  * @file   mesh_partition_scotch.hh
  *
  * @author David Simon Kammer <david.kammer@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Fri Jun 18 2010
- * @date last modification: Sun Oct 19 2014
+ * @date last modification: Wed Nov 08 2017
  *
  * @brief  mesh partitioning based on libScotch
  *
  * @section LICENSE
  *
- * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
- * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
- * Solides)
+ * 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
+ * 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
+ * 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_MESH_PARTITION_SCOTCH_HH__
 #define __AKANTU_MESH_PARTITION_SCOTCH_HH__
 
 /* -------------------------------------------------------------------------- */
 #include "aka_common.hh"
 #include "mesh_partition.hh"
 
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 
 class MeshPartitionScotch : public MeshPartition {
   /* ------------------------------------------------------------------------ */
   /* Constructors/Destructors                                                 */
   /* ------------------------------------------------------------------------ */
 public:
   MeshPartitionScotch(const Mesh & mesh, UInt spatial_dimension,
                       const ID & id = "mesh_partition_scotch",
                       const MemoryID & memory_id = 0);
 
   /* ------------------------------------------------------------------------ */
   /* Methods                                                                  */
   /* ------------------------------------------------------------------------ */
 public:
   void
   partitionate(UInt nb_part,
                const EdgeLoadFunctor & edge_load_func = ConstEdgeLoadFunctor(),
                const Array<UInt> & pairs = Array<UInt>()) override;
 
   void reorder() override;
 
   /* ------------------------------------------------------------------------ */
   /* Accessors                                                                */
   /* ------------------------------------------------------------------------ */
 public:
   /* ------------------------------------------------------------------------ */
   /* Class Members                                                            */
   /* ------------------------------------------------------------------------ */
 private:
 };
 
 } // akantu
 
 #endif /* __AKANTU_MESH_PARTITION_SCOTCH_HH__ */
diff --git a/src/mesh_utils/mesh_utils.cc b/src/mesh_utils/mesh_utils.cc
index 7883e4a37..cc68fe58f 100644
--- a/src/mesh_utils/mesh_utils.cc
+++ b/src/mesh_utils/mesh_utils.cc
@@ -1,2091 +1,2090 @@
 /**
  * @file   mesh_utils.cc
  *
  * @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
  * @author Dana Christen <dana.christen@epfl.ch>
  * @author David Simon Kammer <david.kammer@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  * @author Leonardo Snozzi <leonardo.snozzi@epfl.ch>
  * @author Marco Vocialta <marco.vocialta@epfl.ch>
  *
  * @date creation: Fri Aug 20 2010
- * @date last modification: Fri Jan 22 2016
+ * @date last modification: Wed Feb 21 2018
  *
  * @brief  All mesh utils necessary for various tasks
  *
  * @section LICENSE
  *
- * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
- * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
- * Solides)
+ * 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
+ * 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
+ * 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 "mesh_utils.hh"
 #include "element_synchronizer.hh"
 #include "fe_engine.hh"
 #include "mesh_accessor.hh"
 /* -------------------------------------------------------------------------- */
 #include <limits>
 #include <numeric>
 #include <queue>
 #include <set>
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 void MeshUtils::buildNode2Elements(const Mesh & mesh,
                                    CSR<Element> & node_to_elem,
                                    UInt spatial_dimension) {
   AKANTU_DEBUG_IN();
   if (spatial_dimension == _all_dimensions)
     spatial_dimension = mesh.getSpatialDimension();
 
   /// count number of occurrence of each node
   UInt nb_nodes = mesh.getNbNodes();
 
   /// array for the node-element list
   node_to_elem.resizeRows(nb_nodes);
   node_to_elem.clearRows();
 
   // AKANTU_DEBUG_ASSERT(
   //     mesh.firstType(spatial_dimension) != mesh.lastType(spatial_dimension),
   //     "Some elements must be found in right dimension to compute facets!");
 
   for (auto && ghost_type : ghost_types) {
     for (auto && type :
          mesh.elementTypes(spatial_dimension, ghost_type, _ek_not_defined)) {
       UInt nb_element = mesh.getNbElement(type, ghost_type);
       auto conn_it = mesh.getConnectivity(type, ghost_type)
                          .begin(Mesh::getNbNodesPerElement(type));
 
       for (UInt el = 0; el < nb_element; ++el, ++conn_it)
         for (UInt n = 0; n < conn_it->size(); ++n)
           ++node_to_elem.rowOffset((*conn_it)(n));
     }
   }
 
   node_to_elem.countToCSR();
   node_to_elem.resizeCols();
 
   /// rearrange element to get the node-element list
   Element e;
   node_to_elem.beginInsertions();
 
   for (auto && ghost_type : ghost_types) {
     e.ghost_type = ghost_type;
     for (auto && type :
          mesh.elementTypes(spatial_dimension, ghost_type, _ek_not_defined)) {
 
       e.type = type;
       UInt nb_element = mesh.getNbElement(type, ghost_type);
       auto conn_it = mesh.getConnectivity(type, ghost_type)
                          .begin(Mesh::getNbNodesPerElement(type));
 
       for (UInt el = 0; el < nb_element; ++el, ++conn_it) {
         e.element = el;
         for (UInt n = 0; n < conn_it->size(); ++n)
           node_to_elem.insertInRow((*conn_it)(n), e);
       }
     }
   }
 
   node_to_elem.endInsertions();
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void MeshUtils::buildNode2ElementsElementTypeMap(const Mesh & mesh,
                                                  CSR<UInt> & node_to_elem,
                                                  const ElementType & type,
                                                  const GhostType & ghost_type) {
   AKANTU_DEBUG_IN();
   UInt nb_nodes = mesh.getNbNodes();
 
   UInt nb_nodes_per_element = Mesh::getNbNodesPerElement(type);
   UInt nb_elements = mesh.getConnectivity(type, ghost_type).size();
 
   UInt * conn_val = mesh.getConnectivity(type, ghost_type).storage();
 
   /// array for the node-element list
   node_to_elem.resizeRows(nb_nodes);
   node_to_elem.clearRows();
 
   /// count number of occurrence of each node
   for (UInt el = 0; el < nb_elements; ++el) {
     UInt el_offset = el * nb_nodes_per_element;
     for (UInt n = 0; n < nb_nodes_per_element; ++n)
       ++node_to_elem.rowOffset(conn_val[el_offset + n]);
   }
 
   /// convert the occurrence array in a csr one
   node_to_elem.countToCSR();
 
   node_to_elem.resizeCols();
   node_to_elem.beginInsertions();
 
   /// save the element index in the node-element list
   for (UInt el = 0; el < nb_elements; ++el) {
     UInt el_offset = el * nb_nodes_per_element;
     for (UInt n = 0; n < nb_nodes_per_element; ++n) {
       node_to_elem.insertInRow(conn_val[el_offset + n], el);
     }
   }
 
   node_to_elem.endInsertions();
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void MeshUtils::buildFacets(Mesh & mesh) {
   AKANTU_DEBUG_IN();
 
   UInt spatial_dimension = mesh.getSpatialDimension();
 
   for (ghost_type_t::iterator gt = ghost_type_t::begin();
        gt != ghost_type_t::end(); ++gt) {
     GhostType gt_facet = *gt;
     Mesh::type_iterator it = mesh.firstType(spatial_dimension - 1, gt_facet);
     Mesh::type_iterator end = mesh.lastType(spatial_dimension - 1, gt_facet);
     for (; it != end; ++it) {
       mesh.getConnectivity(*it, *gt).resize(0);
       // \todo inform the mesh event handler
     }
   }
 
   buildFacetsDimension(mesh, mesh, true, spatial_dimension);
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void MeshUtils::buildAllFacets(const Mesh & mesh, Mesh & mesh_facets,
                                UInt to_dimension) {
   AKANTU_DEBUG_IN();
 
   UInt spatial_dimension = mesh.getSpatialDimension();
 
   buildAllFacets(mesh, mesh_facets, spatial_dimension, to_dimension);
 
   AKANTU_DEBUG_OUT();
 }
 /* -------------------------------------------------------------------------- */
 void MeshUtils::buildAllFacets(const Mesh & mesh, Mesh & mesh_facets,
                                UInt from_dimension, UInt to_dimension) {
   AKANTU_DEBUG_IN();
 
   AKANTU_DEBUG_ASSERT(
       mesh_facets.isMeshFacets(),
       "The mesh_facets should be initialized with initMeshFacets");
 
   /// generate facets
   buildFacetsDimension(mesh, mesh_facets, false, from_dimension);
 
   /// copy nodes type
   MeshAccessor mesh_accessor_facets(mesh_facets);
   mesh_accessor_facets.getNodesType().copy(mesh.getNodesType());
 
   /// sort facets and generate sub-facets
   for (UInt i = from_dimension - 1; i > to_dimension; --i) {
     buildFacetsDimension(mesh_facets, mesh_facets, false, i);
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void MeshUtils::buildFacetsDimension(const Mesh & mesh, Mesh & mesh_facets,
                                      bool boundary_only, UInt dimension) {
   AKANTU_DEBUG_IN();
 
   // save the current parent of mesh_facets and set it temporarly to mesh since
   // mesh is the one containing the elements for which mesh_facets has the
   // sub-elements
   // example: if the function is called with mesh = mesh_facets
   const Mesh * mesh_facets_parent = nullptr;
   try {
     mesh_facets_parent = &mesh_facets.getMeshParent();
   } catch (...) {
   }
 
   mesh_facets.defineMeshParent(mesh);
   MeshAccessor mesh_accessor(mesh_facets);
 
   UInt spatial_dimension = mesh.getSpatialDimension();
 
   const Array<Real> & mesh_facets_nodes = mesh_facets.getNodes();
   const auto mesh_facets_nodes_it = mesh_facets_nodes.begin(spatial_dimension);
 
   CSR<Element> node_to_elem;
   buildNode2Elements(mesh, node_to_elem, dimension);
 
   Array<UInt> counter;
   std::vector<Element> connected_elements;
 
   // init the SubelementToElement data to improve performance
   for (auto && ghost_type : ghost_types) {
     for (auto && type : mesh.elementTypes(dimension, ghost_type)) {
       mesh_accessor.getSubelementToElement(type, ghost_type);
 
       auto facet_types = mesh.getAllFacetTypes(type);
 
       for (auto && ft : arange(facet_types.size())) {
         auto facet_type = facet_types(ft);
         mesh_accessor.getElementToSubelement(facet_type, ghost_type);
         mesh_accessor.getConnectivity(facet_type, ghost_type);
       }
     }
   }
 
   const ElementSynchronizer * synchronizer = nullptr;
   if (mesh.isDistributed()) {
     synchronizer = &(mesh.getElementSynchronizer());
   }
 
   Element current_element;
   for (auto && ghost_type : ghost_types) {
     GhostType facet_ghost_type = ghost_type;
     current_element.ghost_type = ghost_type;
 
     for (auto && type : mesh.elementTypes(dimension, ghost_type)) {
       auto facet_types = mesh.getAllFacetTypes(type);
       current_element.type = type;
 
       for (auto && ft : arange(facet_types.size())) {
         auto facet_type = facet_types(ft);
         auto nb_element = mesh.getNbElement(type, ghost_type);
 
         auto element_to_subelement =
             &mesh_facets.getElementToSubelement(facet_type, ghost_type);
         auto connectivity_facets =
             &mesh_facets.getConnectivity(facet_type, ghost_type);
 
         auto nb_facet_per_element = mesh.getNbFacetsPerElement(type, ft);
         const auto & element_connectivity =
             mesh.getConnectivity(type, ghost_type);
         Matrix<const UInt> facet_local_connectivity(
             mesh.getFacetLocalConnectivity(type, ft));
 
         auto nb_nodes_per_facet = connectivity_facets->getNbComponent();
         Vector<UInt> facet(nb_nodes_per_facet);
 
         for (UInt el = 0; el < nb_element; ++el) {
           current_element.element = el;
 
           for (UInt f = 0; f < nb_facet_per_element; ++f) {
             for (UInt n = 0; n < nb_nodes_per_facet; ++n)
               facet(n) =
                   element_connectivity(el, facet_local_connectivity(f, n));
 
             UInt first_node_nb_elements = node_to_elem.getNbCols(facet(0));
             counter.resize(first_node_nb_elements);
             counter.clear();
 
             // loop over the other nodes to search intersecting elements,
             // which are the elements that share another node with the
             // starting element after first_node
             UInt local_el = 0;
             auto first_node_elements = node_to_elem.begin(facet(0));
             auto first_node_elements_end = node_to_elem.end(facet(0));
             for (; first_node_elements != first_node_elements_end;
                  ++first_node_elements, ++local_el) {
               for (UInt n = 1; n < nb_nodes_per_facet; ++n) {
                 auto node_elements_begin = node_to_elem.begin(facet(n));
                 auto node_elements_end = node_to_elem.end(facet(n));
                 counter(local_el) +=
                     std::count(node_elements_begin, node_elements_end,
                                *first_node_elements);
               }
             }
 
             // counting the number of elements connected to the facets and
             // taking the minimum element number, because the facet should
             // be inserted just once
             UInt nb_element_connected_to_facet = 0;
             Element minimum_el = ElementNull;
             connected_elements.clear();
             for (UInt el_f = 0; el_f < first_node_nb_elements; el_f++) {
               Element real_el = node_to_elem(facet(0), el_f);
               if (not(counter(el_f) == nb_nodes_per_facet - 1))
                 continue;
 
               ++nb_element_connected_to_facet;
               minimum_el = std::min(minimum_el, real_el);
               connected_elements.push_back(real_el);
             }
 
             if (minimum_el != current_element)
               continue;
 
             bool full_ghost_facet = false;
 
             UInt n = 0;
             while (n < nb_nodes_per_facet && mesh.isPureGhostNode(facet(n)))
               ++n;
             if (n == nb_nodes_per_facet)
               full_ghost_facet = true;
 
             if (full_ghost_facet)
               continue;
 
             if (boundary_only and nb_element_connected_to_facet != 1)
               continue;
 
             std::vector<Element> elements;
 
             // build elements_on_facets: linearized_el must come first
             // in order to store the facet in the correct direction
             // and avoid to invert the sign in the normal computation
             elements.push_back(current_element);
 
             if (nb_element_connected_to_facet == 1) { /// boundary facet
               elements.push_back(ElementNull);
             } else if (nb_element_connected_to_facet == 2) { /// internal facet
               elements.push_back(connected_elements[1]);
 
               /// check if facet is in between ghost and normal
               /// elements: if it's the case, the facet is either
               /// ghost or not ghost. The criterion to decide this
               /// is arbitrary. It was chosen to check the processor
               /// id (prank) of the two neighboring elements. If
               /// prank of the ghost element is lower than prank of
               /// the normal one, the facet is not ghost, otherwise
               /// it's ghost
               GhostType gt[2] = {_not_ghost, _not_ghost};
               for (UInt el = 0; el < connected_elements.size(); ++el)
                 gt[el] = connected_elements[el].ghost_type;
 
               if (gt[0] != gt[1] and
                   (gt[0] == _not_ghost or gt[1] == _not_ghost)) {
                 UInt prank[2];
                 for (UInt el = 0; el < 2; ++el) {
                   prank[el] = synchronizer->getRank(connected_elements[el]);
                 }
 
                 // ugly trick from Marco detected :P
                 bool ghost_one = (gt[0] != _ghost);
                 if (prank[ghost_one] > prank[!ghost_one])
                   facet_ghost_type = _not_ghost;
                 else
                   facet_ghost_type = _ghost;
 
                 connectivity_facets =
                     &mesh_facets.getConnectivity(facet_type, facet_ghost_type);
                 element_to_subelement = &mesh_facets.getElementToSubelement(
                     facet_type, facet_ghost_type);
               }
             } else { /// facet of facet
               for (UInt i = 1; i < nb_element_connected_to_facet; ++i) {
                 elements.push_back(connected_elements[i]);
               }
             }
 
             element_to_subelement->push_back(elements);
             connectivity_facets->push_back(facet);
 
             /// current facet index
             UInt current_facet = connectivity_facets->size() - 1;
 
             /// loop on every element connected to current facet and
             /// insert current facet in the first free spot of the
             /// subelement_to_element vector
             for (UInt elem = 0; elem < elements.size(); ++elem) {
               Element loc_el = elements[elem];
 
               if (loc_el.type == _not_defined)
                 continue;
 
               Array<Element> & subelement_to_element =
                   mesh_facets.getSubelementToElement(loc_el.type,
                                                      loc_el.ghost_type);
 
               UInt nb_facet_per_loc_element =
                   subelement_to_element.getNbComponent();
 
               for (UInt f_in = 0; f_in < nb_facet_per_loc_element; ++f_in) {
                 auto & el = subelement_to_element(loc_el.element, f_in);
                 if (el.type != _not_defined)
                   continue;
 
                 el.type = facet_type;
                 el.element = current_facet;
                 el.ghost_type = facet_ghost_type;
                 break;
               }
             }
 
             /// reset connectivity in case a facet was found in
             /// between ghost and normal elements
             if (facet_ghost_type != ghost_type) {
               facet_ghost_type = ghost_type;
               connectivity_facets =
                   &mesh_accessor.getConnectivity(facet_type, facet_ghost_type);
               element_to_subelement = &mesh_accessor.getElementToSubelement(
                   facet_type, facet_ghost_type);
             }
           }
         }
       }
     }
   }
 
   // restore the parent of mesh_facet
   if (mesh_facets_parent)
     mesh_facets.defineMeshParent(*mesh_facets_parent);
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void MeshUtils::renumberMeshNodes(Mesh & mesh,
                                   Array<UInt> & local_connectivities,
                                   UInt nb_local_element, UInt nb_ghost_element,
                                   ElementType type,
                                   Array<UInt> & old_nodes_numbers) {
   AKANTU_DEBUG_IN();
 
   UInt nb_nodes_per_element = Mesh::getNbNodesPerElement(type);
 
   std::map<UInt, UInt> renumbering_map;
   for (UInt i = 0; i < old_nodes_numbers.size(); ++i) {
     renumbering_map[old_nodes_numbers(i)] = i;
   }
 
   /// renumber the nodes
   renumberNodesInConnectivity(local_connectivities,
                               (nb_local_element + nb_ghost_element) *
                                   nb_nodes_per_element,
                               renumbering_map);
 
   old_nodes_numbers.resize(renumbering_map.size());
   for (auto & renumber_pair : renumbering_map) {
     old_nodes_numbers(renumber_pair.second) = renumber_pair.first;
   }
   renumbering_map.clear();
 
   MeshAccessor mesh_accessor(mesh);
 
   /// copy the renumbered connectivity to the right place
   auto & local_conn = mesh_accessor.getConnectivity(type);
   local_conn.resize(nb_local_element);
   memcpy(local_conn.storage(), local_connectivities.storage(),
          nb_local_element * nb_nodes_per_element * sizeof(UInt));
 
   auto & ghost_conn = mesh_accessor.getConnectivity(type, _ghost);
   ghost_conn.resize(nb_ghost_element);
   std::memcpy(ghost_conn.storage(),
               local_connectivities.storage() +
                   nb_local_element * nb_nodes_per_element,
               nb_ghost_element * nb_nodes_per_element * sizeof(UInt));
 
   auto & ghost_counter = mesh_accessor.getGhostsCounters(type, _ghost);
   ghost_counter.resize(nb_ghost_element, 1);
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void MeshUtils::renumberNodesInConnectivity(
     Array<UInt> & list_nodes, UInt nb_nodes,
     std::map<UInt, UInt> & renumbering_map) {
   AKANTU_DEBUG_IN();
 
   UInt * connectivity = list_nodes.storage();
   UInt new_node_num = renumbering_map.size();
   for (UInt n = 0; n < nb_nodes; ++n, ++connectivity) {
     UInt & node = *connectivity;
     auto it = renumbering_map.find(node);
     if (it == renumbering_map.end()) {
       UInt old_node = node;
       renumbering_map[old_node] = new_node_num;
       node = new_node_num;
       ++new_node_num;
     } else {
       node = it->second;
     }
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void MeshUtils::purifyMesh(Mesh & mesh) {
   AKANTU_DEBUG_IN();
 
   std::map<UInt, UInt> renumbering_map;
 
   RemovedNodesEvent remove_nodes(mesh);
   Array<UInt> & nodes_removed = remove_nodes.getList();
 
   for (UInt gt = _not_ghost; gt <= _ghost; ++gt) {
     auto ghost_type = (GhostType)gt;
 
     Mesh::type_iterator it =
         mesh.firstType(_all_dimensions, ghost_type, _ek_not_defined);
     Mesh::type_iterator end =
         mesh.lastType(_all_dimensions, ghost_type, _ek_not_defined);
     for (; it != end; ++it) {
 
       ElementType type(*it);
       UInt nb_nodes_per_element = Mesh::getNbNodesPerElement(type);
 
       Array<UInt> & connectivity = mesh.getConnectivity(type, ghost_type);
       UInt nb_element(connectivity.size());
 
       renumberNodesInConnectivity(
           connectivity, nb_element * nb_nodes_per_element, renumbering_map);
     }
   }
 
   Array<UInt> & new_numbering = remove_nodes.getNewNumbering();
   std::fill(new_numbering.begin(), new_numbering.end(), UInt(-1));
 
   auto it = renumbering_map.begin();
   auto end = renumbering_map.end();
   for (; it != end; ++it) {
     new_numbering(it->first) = it->second;
   }
 
   for (UInt i = 0; i < new_numbering.size(); ++i) {
     if (new_numbering(i) == UInt(-1))
       nodes_removed.push_back(i);
   }
 
   mesh.sendEvent(remove_nodes);
 
   AKANTU_DEBUG_OUT();
 }
 
 #if defined(AKANTU_COHESIVE_ELEMENT)
 /* -------------------------------------------------------------------------- */
 UInt MeshUtils::insertCohesiveElements(
     Mesh & mesh, Mesh & mesh_facets,
     const ElementTypeMapArray<bool> & facet_insertion,
     Array<UInt> & doubled_nodes, Array<Element> & new_elements,
     bool only_double_facets) {
   UInt spatial_dimension = mesh.getSpatialDimension();
   UInt elements_to_insert = updateFacetToDouble(mesh_facets, facet_insertion);
 
   if (elements_to_insert > 0) {
 
     if (spatial_dimension == 1) {
       doublePointFacet(mesh, mesh_facets, doubled_nodes);
     } else {
       doubleFacet(mesh, mesh_facets, spatial_dimension - 1, doubled_nodes,
                   true);
       findSubfacetToDouble<false>(mesh, mesh_facets);
 
       if (spatial_dimension == 2) {
         doubleSubfacet<2>(mesh, mesh_facets, doubled_nodes);
       } else if (spatial_dimension == 3) {
         doubleFacet(mesh, mesh_facets, 1, doubled_nodes, false);
         findSubfacetToDouble<true>(mesh, mesh_facets);
         doubleSubfacet<3>(mesh, mesh_facets, doubled_nodes);
       }
     }
 
     if (!only_double_facets)
       updateCohesiveData(mesh, mesh_facets, new_elements);
   }
 
   return elements_to_insert;
 }
 #endif
 
 /* -------------------------------------------------------------------------- */
 void MeshUtils::doubleNodes(Mesh & mesh, const std::vector<UInt> & old_nodes,
                             Array<UInt> & doubled_nodes) {
   AKANTU_DEBUG_IN();
 
   Array<Real> & position = mesh.getNodes();
   UInt spatial_dimension = mesh.getSpatialDimension();
 
   UInt old_nb_nodes = position.size();
   UInt new_nb_nodes = old_nb_nodes + old_nodes.size();
 
   UInt old_nb_doubled_nodes = doubled_nodes.size();
   UInt new_nb_doubled_nodes = old_nb_doubled_nodes + old_nodes.size();
 
   position.resize(new_nb_nodes);
   doubled_nodes.resize(new_nb_doubled_nodes);
 
   Array<Real>::iterator<Vector<Real>> position_begin =
       position.begin(spatial_dimension);
 
   for (UInt n = 0; n < old_nodes.size(); ++n) {
     UInt new_node = old_nb_nodes + n;
 
     /// store doubled nodes
     doubled_nodes(old_nb_doubled_nodes + n, 0) = old_nodes[n];
     doubled_nodes(old_nb_doubled_nodes + n, 1) = new_node;
 
     /// update position
     std::copy(position_begin + old_nodes[n], position_begin + old_nodes[n] + 1,
               position_begin + new_node);
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void MeshUtils::doubleFacet(Mesh & mesh, Mesh & mesh_facets,
                             UInt facet_dimension, Array<UInt> & doubled_nodes,
                             bool facet_mode) {
   AKANTU_DEBUG_IN();
 
   for (ghost_type_t::iterator gt = ghost_type_t::begin();
        gt != ghost_type_t::end(); ++gt) {
 
     GhostType gt_facet = *gt;
 
     Mesh::type_iterator it = mesh_facets.firstType(facet_dimension, gt_facet);
     Mesh::type_iterator end = mesh_facets.lastType(facet_dimension, gt_facet);
 
     for (; it != end; ++it) {
 
       ElementType type_facet = *it;
 
       Array<UInt> & f_to_double =
           mesh_facets.getData<UInt>("facet_to_double", type_facet, gt_facet);
       UInt nb_facet_to_double = f_to_double.size();
 
       if (nb_facet_to_double == 0)
         continue;
 
       ElementType type_subfacet = Mesh::getFacetType(type_facet);
       const UInt nb_subfacet_per_facet =
           Mesh::getNbFacetsPerElement(type_facet);
       GhostType gt_subfacet = _casper;
       Array<std::vector<Element>> * f_to_subfacet = nullptr;
 
       Array<Element> & subfacet_to_facet =
           mesh_facets.getSubelementToElement(type_facet, gt_facet);
 
       Array<UInt> & conn_facet =
           mesh_facets.getConnectivity(type_facet, gt_facet);
       UInt nb_nodes_per_facet = conn_facet.getNbComponent();
 
       UInt old_nb_facet = conn_facet.size();
       UInt new_nb_facet = old_nb_facet + nb_facet_to_double;
 
       conn_facet.resize(new_nb_facet);
       subfacet_to_facet.resize(new_nb_facet);
 
       UInt new_facet = old_nb_facet - 1;
       Element new_facet_el{type_facet, 0, gt_facet};
 
       Array<Element>::iterator<Vector<Element>> subfacet_to_facet_begin =
           subfacet_to_facet.begin(nb_subfacet_per_facet);
       Array<UInt>::iterator<Vector<UInt>> conn_facet_begin =
           conn_facet.begin(nb_nodes_per_facet);
 
       for (UInt facet = 0; facet < nb_facet_to_double; ++facet) {
         UInt old_facet = f_to_double(facet);
         ++new_facet;
 
         /// adding a new facet by copying original one
 
         /// copy connectivity in new facet
         std::copy(conn_facet_begin + old_facet,
                   conn_facet_begin + old_facet + 1,
                   conn_facet_begin + new_facet);
 
         /// update subfacet_to_facet
         std::copy(subfacet_to_facet_begin + old_facet,
                   subfacet_to_facet_begin + old_facet + 1,
                   subfacet_to_facet_begin + new_facet);
 
         new_facet_el.element = new_facet;
 
         /// loop on every subfacet
         for (UInt sf = 0; sf < nb_subfacet_per_facet; ++sf) {
           Element & subfacet = subfacet_to_facet(old_facet, sf);
           if (subfacet == ElementNull)
             continue;
 
           if (gt_subfacet != subfacet.ghost_type) {
             gt_subfacet = subfacet.ghost_type;
             f_to_subfacet = &mesh_facets.getElementToSubelement(
                 type_subfacet, subfacet.ghost_type);
           }
 
           /// update facet_to_subfacet array
           (*f_to_subfacet)(subfacet.element).push_back(new_facet_el);
         }
       }
 
       /// update facet_to_subfacet and _segment_3 facets if any
       if (!facet_mode) {
         updateSubfacetToFacet(mesh_facets, type_facet, gt_facet, true);
         updateFacetToSubfacet(mesh_facets, type_facet, gt_facet, true);
         updateQuadraticSegments<true>(mesh, mesh_facets, type_facet, gt_facet,
                                       doubled_nodes);
       } else
         updateQuadraticSegments<false>(mesh, mesh_facets, type_facet, gt_facet,
                                        doubled_nodes);
     }
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 UInt MeshUtils::updateFacetToDouble(
     Mesh & mesh_facets, const ElementTypeMapArray<bool> & facet_insertion) {
   AKANTU_DEBUG_IN();
 
   UInt spatial_dimension = mesh_facets.getSpatialDimension();
   UInt nb_facets_to_double = 0.;
 
   for (ghost_type_t::iterator gt = ghost_type_t::begin();
        gt != ghost_type_t::end(); ++gt) {
 
     GhostType gt_facet = *gt;
 
     Mesh::type_iterator it =
         mesh_facets.firstType(spatial_dimension - 1, gt_facet);
     Mesh::type_iterator end =
         mesh_facets.lastType(spatial_dimension - 1, gt_facet);
 
     for (; it != end; ++it) {
 
       ElementType type_facet = *it;
 
       const Array<bool> & f_insertion = facet_insertion(type_facet, gt_facet);
       Array<UInt> & f_to_double =
           mesh_facets.getData<UInt>("facet_to_double", type_facet, gt_facet);
 
       Array<std::vector<Element>> & element_to_facet =
           mesh_facets.getElementToSubelement(type_facet, gt_facet);
 
       ElementType el_type = _not_defined;
       GhostType el_gt = _casper;
       UInt nb_facet_per_element = 0;
       Element old_facet_el{type_facet, 0, gt_facet};
 
       Array<Element> * facet_to_element = nullptr;
 
       for (UInt f = 0; f < f_insertion.size(); ++f) {
 
         if (f_insertion(f) == false)
           continue;
 
         ++nb_facets_to_double;
 
         if (element_to_facet(f)[1].type == _not_defined
 #if defined(AKANTU_COHESIVE_ELEMENT)
             || element_to_facet(f)[1].kind() == _ek_cohesive
 #endif
             ) {
           AKANTU_DEBUG_WARNING("attempt to double a facet on the boundary");
           continue;
         }
 
         f_to_double.push_back(f);
 
         UInt new_facet = mesh_facets.getNbElement(type_facet, gt_facet) +
                          f_to_double.size() - 1;
         old_facet_el.element = f;
 
         /// update facet_to_element vector
         Element & elem_to_update = element_to_facet(f)[1];
         UInt el = elem_to_update.element;
 
         if (elem_to_update.ghost_type != el_gt ||
             elem_to_update.type != el_type) {
           el_type = elem_to_update.type;
           el_gt = elem_to_update.ghost_type;
           facet_to_element =
               &mesh_facets.getSubelementToElement(el_type, el_gt);
           nb_facet_per_element = facet_to_element->getNbComponent();
         }
 
         Element * f_update =
             std::find(facet_to_element->storage() + el * nb_facet_per_element,
                       facet_to_element->storage() + el * nb_facet_per_element +
                           nb_facet_per_element,
                       old_facet_el);
 
         AKANTU_DEBUG_ASSERT(
             facet_to_element->storage() + el * nb_facet_per_element !=
                 facet_to_element->storage() + el * nb_facet_per_element +
                     nb_facet_per_element,
             "Facet not found");
 
         f_update->element = new_facet;
 
         /// update elements connected to facet
         std::vector<Element> first_facet_list = element_to_facet(f);
         element_to_facet.push_back(first_facet_list);
 
         /// set new and original facets as boundary facets
         element_to_facet(new_facet)[0] = element_to_facet(new_facet)[1];
 
         element_to_facet(f)[1] = ElementNull;
         element_to_facet(new_facet)[1] = ElementNull;
       }
     }
   }
 
   AKANTU_DEBUG_OUT();
   return nb_facets_to_double;
 }
 
 /* -------------------------------------------------------------------------- */
 void MeshUtils::resetFacetToDouble(Mesh & mesh_facets) {
   AKANTU_DEBUG_IN();
 
   for (UInt g = _not_ghost; g <= _ghost; ++g) {
     auto gt = (GhostType)g;
 
     Mesh::type_iterator it = mesh_facets.firstType(_all_dimensions, gt);
     Mesh::type_iterator end = mesh_facets.lastType(_all_dimensions, gt);
     for (; it != end; ++it) {
       ElementType type = *it;
       mesh_facets.getDataPointer<UInt>("facet_to_double", type, gt, 1, false);
 
       mesh_facets.getDataPointer<std::vector<Element>>(
           "facets_to_subfacet_double", type, gt, 1, false);
 
       mesh_facets.getDataPointer<std::vector<Element>>(
           "elements_to_subfacet_double", type, gt, 1, false);
 
       mesh_facets.getDataPointer<std::vector<Element>>(
           "subfacets_to_subsubfacet_double", type, gt, 1, false);
     }
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <bool subsubfacet_mode>
 void MeshUtils::findSubfacetToDouble(Mesh & mesh, Mesh & mesh_facets) {
   AKANTU_DEBUG_IN();
 
   UInt spatial_dimension = mesh_facets.getSpatialDimension();
   if (spatial_dimension == 1)
     return;
 
   for (ghost_type_t::iterator gt = ghost_type_t::begin();
        gt != ghost_type_t::end(); ++gt) {
 
     GhostType gt_facet = *gt;
 
     Mesh::type_iterator it =
         mesh_facets.firstType(spatial_dimension - 1, gt_facet);
     Mesh::type_iterator end =
         mesh_facets.lastType(spatial_dimension - 1, gt_facet);
 
     for (; it != end; ++it) {
 
       ElementType type_facet = *it;
 
       Array<UInt> & f_to_double =
           mesh_facets.getData<UInt>("facet_to_double", type_facet, gt_facet);
       UInt nb_facet_to_double = f_to_double.size();
       if (nb_facet_to_double == 0)
         continue;
 
       ElementType type_subfacet = Mesh::getFacetType(type_facet);
       GhostType gt_subfacet = _casper;
 
       ElementType type_subsubfacet = Mesh::getFacetType(type_subfacet);
       GhostType gt_subsubfacet = _casper;
 
       Array<UInt> * conn_subfacet = nullptr;
       Array<UInt> * sf_to_double = nullptr;
       Array<std::vector<Element>> * sf_to_subfacet_double = nullptr;
       Array<std::vector<Element>> * f_to_subfacet_double = nullptr;
       Array<std::vector<Element>> * el_to_subfacet_double = nullptr;
 
       UInt nb_subfacet = Mesh::getNbFacetsPerElement(type_facet);
 
       UInt nb_subsubfacet;
       UInt nb_nodes_per_sf_el;
 
       if (subsubfacet_mode) {
         nb_nodes_per_sf_el = Mesh::getNbNodesPerElement(type_subsubfacet);
         nb_subsubfacet = Mesh::getNbFacetsPerElement(type_subfacet);
       } else
         nb_nodes_per_sf_el = Mesh::getNbNodesPerElement(type_subfacet);
 
       Array<Element> & subfacet_to_facet =
           mesh_facets.getSubelementToElement(type_facet, gt_facet);
 
       Array<std::vector<Element>> & element_to_facet =
           mesh_facets.getElementToSubelement(type_facet, gt_facet);
 
       Array<Element> * subsubfacet_to_subfacet = nullptr;
 
       UInt old_nb_facet = subfacet_to_facet.size() - nb_facet_to_double;
 
       Element current_facet{type_facet, 0, gt_facet};
       std::vector<Element> element_list;
       std::vector<Element> facet_list;
       std::vector<Element> * subfacet_list;
       if (subsubfacet_mode)
         subfacet_list = new std::vector<Element>;
 
       /// map to filter subfacets
       Array<std::vector<Element>> * facet_to_subfacet = nullptr;
 
       /// this is used to make sure that both new and old facets are
       /// checked
       UInt facets[2];
 
       /// loop on every facet
       for (UInt f_index = 0; f_index < 2; ++f_index) {
         for (UInt facet = 0; facet < nb_facet_to_double; ++facet) {
           facets[bool(f_index)] = f_to_double(facet);
           facets[!bool(f_index)] = old_nb_facet + facet;
 
           UInt old_facet = facets[0];
           UInt new_facet = facets[1];
 
           Element & starting_element = element_to_facet(new_facet)[0];
           current_facet.element = old_facet;
 
           /// loop on every subfacet
           for (UInt sf = 0; sf < nb_subfacet; ++sf) {
 
             Element & subfacet = subfacet_to_facet(old_facet, sf);
             if (subfacet == ElementNull)
               continue;
 
             if (gt_subfacet != subfacet.ghost_type) {
               gt_subfacet = subfacet.ghost_type;
 
               if (subsubfacet_mode) {
                 subsubfacet_to_subfacet = &mesh_facets.getSubelementToElement(
                     type_subfacet, gt_subfacet);
               } else {
                 conn_subfacet =
                     &mesh_facets.getConnectivity(type_subfacet, gt_subfacet);
                 sf_to_double = &mesh_facets.getData<UInt>(
                     "facet_to_double", type_subfacet, gt_subfacet);
 
                 f_to_subfacet_double =
                     &mesh_facets.getData<std::vector<Element>>(
                         "facets_to_subfacet_double", type_subfacet,
                         gt_subfacet);
 
                 el_to_subfacet_double =
                     &mesh_facets.getData<std::vector<Element>>(
                         "elements_to_subfacet_double", type_subfacet,
                         gt_subfacet);
 
                 facet_to_subfacet = &mesh_facets.getElementToSubelement(
                     type_subfacet, gt_subfacet);
               }
             }
 
             if (subsubfacet_mode) {
               /// loop on every subsubfacet
               for (UInt ssf = 0; ssf < nb_subsubfacet; ++ssf) {
                 Element & subsubfacet =
                     (*subsubfacet_to_subfacet)(subfacet.element, ssf);
 
                 if (subsubfacet == ElementNull)
                   continue;
 
                 if (gt_subsubfacet != subsubfacet.ghost_type) {
                   gt_subsubfacet = subsubfacet.ghost_type;
                   conn_subfacet = &mesh_facets.getConnectivity(type_subsubfacet,
                                                                gt_subsubfacet);
                   sf_to_double = &mesh_facets.getData<UInt>(
                       "facet_to_double", type_subsubfacet, gt_subsubfacet);
 
                   sf_to_subfacet_double =
                       &mesh_facets.getData<std::vector<Element>>(
                           "subfacets_to_subsubfacet_double", type_subsubfacet,
                           gt_subsubfacet);
 
                   f_to_subfacet_double =
                       &mesh_facets.getData<std::vector<Element>>(
                           "facets_to_subfacet_double", type_subsubfacet,
                           gt_subsubfacet);
 
                   el_to_subfacet_double =
                       &mesh_facets.getData<std::vector<Element>>(
                           "elements_to_subfacet_double", type_subsubfacet,
                           gt_subsubfacet);
 
                   facet_to_subfacet = &mesh_facets.getElementToSubelement(
                       type_subsubfacet, gt_subsubfacet);
                 }
 
                 UInt global_ssf = subsubfacet.element;
 
                 Vector<UInt> subsubfacet_connectivity(
                     conn_subfacet->storage() + global_ssf * nb_nodes_per_sf_el,
                     nb_nodes_per_sf_el);
 
                 /// check if subsubfacet is to be doubled
                 if (findElementsAroundSubfacet<true>(
                         mesh, mesh_facets, starting_element, current_facet,
                         subsubfacet_connectivity, element_list, facet_list,
                         subfacet_list) == false &&
                     removeElementsInVector(*subfacet_list,
                                            (*facet_to_subfacet)(global_ssf)) ==
                         false) {
 
                   sf_to_double->push_back(global_ssf);
                   sf_to_subfacet_double->push_back(*subfacet_list);
                   f_to_subfacet_double->push_back(facet_list);
                   el_to_subfacet_double->push_back(element_list);
                 }
               }
             } else {
               const UInt global_sf = subfacet.element;
 
               Vector<UInt> subfacet_connectivity(
                   conn_subfacet->storage() + global_sf * nb_nodes_per_sf_el,
                   nb_nodes_per_sf_el);
 
               /// check if subfacet is to be doubled
               if (findElementsAroundSubfacet<false>(
                       mesh, mesh_facets, starting_element, current_facet,
                       subfacet_connectivity, element_list,
                       facet_list) == false &&
                   removeElementsInVector(
                       facet_list, (*facet_to_subfacet)(global_sf)) == false) {
 
                 sf_to_double->push_back(global_sf);
                 f_to_subfacet_double->push_back(facet_list);
                 el_to_subfacet_double->push_back(element_list);
               }
             }
           }
         }
       }
 
       if (subsubfacet_mode)
         delete subfacet_list;
     }
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 #if defined(AKANTU_COHESIVE_ELEMENT)
 void MeshUtils::updateCohesiveData(Mesh & mesh, Mesh & mesh_facets,
                                    Array<Element> & new_elements) {
   AKANTU_DEBUG_IN();
 
   UInt spatial_dimension = mesh.getSpatialDimension();
   bool third_dimension = spatial_dimension == 3;
 
   MeshAccessor mesh_facets_accessor(mesh_facets);
 
   for (auto gt_facet : ghost_types) {
     for (auto type_facet :
          mesh_facets.elementTypes(spatial_dimension - 1, gt_facet)) {
 
       Array<UInt> & f_to_double =
           mesh_facets.getData<UInt>("facet_to_double", type_facet, gt_facet);
 
       UInt nb_facet_to_double = f_to_double.size();
       if (nb_facet_to_double == 0)
         continue;
 
       ElementType type_cohesive = FEEngine::getCohesiveElementType(type_facet);
 
       auto & facet_to_coh_element =
           mesh_facets_accessor.getSubelementToElement(type_cohesive, gt_facet);
 
       auto & conn_facet = mesh_facets.getConnectivity(type_facet, gt_facet);
       auto & conn_cohesive = mesh.getConnectivity(type_cohesive, gt_facet);
       UInt nb_nodes_per_facet = Mesh::getNbNodesPerElement(type_facet);
 
       Array<std::vector<Element>> & element_to_facet =
           mesh_facets.getElementToSubelement(type_facet, gt_facet);
 
       UInt old_nb_cohesive_elements = conn_cohesive.size();
       UInt new_nb_cohesive_elements = conn_cohesive.size() + nb_facet_to_double;
 
       UInt old_nb_facet = element_to_facet.size() - nb_facet_to_double;
       facet_to_coh_element.resize(new_nb_cohesive_elements);
       conn_cohesive.resize(new_nb_cohesive_elements);
 
       UInt new_elements_old_size = new_elements.size();
       new_elements.resize(new_elements_old_size + nb_facet_to_double);
 
       Element c_element{type_cohesive, 0, gt_facet};
       Element f_element{type_facet, 0, gt_facet};
 
       UInt facets[2];
 
       for (UInt facet = 0; facet < nb_facet_to_double; ++facet) {
 
         /// (in 3D cohesive elements connectivity is inverted)
         facets[third_dimension] = f_to_double(facet);
         facets[!third_dimension] = old_nb_facet + facet;
 
         UInt cohesive_element = old_nb_cohesive_elements + facet;
 
         /// store doubled facets
         f_element.element = facets[0];
         facet_to_coh_element(cohesive_element, 0) = f_element;
         f_element.element = facets[1];
         facet_to_coh_element(cohesive_element, 1) = f_element;
 
         /// modify cohesive elements' connectivity
         for (UInt n = 0; n < nb_nodes_per_facet; ++n) {
           conn_cohesive(cohesive_element, n) = conn_facet(facets[0], n);
           conn_cohesive(cohesive_element, n + nb_nodes_per_facet) =
               conn_facet(facets[1], n);
         }
 
         /// update element_to_facet vectors
         c_element.element = cohesive_element;
         element_to_facet(facets[0])[1] = c_element;
         element_to_facet(facets[1])[1] = c_element;
 
         /// add cohesive element to the element event list
         new_elements(new_elements_old_size + facet) = c_element;
       }
     }
   }
 
   AKANTU_DEBUG_OUT();
 }
 #endif
 
 /* -------------------------------------------------------------------------- */
 void MeshUtils::doublePointFacet(Mesh & mesh, Mesh & mesh_facets,
                                  Array<UInt> & doubled_nodes) {
   AKANTU_DEBUG_IN();
 
   UInt spatial_dimension = mesh.getSpatialDimension();
   if (spatial_dimension != 1)
     return;
 
   Array<Real> & position = mesh.getNodes();
 
   for (ghost_type_t::iterator gt = ghost_type_t::begin();
        gt != ghost_type_t::end(); ++gt) {
 
     GhostType gt_facet = *gt;
 
     Mesh::type_iterator it =
         mesh_facets.firstType(spatial_dimension - 1, gt_facet);
     Mesh::type_iterator end =
         mesh_facets.lastType(spatial_dimension - 1, gt_facet);
 
     for (; it != end; ++it) {
 
       ElementType type_facet = *it;
 
       Array<UInt> & conn_facet =
           mesh_facets.getConnectivity(type_facet, gt_facet);
       Array<std::vector<Element>> & element_to_facet =
           mesh_facets.getElementToSubelement(type_facet, gt_facet);
 
       const Array<UInt> & f_to_double =
           mesh_facets.getData<UInt>("facet_to_double", type_facet, gt_facet);
 
       UInt nb_facet_to_double = f_to_double.size();
 
       UInt old_nb_facet = element_to_facet.size() - nb_facet_to_double;
       UInt new_nb_facet = element_to_facet.size();
 
       UInt old_nb_nodes = position.size();
       UInt new_nb_nodes = old_nb_nodes + nb_facet_to_double;
 
       position.resize(new_nb_nodes);
       conn_facet.resize(new_nb_facet);
 
       UInt old_nb_doubled_nodes = doubled_nodes.size();
       doubled_nodes.resize(old_nb_doubled_nodes + nb_facet_to_double);
 
       for (UInt facet = 0; facet < nb_facet_to_double; ++facet) {
         UInt old_facet = f_to_double(facet);
         UInt new_facet = old_nb_facet + facet;
 
         ElementType type = element_to_facet(new_facet)[0].type;
         UInt el = element_to_facet(new_facet)[0].element;
         GhostType gt = element_to_facet(new_facet)[0].ghost_type;
 
         UInt old_node = conn_facet(old_facet);
         UInt new_node = old_nb_nodes + facet;
 
         /// update position
         position(new_node) = position(old_node);
 
         conn_facet(new_facet) = new_node;
         Array<UInt> & conn_segment = mesh.getConnectivity(type, gt);
         UInt nb_nodes_per_segment = conn_segment.getNbComponent();
 
         /// update facet connectivity
         UInt i;
         for (i = 0;
              conn_segment(el, i) != old_node && i <= nb_nodes_per_segment; ++i)
           ;
         conn_segment(el, i) = new_node;
 
         doubled_nodes(old_nb_doubled_nodes + facet, 0) = old_node;
         doubled_nodes(old_nb_doubled_nodes + facet, 1) = new_node;
       }
     }
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <bool third_dim_segments>
 void MeshUtils::updateQuadraticSegments(Mesh & mesh, Mesh & mesh_facets,
                                         ElementType type_facet,
                                         GhostType gt_facet,
                                         Array<UInt> & doubled_nodes) {
   AKANTU_DEBUG_IN();
 
   if (type_facet != _segment_3)
     return;
 
   Array<UInt> & f_to_double =
       mesh_facets.getData<UInt>("facet_to_double", type_facet, gt_facet);
   UInt nb_facet_to_double = f_to_double.size();
 
   UInt old_nb_facet =
       mesh_facets.getNbElement(type_facet, gt_facet) - nb_facet_to_double;
 
   Array<UInt> & conn_facet = mesh_facets.getConnectivity(type_facet, gt_facet);
 
   Array<std::vector<Element>> & element_to_facet =
       mesh_facets.getElementToSubelement(type_facet, gt_facet);
 
   /// this ones matter only for segments in 3D
   Array<std::vector<Element>> * el_to_subfacet_double = nullptr;
   Array<std::vector<Element>> * f_to_subfacet_double = nullptr;
 
   if (third_dim_segments) {
     el_to_subfacet_double = &mesh_facets.getData<std::vector<Element>>(
         "elements_to_subfacet_double", type_facet, gt_facet);
 
     f_to_subfacet_double = &mesh_facets.getData<std::vector<Element>>(
         "facets_to_subfacet_double", type_facet, gt_facet);
   }
 
   std::vector<UInt> middle_nodes;
 
   for (UInt facet = 0; facet < nb_facet_to_double; ++facet) {
     UInt old_facet = f_to_double(facet);
     UInt node = conn_facet(old_facet, 2);
     if (!mesh.isPureGhostNode(node))
       middle_nodes.push_back(node);
   }
 
   UInt n = doubled_nodes.size();
 
   doubleNodes(mesh, middle_nodes, doubled_nodes);
 
   for (UInt facet = 0; facet < nb_facet_to_double; ++facet) {
     UInt old_facet = f_to_double(facet);
     UInt old_node = conn_facet(old_facet, 2);
     if (mesh.isPureGhostNode(old_node))
       continue;
 
     UInt new_node = doubled_nodes(n, 1);
     UInt new_facet = old_nb_facet + facet;
 
     conn_facet(new_facet, 2) = new_node;
 
     if (third_dim_segments) {
       updateElementalConnectivity(mesh_facets, old_node, new_node,
                                   element_to_facet(new_facet));
 
       updateElementalConnectivity(mesh, old_node, new_node,
                                   (*el_to_subfacet_double)(facet),
                                   &(*f_to_subfacet_double)(facet));
     } else {
       updateElementalConnectivity(mesh, old_node, new_node,
                                   element_to_facet(new_facet));
     }
     ++n;
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void MeshUtils::updateSubfacetToFacet(Mesh & mesh_facets,
                                       ElementType type_subfacet,
                                       GhostType gt_subfacet, bool facet_mode) {
   AKANTU_DEBUG_IN();
 
   Array<UInt> & sf_to_double =
       mesh_facets.getData<UInt>("facet_to_double", type_subfacet, gt_subfacet);
   UInt nb_subfacet_to_double = sf_to_double.size();
 
   /// update subfacet_to_facet vector
   ElementType type_facet = _not_defined;
   GhostType gt_facet = _casper;
   Array<Element> * subfacet_to_facet = nullptr;
   UInt nb_subfacet_per_facet = 0;
   UInt old_nb_subfacet = mesh_facets.getNbElement(type_subfacet, gt_subfacet) -
                          nb_subfacet_to_double;
 
   Array<std::vector<Element>> * facet_list = nullptr;
   if (facet_mode)
     facet_list = &mesh_facets.getData<std::vector<Element>>(
         "facets_to_subfacet_double", type_subfacet, gt_subfacet);
   else
     facet_list = &mesh_facets.getData<std::vector<Element>>(
         "subfacets_to_subsubfacet_double", type_subfacet, gt_subfacet);
 
   Element old_subfacet_el{type_subfacet, 0, gt_subfacet};
   Element new_subfacet_el{type_subfacet, 0, gt_subfacet};
 
   for (UInt sf = 0; sf < nb_subfacet_to_double; ++sf) {
     old_subfacet_el.element = sf_to_double(sf);
     new_subfacet_el.element = old_nb_subfacet + sf;
 
     for (UInt f = 0; f < (*facet_list)(sf).size(); ++f) {
       Element & facet = (*facet_list)(sf)[f];
 
       if (facet.type != type_facet || facet.ghost_type != gt_facet) {
         type_facet = facet.type;
         gt_facet = facet.ghost_type;
 
         subfacet_to_facet =
             &mesh_facets.getSubelementToElement(type_facet, gt_facet);
         nb_subfacet_per_facet = subfacet_to_facet->getNbComponent();
       }
 
       Element * sf_update = std::find(
           subfacet_to_facet->storage() + facet.element * nb_subfacet_per_facet,
           subfacet_to_facet->storage() + facet.element * nb_subfacet_per_facet +
               nb_subfacet_per_facet,
           old_subfacet_el);
 
       AKANTU_DEBUG_ASSERT(subfacet_to_facet->storage() +
                                   facet.element * nb_subfacet_per_facet !=
                               subfacet_to_facet->storage() +
                                   facet.element * nb_subfacet_per_facet +
                                   nb_subfacet_per_facet,
                           "Subfacet not found");
 
       *sf_update = new_subfacet_el;
     }
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void MeshUtils::updateFacetToSubfacet(Mesh & mesh_facets,
                                       ElementType type_subfacet,
                                       GhostType gt_subfacet, bool facet_mode) {
   AKANTU_DEBUG_IN();
 
   Array<UInt> & sf_to_double =
       mesh_facets.getData<UInt>("facet_to_double", type_subfacet, gt_subfacet);
   UInt nb_subfacet_to_double = sf_to_double.size();
 
   Array<std::vector<Element>> & facet_to_subfacet =
       mesh_facets.getElementToSubelement(type_subfacet, gt_subfacet);
 
   Array<std::vector<Element>> * facet_to_subfacet_double = nullptr;
 
   if (facet_mode) {
     facet_to_subfacet_double = &mesh_facets.getData<std::vector<Element>>(
         "facets_to_subfacet_double", type_subfacet, gt_subfacet);
   } else {
     facet_to_subfacet_double = &mesh_facets.getData<std::vector<Element>>(
         "subfacets_to_subsubfacet_double", type_subfacet, gt_subfacet);
   }
 
   UInt old_nb_subfacet = facet_to_subfacet.size();
   facet_to_subfacet.resize(old_nb_subfacet + nb_subfacet_to_double);
 
   for (UInt sf = 0; sf < nb_subfacet_to_double; ++sf)
     facet_to_subfacet(old_nb_subfacet + sf) = (*facet_to_subfacet_double)(sf);
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <UInt spatial_dimension>
 void MeshUtils::doubleSubfacet(Mesh & mesh, Mesh & mesh_facets,
                                Array<UInt> & doubled_nodes) {
   AKANTU_DEBUG_IN();
 
   if (spatial_dimension == 1)
     return;
 
   for (ghost_type_t::iterator gt = ghost_type_t::begin();
        gt != ghost_type_t::end(); ++gt) {
 
     GhostType gt_subfacet = *gt;
 
     Mesh::type_iterator it = mesh_facets.firstType(0, gt_subfacet);
     Mesh::type_iterator end = mesh_facets.lastType(0, gt_subfacet);
 
     for (; it != end; ++it) {
 
       ElementType type_subfacet = *it;
 
       Array<UInt> & sf_to_double = mesh_facets.getData<UInt>(
           "facet_to_double", type_subfacet, gt_subfacet);
       UInt nb_subfacet_to_double = sf_to_double.size();
 
       if (nb_subfacet_to_double == 0)
         continue;
 
       AKANTU_DEBUG_ASSERT(
           type_subfacet == _point_1,
           "Only _point_1 subfacet doubling is supported at the moment");
 
       Array<UInt> & conn_subfacet =
           mesh_facets.getConnectivity(type_subfacet, gt_subfacet);
 
       UInt old_nb_subfacet = conn_subfacet.size();
       UInt new_nb_subfacet = old_nb_subfacet + nb_subfacet_to_double;
 
       conn_subfacet.resize(new_nb_subfacet);
 
       std::vector<UInt> nodes_to_double;
       UInt old_nb_doubled_nodes = doubled_nodes.size();
 
       /// double nodes
       for (UInt sf = 0; sf < nb_subfacet_to_double; ++sf) {
         UInt old_subfacet = sf_to_double(sf);
         nodes_to_double.push_back(conn_subfacet(old_subfacet));
       }
 
       doubleNodes(mesh, nodes_to_double, doubled_nodes);
 
       /// add new nodes in connectivity
       for (UInt sf = 0; sf < nb_subfacet_to_double; ++sf) {
         UInt new_subfacet = old_nb_subfacet + sf;
         UInt new_node = doubled_nodes(old_nb_doubled_nodes + sf, 1);
 
         conn_subfacet(new_subfacet) = new_node;
       }
 
       /// update facet and element connectivity
       Array<std::vector<Element>> & f_to_subfacet_double =
           mesh_facets.getData<std::vector<Element>>("facets_to_subfacet_double",
                                                     type_subfacet, gt_subfacet);
 
       Array<std::vector<Element>> & el_to_subfacet_double =
           mesh_facets.getData<std::vector<Element>>(
               "elements_to_subfacet_double", type_subfacet, gt_subfacet);
 
       Array<std::vector<Element>> * sf_to_subfacet_double = nullptr;
 
       if (spatial_dimension == 3)
         sf_to_subfacet_double = &mesh_facets.getData<std::vector<Element>>(
             "subfacets_to_subsubfacet_double", type_subfacet, gt_subfacet);
 
       for (UInt sf = 0; sf < nb_subfacet_to_double; ++sf) {
         UInt old_node = doubled_nodes(old_nb_doubled_nodes + sf, 0);
         UInt new_node = doubled_nodes(old_nb_doubled_nodes + sf, 1);
 
         updateElementalConnectivity(mesh, old_node, new_node,
                                     el_to_subfacet_double(sf),
                                     &f_to_subfacet_double(sf));
 
         updateElementalConnectivity(mesh_facets, old_node, new_node,
                                     f_to_subfacet_double(sf));
 
         if (spatial_dimension == 3)
           updateElementalConnectivity(mesh_facets, old_node, new_node,
                                       (*sf_to_subfacet_double)(sf));
       }
 
       if (spatial_dimension == 2) {
         updateSubfacetToFacet(mesh_facets, type_subfacet, gt_subfacet, true);
         updateFacetToSubfacet(mesh_facets, type_subfacet, gt_subfacet, true);
       } else if (spatial_dimension == 3) {
         updateSubfacetToFacet(mesh_facets, type_subfacet, gt_subfacet, false);
         updateFacetToSubfacet(mesh_facets, type_subfacet, gt_subfacet, false);
       }
     }
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void MeshUtils::flipFacets(
     Mesh & mesh_facets, const ElementTypeMapArray<UInt> & global_connectivity,
     GhostType gt_facet) {
   AKANTU_DEBUG_IN();
 
   UInt spatial_dimension = mesh_facets.getSpatialDimension();
 
   /// get global connectivity for local mesh
   ElementTypeMapArray<UInt> global_connectivity_tmp("global_connectivity_tmp",
                                                     mesh_facets.getID(),
                                                     mesh_facets.getMemoryID());
 
   global_connectivity_tmp.initialize(
       mesh_facets, _spatial_dimension = spatial_dimension - 1,
       _ghost_type = gt_facet, _with_nb_nodes_per_element = true,
       _with_nb_element = true);
 
   mesh_facets.getGlobalConnectivity(global_connectivity_tmp);
 
   /// loop on every facet
   for (auto type_facet :
        mesh_facets.elementTypes(spatial_dimension - 1, gt_facet)) {
 
     auto & connectivity = mesh_facets.getConnectivity(type_facet, gt_facet);
     const auto & g_connectivity = global_connectivity(type_facet, gt_facet);
 
     auto & el_to_f = mesh_facets.getElementToSubelement(type_facet, gt_facet);
     auto & subfacet_to_facet =
         mesh_facets.getSubelementToElement(type_facet, gt_facet);
 
     UInt nb_subfacet_per_facet = subfacet_to_facet.getNbComponent();
     UInt nb_nodes_per_facet = connectivity.getNbComponent();
     UInt nb_facet = connectivity.size();
 
     UInt nb_nodes_per_P1_facet =
         Mesh::getNbNodesPerElement(Mesh::getP1ElementType(type_facet));
 
     auto & global_conn_tmp = global_connectivity_tmp(type_facet, gt_facet);
 
     auto conn_it = connectivity.begin(nb_nodes_per_facet);
     auto gconn_tmp_it = global_conn_tmp.begin(nb_nodes_per_facet);
     auto conn_glob_it = g_connectivity.begin(nb_nodes_per_facet);
     auto subf_to_f = subfacet_to_facet.begin(nb_subfacet_per_facet);
 
     auto * conn_tmp_pointer = new UInt[nb_nodes_per_facet];
     Vector<UInt> conn_tmp(conn_tmp_pointer, nb_nodes_per_facet);
 
     Element el_tmp;
     auto * subf_tmp_pointer = new Element[nb_subfacet_per_facet];
     Vector<Element> subf_tmp(subf_tmp_pointer, nb_subfacet_per_facet);
 
     for (UInt f = 0; f < nb_facet;
          ++f, ++conn_it, ++gconn_tmp_it, ++subf_to_f, ++conn_glob_it) {
 
       Vector<UInt> & gconn_tmp = *gconn_tmp_it;
       const Vector<UInt> & conn_glob = *conn_glob_it;
       Vector<UInt> & conn_local = *conn_it;
 
       /// skip facet if connectivities are the same
       if (gconn_tmp == conn_glob)
         continue;
 
       /// re-arrange connectivity
       conn_tmp = conn_local;
 
       UInt * begin = conn_glob.storage();
       UInt * end = conn_glob.storage() + nb_nodes_per_facet;
 
       for (UInt n = 0; n < nb_nodes_per_facet; ++n) {
 
         UInt * new_node = std::find(begin, end, gconn_tmp(n));
         AKANTU_DEBUG_ASSERT(new_node != end, "Node not found");
 
         UInt new_position = new_node - begin;
 
         conn_local(new_position) = conn_tmp(n);
       }
 
       /// if 3D, check if facets are just rotated
       if (spatial_dimension == 3) {
         /// find first node
         UInt * new_node = std::find(begin, end, gconn_tmp(0));
         AKANTU_DEBUG_ASSERT(new_node != end, "Node not found");
 
         UInt new_position = new_node - begin;
         UInt n = 1;
 
         /// count how many nodes in the received connectivity follow
         /// the same order of those in the local connectivity
         for (; n < nb_nodes_per_P1_facet &&
                gconn_tmp(n) ==
                    conn_glob((new_position + n) % nb_nodes_per_P1_facet);
              ++n)
           ;
 
         /// skip the facet inversion if facet is just rotated
         if (n == nb_nodes_per_P1_facet)
           continue;
       }
 
       /// update data to invert facet
       el_tmp = el_to_f(f)[0];
       el_to_f(f)[0] = el_to_f(f)[1];
       el_to_f(f)[1] = el_tmp;
 
       subf_tmp = (*subf_to_f);
       (*subf_to_f)(0) = subf_tmp(1);
       (*subf_to_f)(1) = subf_tmp(0);
     }
 
     delete[] subf_tmp_pointer;
     delete[] conn_tmp_pointer;
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void MeshUtils::fillElementToSubElementsData(Mesh & mesh) {
   AKANTU_DEBUG_IN();
 
   if (mesh.getNbElement(mesh.getSpatialDimension() - 1) == 0) {
     AKANTU_DEBUG_INFO("There are not facets, add them in the mesh file or call "
                       "the buildFacet method.");
     return;
   }
 
   UInt spatial_dimension = mesh.getSpatialDimension();
   ElementTypeMapArray<Real> barycenters("barycenter_tmp", mesh.getID(),
                                         mesh.getMemoryID());
   barycenters.initialize(mesh, _nb_component = spatial_dimension,
                          _spatial_dimension = _all_dimensions);
   // mesh.initElementTypeMapArray(barycenters, spatial_dimension,
   // _all_dimensions);
 
   Element element;
   for (auto ghost_type : ghost_types) {
     element.ghost_type = ghost_type;
     for (auto & type : mesh.elementTypes(_all_dimensions, ghost_type)) {
       element.type = type;
 
       UInt nb_element = mesh.getNbElement(type, ghost_type);
       Array<Real> & barycenters_arr = barycenters(type, ghost_type);
       barycenters_arr.resize(nb_element);
       auto bary = barycenters_arr.begin(spatial_dimension);
       auto bary_end = barycenters_arr.end(spatial_dimension);
 
       for (UInt el = 0; bary != bary_end; ++bary, ++el) {
         element.element = el;
         mesh.getBarycenter(element, *bary);
       }
     }
   }
 
   MeshAccessor mesh_accessor(mesh);
   for (Int sp(spatial_dimension); sp >= 1; --sp) {
     if (mesh.getNbElement(sp) == 0)
       continue;
 
     for (auto ghost_type : ghost_types) {
       for (auto & type : mesh.elementTypes(sp, ghost_type)) {
         mesh_accessor.getSubelementToElement(type, ghost_type)
             .resize(mesh.getNbElement(type, ghost_type));
         mesh_accessor.getSubelementToElement(type, ghost_type).clear();
       }
 
       for (auto & type : mesh.elementTypes(sp - 1, ghost_type)) {
         mesh_accessor.getElementToSubelement(type, ghost_type)
             .resize(mesh.getNbElement(type, ghost_type));
         mesh.getElementToSubelement(type, ghost_type).clear();
       }
     }
 
     CSR<Element> nodes_to_elements;
     buildNode2Elements(mesh, nodes_to_elements, sp);
 
     Element facet_element;
 
     for (auto ghost_type : ghost_types) {
       facet_element.ghost_type = ghost_type;
       for (auto & type : mesh.elementTypes(sp - 1, ghost_type)) {
         facet_element.type = type;
 
         auto & element_to_subelement =
             mesh.getElementToSubelement(type, ghost_type);
 
         const auto & connectivity = mesh.getConnectivity(type, ghost_type);
 
         auto fit = connectivity.begin(mesh.getNbNodesPerElement(type));
         auto fend = connectivity.end(mesh.getNbNodesPerElement(type));
 
         UInt fid = 0;
         for (; fit != fend; ++fit, ++fid) {
           const Vector<UInt> & facet = *fit;
           facet_element.element = fid;
           std::map<Element, UInt> element_seen_counter;
           UInt nb_nodes_per_facet =
               mesh.getNbNodesPerElement(Mesh::getP1ElementType(type));
 
           for (UInt n(0); n < nb_nodes_per_facet; ++n) {
 
             auto eit = nodes_to_elements.begin(facet(n));
             auto eend = nodes_to_elements.end(facet(n));
             for (; eit != eend; ++eit) {
               auto & elem = *eit;
               auto cit = element_seen_counter.find(elem);
               if (cit != element_seen_counter.end()) {
                 cit->second++;
               } else {
                 element_seen_counter[elem] = 1;
               }
             }
           }
 
           std::vector<Element> connected_elements;
           auto cit = element_seen_counter.begin();
           auto cend = element_seen_counter.end();
           for (; cit != cend; ++cit) {
             if (cit->second == nb_nodes_per_facet)
               connected_elements.push_back(cit->first);
           }
 
           auto ceit = connected_elements.begin();
           auto ceend = connected_elements.end();
           for (; ceit != ceend; ++ceit)
             element_to_subelement(fid).push_back(*ceit);
 
           for (UInt ce = 0; ce < connected_elements.size(); ++ce) {
             Element & elem = connected_elements[ce];
             Array<Element> & subelement_to_element =
                 mesh_accessor.getSubelementToElement(elem.type,
                                                      elem.ghost_type);
 
             UInt f(0);
             for (; f < mesh.getNbFacetsPerElement(elem.type) &&
                    subelement_to_element(elem.element, f) != ElementNull;
                  ++f)
               ;
 
             AKANTU_DEBUG_ASSERT(
                 f < mesh.getNbFacetsPerElement(elem.type),
                 "The element " << elem << " seems to have too many facets!! ("
                                << f << " < "
                                << mesh.getNbFacetsPerElement(elem.type) << ")");
 
             subelement_to_element(elem.element, f) = facet_element;
           }
         }
       }
     }
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <bool third_dim_points>
 bool MeshUtils::findElementsAroundSubfacet(
     const Mesh & mesh, const Mesh & mesh_facets,
     const Element & starting_element, const Element & end_facet,
     const Vector<UInt> & subfacet_connectivity,
     std::vector<Element> & elem_list, std::vector<Element> & facet_list,
     std::vector<Element> * subfacet_list) {
   AKANTU_DEBUG_IN();
 
   /// preallocated stuff before starting
   bool facet_matched = false;
 
   elem_list.clear();
   facet_list.clear();
 
   if (third_dim_points)
     subfacet_list->clear();
 
   elem_list.push_back(starting_element);
 
   const Array<UInt> * facet_connectivity = nullptr;
   const Array<UInt> * sf_connectivity = nullptr;
   const Array<Element> * facet_to_element = nullptr;
   const Array<Element> * subfacet_to_facet = nullptr;
 
   ElementType current_type = _not_defined;
   GhostType current_ghost_type = _casper;
 
   ElementType current_facet_type = _not_defined;
   GhostType current_facet_ghost_type = _casper;
 
   ElementType current_subfacet_type = _not_defined;
   GhostType current_subfacet_ghost_type = _casper;
 
   const Array<std::vector<Element>> * element_to_facet = nullptr;
 
   const Element * opposing_el = nullptr;
 
   std::queue<Element> elements_to_check;
   elements_to_check.push(starting_element);
 
   /// keep going until there are elements to check
   while (!elements_to_check.empty()) {
 
     /// check current element
     Element & current_el = elements_to_check.front();
 
     if (current_el.type != current_type ||
         current_el.ghost_type != current_ghost_type) {
 
       current_type = current_el.type;
       current_ghost_type = current_el.ghost_type;
 
       facet_to_element =
           &mesh_facets.getSubelementToElement(current_type, current_ghost_type);
     }
 
     /// loop over each facet of the element
     for (UInt f = 0; f < facet_to_element->getNbComponent(); ++f) {
 
       const Element & current_facet =
           (*facet_to_element)(current_el.element, f);
 
       if (current_facet == ElementNull)
         continue;
 
       if (current_facet_type != current_facet.type ||
           current_facet_ghost_type != current_facet.ghost_type) {
 
         current_facet_type = current_facet.type;
         current_facet_ghost_type = current_facet.ghost_type;
 
         element_to_facet = &mesh_facets.getElementToSubelement(
             current_facet_type, current_facet_ghost_type);
         facet_connectivity = &mesh_facets.getConnectivity(
             current_facet_type, current_facet_ghost_type);
 
         if (third_dim_points)
           subfacet_to_facet = &mesh_facets.getSubelementToElement(
               current_facet_type, current_facet_ghost_type);
       }
 
       /// check if end facet is reached
       if (current_facet == end_facet)
         facet_matched = true;
 
       /// add this facet if not already passed
       if (std::find(facet_list.begin(), facet_list.end(), current_facet) ==
               facet_list.end() &&
           hasElement(*facet_connectivity, current_facet,
                      subfacet_connectivity)) {
         facet_list.push_back(current_facet);
 
         if (third_dim_points) {
           /// check subfacets
           for (UInt sf = 0; sf < subfacet_to_facet->getNbComponent(); ++sf) {
             const Element & current_subfacet =
                 (*subfacet_to_facet)(current_facet.element, sf);
 
             if (current_subfacet == ElementNull)
               continue;
 
             if (current_subfacet_type != current_subfacet.type ||
                 current_subfacet_ghost_type != current_subfacet.ghost_type) {
               current_subfacet_type = current_subfacet.type;
               current_subfacet_ghost_type = current_subfacet.ghost_type;
 
               sf_connectivity = &mesh_facets.getConnectivity(
                   current_subfacet_type, current_subfacet_ghost_type);
             }
 
             if (std::find(subfacet_list->begin(), subfacet_list->end(),
                           current_subfacet) == subfacet_list->end() &&
                 hasElement(*sf_connectivity, current_subfacet,
                            subfacet_connectivity))
               subfacet_list->push_back(current_subfacet);
           }
         }
       } else
         continue;
 
       /// consider opposing element
       if ((*element_to_facet)(current_facet.element)[0] == current_el)
         opposing_el = &(*element_to_facet)(current_facet.element)[1];
       else
         opposing_el = &(*element_to_facet)(current_facet.element)[0];
 
       /// skip null elements since they are on a boundary
       if (*opposing_el == ElementNull)
         continue;
 
       /// skip this element if already added
       if (std::find(elem_list.begin(), elem_list.end(), *opposing_el) !=
           elem_list.end())
         continue;
 
       /// only regular elements have to be checked
       if (opposing_el->kind() == _ek_regular)
         elements_to_check.push(*opposing_el);
 
       elem_list.push_back(*opposing_el);
 
 #ifndef AKANTU_NDEBUG
       const Array<UInt> & conn_elem =
           mesh.getConnectivity(opposing_el->type, opposing_el->ghost_type);
 
       AKANTU_DEBUG_ASSERT(
           hasElement(conn_elem, *opposing_el, subfacet_connectivity),
           "Subfacet doesn't belong to this element");
 #endif
     }
 
     /// erased checked element from the list
     elements_to_check.pop();
   }
 
   AKANTU_DEBUG_OUT();
   return facet_matched;
 }
 
 /* -------------------------------------------------------------------------- */
 UInt MeshUtils::updateLocalMasterGlobalConnectivity(Mesh & mesh,
                                                     UInt local_nb_new_nodes) {
   const auto & comm = mesh.getCommunicator();
   Int rank = comm.whoAmI();
   Int nb_proc = comm.getNbProc();
   if (nb_proc == 1)
     return local_nb_new_nodes;
 
   /// resize global ids array
   Array<UInt> & nodes_global_ids = mesh.getGlobalNodesIds();
   UInt old_nb_nodes = mesh.getNbNodes() - local_nb_new_nodes;
 
   nodes_global_ids.resize(mesh.getNbNodes());
 
   /// compute the number of global nodes based on the number of old nodes
   Vector<UInt> old_local_master_nodes(nb_proc);
   for (UInt n = 0; n < old_nb_nodes; ++n)
     if (mesh.isLocalOrMasterNode(n))
       ++old_local_master_nodes(rank);
   comm.allGather(old_local_master_nodes);
   UInt old_global_nodes =
       std::accumulate(old_local_master_nodes.storage(),
                       old_local_master_nodes.storage() + nb_proc, 0);
 
   /// compute amount of local or master doubled nodes
   Vector<UInt> local_master_nodes(nb_proc);
   for (UInt n = old_nb_nodes; n < mesh.getNbNodes(); ++n)
     if (mesh.isLocalOrMasterNode(n))
       ++local_master_nodes(rank);
 
   comm.allGather(local_master_nodes);
 
   /// update global number of nodes
   UInt total_nb_new_nodes = std::accumulate(
       local_master_nodes.storage(), local_master_nodes.storage() + nb_proc, 0);
 
   if (total_nb_new_nodes == 0)
     return 0;
 
   /// set global ids of local and master nodes
   UInt starting_index =
       std::accumulate(local_master_nodes.storage(),
                       local_master_nodes.storage() + rank, old_global_nodes);
 
   for (UInt n = old_nb_nodes; n < mesh.getNbNodes(); ++n) {
     if (mesh.isLocalOrMasterNode(n)) {
       nodes_global_ids(n) = starting_index;
       ++starting_index;
     }
   }
 
   MeshAccessor mesh_accessor(mesh);
   mesh_accessor.setNbGlobalNodes(old_global_nodes + total_nb_new_nodes);
   return total_nb_new_nodes;
 }
 
 /* -------------------------------------------------------------------------- */
 void MeshUtils::updateElementalConnectivity(
     Mesh & mesh, UInt old_node, UInt new_node,
     const std::vector<Element> & element_list,
     __attribute__((unused)) const std::vector<Element> * facet_list) {
   AKANTU_DEBUG_IN();
 
   ElementType el_type = _not_defined;
   GhostType gt_type = _casper;
   Array<UInt> * conn_elem = nullptr;
 #if defined(AKANTU_COHESIVE_ELEMENT)
   const Array<Element> * cohesive_facets = nullptr;
 #endif
   UInt nb_nodes_per_element = 0;
   UInt * n_update = nullptr;
 
   for (UInt el = 0; el < element_list.size(); ++el) {
     const Element & elem = element_list[el];
     if (elem.type == _not_defined)
       continue;
 
     if (elem.type != el_type || elem.ghost_type != gt_type) {
       el_type = elem.type;
       gt_type = elem.ghost_type;
       conn_elem = &mesh.getConnectivity(el_type, gt_type);
       nb_nodes_per_element = conn_elem->getNbComponent();
 #if defined(AKANTU_COHESIVE_ELEMENT)
       if (elem.kind() == _ek_cohesive)
         cohesive_facets =
             &mesh.getMeshFacets().getSubelementToElement(el_type, gt_type);
 #endif
     }
 
 #if defined(AKANTU_COHESIVE_ELEMENT)
     if (elem.kind() == _ek_cohesive) {
 
       AKANTU_DEBUG_ASSERT(
           facet_list != nullptr,
           "Provide a facet list in order to update cohesive elements");
 
       /// loop over cohesive element's facets
       for (UInt f = 0, n = 0; f < 2; ++f, n += nb_nodes_per_element / 2) {
         const Element & facet = (*cohesive_facets)(elem.element, f);
 
         /// skip facets if not present in the list
         if (std::find(facet_list->begin(), facet_list->end(), facet) ==
             facet_list->end())
           continue;
 
         n_update = std::find(
             conn_elem->storage() + elem.element * nb_nodes_per_element + n,
             conn_elem->storage() + elem.element * nb_nodes_per_element + n +
                 nb_nodes_per_element / 2,
             old_node);
 
         AKANTU_DEBUG_ASSERT(n_update !=
                                 conn_elem->storage() +
                                     elem.element * nb_nodes_per_element + n +
                                     nb_nodes_per_element / 2,
                             "Node not found in current element");
 
         /// update connectivity
         *n_update = new_node;
       }
     } else {
 #endif
       n_update =
           std::find(conn_elem->storage() + elem.element * nb_nodes_per_element,
                     conn_elem->storage() + elem.element * nb_nodes_per_element +
                         nb_nodes_per_element,
                     old_node);
 
       AKANTU_DEBUG_ASSERT(n_update !=
                               conn_elem->storage() +
                                   elem.element * nb_nodes_per_element +
                                   nb_nodes_per_element,
                           "Node not found in current element");
 
       /// update connectivity
       *n_update = new_node;
 #if defined(AKANTU_COHESIVE_ELEMENT)
     }
 #endif
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 } // namespace akantu
diff --git a/src/mesh_utils/mesh_utils.hh b/src/mesh_utils/mesh_utils.hh
index f7af08129..51932d972 100644
--- a/src/mesh_utils/mesh_utils.hh
+++ b/src/mesh_utils/mesh_utils.hh
@@ -1,244 +1,243 @@
 /**
  * @file   mesh_utils.hh
  *
  * @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
  * @author Dana Christen <dana.christen@epfl.ch>
  * @author David Simon Kammer <david.kammer@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  * @author Leonardo Snozzi <leonardo.snozzi@epfl.ch>
  * @author Marco Vocialta <marco.vocialta@epfl.ch>
  *
  * @date creation: Fri Jun 18 2010
- * @date last modification: Fri Oct 02 2015
+ * @date last modification: Sun Dec 03 2017
  *
  * @brief  All mesh utils necessary for various tasks
  *
  * @section LICENSE
  *
- * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
- * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
- * Solides)
+ * 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
+ * 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
+ * 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 "aka_csr.hh"
 #include "mesh.hh"
 /* -------------------------------------------------------------------------- */
 
 #include <vector>
 
 /* -------------------------------------------------------------------------- */
 #ifndef __AKANTU_MESH_UTILS_HH__
 #define __AKANTU_MESH_UTILS_HH__
 
 /* -------------------------------------------------------------------------- */
 namespace akantu {
 
 class MeshUtils {
 
   /* ------------------------------------------------------------------------ */
   /* Methods                                                                  */
   /* ------------------------------------------------------------------------ */
 public:
   /// build a CSR<UInt> that contains for each node the linearized number of
   /// the connected elements of a given spatial dimension
   // static void buildNode2Elements(const Mesh & mesh, CSR<UInt> & node_to_elem,
   //                                UInt spatial_dimension = _all_dimensions);
 
   /// build a CSR<Element> that contains for each node the list of connected
   /// elements of a given spatial dimension
   static void buildNode2Elements(const Mesh & mesh, CSR<Element> & node_to_elem,
                                  UInt spatial_dimension = _all_dimensions);
 
   /// build a CSR<UInt> that contains for each node the number of
   /// the connected elements of a given ElementType
   static void
   buildNode2ElementsElementTypeMap(const Mesh & mesh, CSR<UInt> & node_to_elem,
                                    const ElementType & type,
                                    const GhostType & ghost_type = _not_ghost);
 
   /// build the facets elements on the boundaries of a mesh
   static void buildFacets(Mesh & mesh);
 
   /// build all the facets elements: boundary and internals and store them in
   /// the mesh_facets for element of dimension from_dimension to to_dimension
   static void buildAllFacets(const Mesh & mesh, Mesh & mesh_facets,
                              UInt from_dimension, UInt to_dimension);
 
   /// build all the facets elements: boundary and internals and store them in
   /// the mesh_facets
   static void buildAllFacets(const Mesh & mesh, Mesh & mesh_facets,
                              UInt to_dimension = 0);
 
   /// build facets for a given spatial dimension
   static void buildFacetsDimension(const Mesh & mesh, Mesh & mesh_facets,
                                    bool boundary_only, UInt dimension);
 
   /// take the local_connectivity array as the array of local and ghost
   /// connectivity, renumber the nodes and set the connectivity of the mesh
   static void renumberMeshNodes(Mesh & mesh, Array<UInt> & local_connectivities,
                                 UInt nb_local_element, UInt nb_ghost_element,
                                 ElementType type, Array<UInt> & old_nodes);
 
   /// compute pbc pair for a given direction
   static void computePBCMap(const Mesh & mymesh, const UInt dir,
                             std::map<UInt, UInt> & pbc_pair);
   /// compute pbc pair for a surface pair
   static void computePBCMap(const Mesh & mymesh,
                             const std::pair<ID, ID> & surface_pair,
                             std::map<UInt, UInt> & pbc_pair);
 
   /// remove not connected nodes /!\ this functions renumbers the nodes.
   static void purifyMesh(Mesh & mesh);
 
 #if defined(AKANTU_COHESIVE_ELEMENT)
   /// function to insert cohesive elements on the selected facets
   /// @return number of facets that have been doubled
   static UInt
   insertCohesiveElements(Mesh & mesh, Mesh & mesh_facets,
                          const ElementTypeMapArray<bool> & facet_insertion,
                          Array<UInt> & doubled_nodes,
                          Array<Element> & new_elements,
                          bool only_double_facets);
 #endif
 
   /// fill the subelement to element and the elements to subelements data
   static void fillElementToSubElementsData(Mesh & mesh);
 
   /// flip facets based on global connectivity
   static void flipFacets(Mesh & mesh_facets,
                          const ElementTypeMapArray<UInt> & global_connectivity,
                          GhostType gt_facet);
 
   /// provide list of elements around a node and check if a given
   /// facet is reached
   template <bool third_dim_points>
   static bool findElementsAroundSubfacet(
       const Mesh & mesh, const Mesh & mesh_facets,
       const Element & starting_element, const Element & end_facet,
       const Vector<UInt> & subfacet_connectivity,
       std::vector<Element> & elem_list, std::vector<Element> & facet_list,
       std::vector<Element> * subfacet_list = nullptr);
 
   /// function to check if a node belongs to a given element
   static inline bool hasElement(const Array<UInt> & connectivity,
                                 const Element & el, const Vector<UInt> & nodes);
 
   /// reset facet_to_double arrays in the Mesh
   static void resetFacetToDouble(Mesh & mesh_facets);
 
   /// associate a node type to each segment in the mesh
   // static void buildSegmentToNodeType(const Mesh & mesh, Mesh & mesh_facets);
 
   /// update local and master global connectivity when new nodes are added
   static UInt updateLocalMasterGlobalConnectivity(Mesh & mesh,
                                                   UInt old_nb_nodes);
 
 private:
   /// match pairs that are on the associated pbc's
   static void matchPBCPairs(const Mesh & mymesh, const UInt dir,
                             Array<UInt> & selected_left,
                             Array<UInt> & selected_right,
                             std::map<UInt, UInt> & pbc_pair);
 
   /// function used by all the renumbering functions
   static void
   renumberNodesInConnectivity(Array<UInt> & list_nodes, UInt nb_nodes,
                               std::map<UInt, UInt> & renumbering_map);
 
   /// update facet_to_subfacet
   static void updateFacetToSubfacet(Mesh & mesh_facets,
                                     ElementType type_subfacet,
                                     GhostType gt_subfacet, bool facet_mode);
 
   /// update subfacet_to_facet
   static void updateSubfacetToFacet(Mesh & mesh_facets,
                                     ElementType type_subfacet,
                                     GhostType gt_subfacet, bool facet_mode);
 
   /// function to double a given facet and update the list of doubled
   /// nodes
   static void doubleFacet(Mesh & mesh, Mesh & mesh_facets, UInt facet_dimension,
                           Array<UInt> & doubled_nodes, bool facet_mode);
 
   /// function to double a subfacet given start and end index for
   /// local facet_to_subfacet vector, and update the list of doubled
   /// nodes
   template <UInt spatial_dimension>
   static void doubleSubfacet(Mesh & mesh, Mesh & mesh_facets,
                              Array<UInt> & doubled_nodes);
 
   /// double a node
   static void doubleNodes(Mesh & mesh, const std::vector<UInt> & old_nodes,
                           Array<UInt> & doubled_nodes);
 
   /// fill facet_to_double array in the mesh
   /// returns the number of facets to be doubled
   static UInt
   updateFacetToDouble(Mesh & mesh_facets,
                       const ElementTypeMapArray<bool> & facet_insertion);
 
   /// find subfacets to be doubled
   template <bool subsubfacet_mode>
   static void findSubfacetToDouble(Mesh & mesh, Mesh & mesh_facets);
 
   /// double facets (points) in 1D
   static void doublePointFacet(Mesh & mesh, Mesh & mesh_facets,
                                Array<UInt> & doubled_nodes);
 
 #if defined(AKANTU_COHESIVE_ELEMENT)
   /// update cohesive element data
   static void updateCohesiveData(Mesh & mesh, Mesh & mesh_facets,
                                  Array<Element> & new_elements);
 #endif
 
   /// update elemental connectivity after doubling a node
   inline static void updateElementalConnectivity(
       Mesh & mesh, UInt old_node, UInt new_node,
       const std::vector<Element> & element_list,
       const std::vector<Element> * facet_list = nullptr);
 
   /// double middle nodes if facets are _segment_3
   template <bool third_dim_segments>
   static void updateQuadraticSegments(Mesh & mesh, Mesh & mesh_facets,
                                       ElementType type_facet,
                                       GhostType gt_facet,
                                       Array<UInt> & doubled_nodes);
 
   /// remove elements on a vector
   inline static bool
   removeElementsInVector(const std::vector<Element> & elem_to_remove,
                          std::vector<Element> & elem_list);
 
   /* ------------------------------------------------------------------------ */
   /* Accessors                                                                */
   /* ------------------------------------------------------------------------ */
 public:
   /* ------------------------------------------------------------------------ */
   /* Class Members                                                            */
   /* ------------------------------------------------------------------------ */
 private:
 };
 
 /* -------------------------------------------------------------------------- */
 /* inline functions                                                           */
 /* -------------------------------------------------------------------------- */
 #include "mesh_utils_inline_impl.cc"
 
 } // akantu
 #endif /* __AKANTU_MESH_UTILS_HH__ */
diff --git a/src/mesh_utils/mesh_utils_distribution.cc b/src/mesh_utils/mesh_utils_distribution.cc
index c6e00425b..416eb5c45 100644
--- a/src/mesh_utils/mesh_utils_distribution.cc
+++ b/src/mesh_utils/mesh_utils_distribution.cc
@@ -1,172 +1,174 @@
 /**
  * @file   mesh_utils_distribution.cc
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
- * @date   Sun Oct  2 19:23:15 2016
+ * @date creation: Tue Nov 08 2016
+ * @date last modification: Tue Nov 07 2017
  *
  * @brief  Implementation of the methods of mesh  utils distribute
  *
  * @section LICENSE
  *
- * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * 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
+ * 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
+ * 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 "mesh_utils_distribution.hh"
 #include "element_info_per_processor.hh"
 #include "element_synchronizer.hh"
 #include "mesh.hh"
 #include "mesh_accessor.hh"
 #include "mesh_partition.hh"
 #include "mesh_utils.hh"
 #include "node_info_per_processor.hh"
 #include "node_synchronizer.hh"
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 
 namespace MeshUtilsDistribution {
   /* ------------------------------------------------------------------------ */
   void distributeMeshCentralized(Mesh & mesh, UInt,
                                  const MeshPartition & partition) {
     MeshAccessor mesh_accessor(mesh);
     ElementSynchronizer & element_synchronizer =
         mesh_accessor.getElementSynchronizer();
     NodeSynchronizer & node_synchronizer = mesh_accessor.getNodeSynchronizer();
 
     const Communicator & comm = element_synchronizer.getCommunicator();
 
     UInt nb_proc = comm.getNbProc();
     UInt my_rank = comm.whoAmI();
 
     mesh_accessor.setNbGlobalNodes(mesh.getNbNodes());
     auto & gids = mesh_accessor.getNodesGlobalIds();
 
     if (nb_proc == 1)
       return;
 
     gids.resize(0);
 
     mesh.synchronizeGroupNames();
 
     AKANTU_DEBUG_ASSERT(
         partition.getNbPartition() == nb_proc,
         "The number of partition does not match the number of processors: "
             << partition.getNbPartition() << " != " << nb_proc);
 
     /**
      * connectivity and communications scheme construction
      */
     UInt count = 0;
     /* --- MAIN LOOP ON TYPES --- */
     for (auto && type :
          mesh.elementTypes(_all_dimensions, _not_ghost, _ek_not_defined)) {
       /// \todo change this ugly way to avoid a problem if an element
       /// type is present in the mesh but not in the partitions
       try {
         partition.getPartition(type, _not_ghost);
       } catch (...) {
         continue;
       }
 
       MasterElementInfoPerProc proc_infos(element_synchronizer, count, my_rank,
                                           type, partition);
       proc_infos.synchronizeConnectivities();
       proc_infos.synchronizePartitions();
       proc_infos.synchronizeTags();
       proc_infos.synchronizeGroups();
       ++count;
     }
 
     { /// Ending the synchronization of elements by sending a stop message
       MasterElementInfoPerProc proc_infos(element_synchronizer, count, my_rank,
                                           _not_defined, partition);
       ++count;
     }
 
     /**
      * Nodes synchronization
      */
     MasterNodeInfoPerProc node_proc_infos(node_synchronizer, count, my_rank);
     node_proc_infos.synchronizeNodes();
     node_proc_infos.synchronizeTypes();
     node_proc_infos.synchronizeGroups();
 
     MeshUtils::fillElementToSubElementsData(mesh);
 
     mesh_accessor.setDistributed();
 
     AKANTU_DEBUG_OUT();
   }
 
   /* ------------------------------------------------------------------------ */
   void distributeMeshCentralized(Mesh & mesh, UInt root) {
     MeshAccessor mesh_accessor(mesh);
     ElementSynchronizer & element_synchronizer =
         mesh_accessor.getElementSynchronizer();
     NodeSynchronizer & node_synchronizer = mesh_accessor.getNodeSynchronizer();
 
     const Communicator & comm = element_synchronizer.getCommunicator();
 
     UInt nb_proc = comm.getNbProc();
 
     mesh_accessor.getNodesGlobalIds().resize(0);
 
     if (nb_proc == 1)
       return;
 
     mesh.synchronizeGroupNames();
 
     /**
      * connectivity and communications scheme construction on distant
      * processors
      */
     UInt count = 0;
     bool need_synchronize = true;
     do {
       /* --------<<<<-SIZE--------------------------------------------------- */
       SlaveElementInfoPerProc proc_infos(element_synchronizer, count, root);
       need_synchronize = proc_infos.needSynchronize();
 
       if (need_synchronize) {
         proc_infos.synchronizeConnectivities();
         proc_infos.synchronizePartitions();
         proc_infos.synchronizeTags();
         proc_infos.synchronizeGroups();
       }
       ++count;
     } while (need_synchronize);
 
     /**
      * Nodes synchronization
      */
 
     SlaveNodeInfoPerProc node_proc_infos(node_synchronizer, count, root);
 
     node_proc_infos.synchronizeNodes();
     node_proc_infos.synchronizeTypes();
     node_proc_infos.synchronizeGroups();
 
     MeshUtils::fillElementToSubElementsData(mesh);
 
     mesh_accessor.setDistributed();
   }
 
 } // namespace MeshUtilsDistribution
 
 } // namespace akantu
diff --git a/src/mesh_utils/mesh_utils_distribution.hh b/src/mesh_utils/mesh_utils_distribution.hh
index e498a6ae7..82112b2dc 100644
--- a/src/mesh_utils/mesh_utils_distribution.hh
+++ b/src/mesh_utils/mesh_utils_distribution.hh
@@ -1,54 +1,55 @@
 /**
  * @file   mesh_utils_distribution.hh
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
- * @date   Sun Oct  2 19:04:13 2016
+ * @date creation: Fri Jun 18 2010
+ * @date last modification: Sat Apr 01 2017
  *
  * @brief  Mesh utils to distribute a mesh
  *
  * @section LICENSE
  *
- * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * 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
+ * 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
+ * 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"
 /* -------------------------------------------------------------------------- */
 
 #ifndef __AKANTU_MESH_UTILS_DISTRIBUTION_HH__
 #define __AKANTU_MESH_UTILS_DISTRIBUTION_HH__
 
 namespace akantu {
 class Mesh;
 class MeshPartition;
 } // akantu
 
 namespace akantu {
 namespace MeshUtilsDistribution {
   /// Master call to distribute a mesh in a centralized manner (the UInt is just
   /// to avoid some shitty access from the slave...)
   void distributeMeshCentralized(Mesh & mesh, UInt,
                                  const MeshPartition & partition);
   /// Slave call to distribute a mesh in a centralized manner
   void distributeMeshCentralized(Mesh & mesh, UInt root);
 } // MeshUtilsDistribution
 
 } // akantu
 
 #endif /* __AKANTU_MESH_UTILS_DISTRIBUTION_HH__ */
diff --git a/src/mesh_utils/mesh_utils_inline_impl.cc b/src/mesh_utils/mesh_utils_inline_impl.cc
index 4c7c8bf27..0a48d9e57 100644
--- a/src/mesh_utils/mesh_utils_inline_impl.cc
+++ b/src/mesh_utils/mesh_utils_inline_impl.cc
@@ -1,82 +1,81 @@
 /**
  * @file   mesh_utils_inline_impl.cc
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  * @author Marco Vocialta <marco.vocialta@epfl.ch>
  *
  * @date creation: Fri Aug 20 2010
- * @date last modification: Fri Mar 20 2015
+ * @date last modification: Wed Nov 08 2017
  *
  * @brief  Mesh utils inline functions
  *
  * @section LICENSE
  *
- * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
- * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
- * Solides)
+ * 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
+ * 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
+ * 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/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 inline bool MeshUtils::hasElement(const Array<UInt> & connectivity,
                                   const Element & el,
                                   const Vector<UInt> & nodes) {
 
   UInt nb_nodes_per_element = connectivity.getNbComponent();
 
   const Vector<UInt> el_nodes(connectivity.storage() +
                                   el.element * nb_nodes_per_element,
                               nb_nodes_per_element);
   UInt * el_nodes_end = el_nodes.storage() + nb_nodes_per_element;
 
   UInt n = 0;
 
   while (n < nodes.size() &&
          std::find(el_nodes.storage(), el_nodes_end, nodes[n]) != el_nodes_end)
     ++n;
 
   return (n == nodes.size());
 }
 
 /* -------------------------------------------------------------------------- */
 
 /* -------------------------------------------------------------------------- */
 inline bool
 MeshUtils::removeElementsInVector(const std::vector<Element> & elem_to_remove,
                                   std::vector<Element> & elem_list) {
   if (elem_list.size() <= elem_to_remove.size())
     return true;
 
   auto el_it = elem_to_remove.begin();
   auto el_last = elem_to_remove.end();
   std::vector<Element>::iterator el_del;
 
   UInt deletions = 0;
 
   for (; el_it != el_last; ++el_it) {
     el_del = std::find(elem_list.begin(), elem_list.end(), *el_it);
 
     if (el_del != elem_list.end()) {
       elem_list.erase(el_del);
       ++deletions;
     }
   }
 
   AKANTU_DEBUG_ASSERT(deletions == 0 || deletions == elem_to_remove.size(),
                       "Not all elements have been erased");
 
   return deletions == 0;
 }
diff --git a/src/mesh_utils/mesh_utils_pbc.cc b/src/mesh_utils/mesh_utils_pbc.cc
index ac6a05a95..ad44e0ae7 100644
--- a/src/mesh_utils/mesh_utils_pbc.cc
+++ b/src/mesh_utils/mesh_utils_pbc.cc
@@ -1,300 +1,299 @@
 /**
  * @file   mesh_utils_pbc.cc
  *
  * @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
  * @author David Simon Kammer <david.kammer@epfl.ch>
  *
  * @date creation: Wed Feb 09 2011
- * @date last modification: Tue Sep 15 2015
+ * @date last modification: Tue Feb 20 2018
  *
  * @brief  periodic boundary condition connectivity tweak
  *
  * @section LICENSE
  *
- * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
- * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
- * Solides)
+ * 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
+ * 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
+ * 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 <map>
 /* -------------------------------------------------------------------------- */
 #include "element_group.hh"
 #include "mesh_accessor.hh"
 #include "mesh_utils.hh"
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 /// class that sorts a set of nodes of same coordinates in 'dir' direction
 class CoordinatesComparison {
 public:
   CoordinatesComparison(const UInt dimension, const UInt dir_1,
                         const UInt dir_2, Real normalization, Real tolerance,
                         const Array<Real> & coords)
       : dim(dimension), dir_1(dir_1), dir_2(dir_2),
         normalization(normalization), tolerance(tolerance),
         coords_it(coords.begin(dim)) {}
   // answers the question whether n2 is larger or equal to n1
   bool operator()(const UInt n1, const UInt n2) {
     Vector<Real> coords_n1 = coords_it[n1];
     Vector<Real> coords_n2 = coords_it[n2];
     return this->operator()(coords_n1, coords_n2);
   }
 
   bool operator()(const Vector<Real> & coords_n1,
                   const Vector<Real> & coords_n2) {
     Real diff = coords_n1(dir_1) - coords_n2(dir_1);
     ;
     if (dim == 2 || std::abs(diff) / normalization > tolerance)
       return diff > 0. ? false : true;
     else if (dim > 2) {
       diff = coords_n1(dir_2) - coords_n2(dir_2);
       ;
       return diff > 0 ? false : true;
     }
     return true;
   }
 
 private:
   UInt dim;
   UInt dir_1;
   UInt dir_2;
   Real normalization;
   Real tolerance;
   const Array<Real>::const_vector_iterator coords_it;
 };
 
 /* -------------------------------------------------------------------------- */
 void MeshUtils::computePBCMap(const Mesh & mesh, const UInt dir,
                               std::map<UInt, UInt> & pbc_pair) {
   Array<UInt> selected_left;
   Array<UInt> selected_right;
 
   const UInt dim = mesh.getSpatialDimension();
   auto it = mesh.getNodes().begin(dim);
   auto end = mesh.getNodes().end(dim);
 
   if (dim <= dir)
     return;
 
   const Vector<Real> & lower_bounds = mesh.getLowerBounds();
   const Vector<Real> & upper_bounds = mesh.getUpperBounds();
 
   AKANTU_DEBUG_INFO("min " << lower_bounds(dir));
   AKANTU_DEBUG_INFO("max " << upper_bounds(dir));
 
   for (UInt node = 0; it != end; ++it, ++node) {
     const Vector<Real> & coords = *it;
     AKANTU_DEBUG_TRACE("treating " << coords(dir));
     if (Math::are_float_equal(coords(dir), lower_bounds(dir))) {
       AKANTU_DEBUG_TRACE("pushing node " << node << " on the left side");
       selected_left.push_back(node);
     } else if (Math::are_float_equal(coords(dir), upper_bounds(dir))) {
       selected_right.push_back(node);
       AKANTU_DEBUG_TRACE("pushing node " << node << " on the right side");
     }
   }
 
   AKANTU_DEBUG_INFO("found "
                     << selected_left.size() << " and " << selected_right.size()
                     << " nodes at each boundary for direction " << dir);
 
   // match pairs
   MeshUtils::matchPBCPairs(mesh, dir, selected_left, selected_right, pbc_pair);
 }
 
 /* -------------------------------------------------------------------------- */
 void MeshUtils::computePBCMap(const Mesh & mesh,
                               const std::pair<ID, ID> & surface_pair,
                               std::map<UInt, UInt> & pbc_pair) {
 
   Array<UInt> selected_first;
   Array<UInt> selected_second;
 
   // find nodes on surfaces
   const ElementGroup & first_surf = mesh.getElementGroup(surface_pair.first);
   const ElementGroup & second_surf = mesh.getElementGroup(surface_pair.second);
 
   // if this surface pair is not on this proc
   if (first_surf.getNbNodes() == 0 || second_surf.getNbNodes() == 0) {
     AKANTU_DEBUG_WARNING("computePBCMap has at least one surface without any "
                          "nodes. I will ignore it.");
     return;
   }
 
   // copy nodes from element group
   selected_first.copy(first_surf.getNodeGroup().getNodes());
   selected_second.copy(second_surf.getNodeGroup().getNodes());
 
   // coordinates
   const Array<Real> & coords = mesh.getNodes();
   const UInt dim = mesh.getSpatialDimension();
 
   // variables to find min and max of surfaces
   Real first_max[3], first_min[3];
   Real second_max[3], second_min[3];
   for (UInt i = 0; i < dim; ++i) {
     first_min[i] = std::numeric_limits<Real>::max();
     second_min[i] = std::numeric_limits<Real>::max();
     first_max[i] = -std::numeric_limits<Real>::max();
     second_max[i] = -std::numeric_limits<Real>::max();
   }
 
   // find min and max of surface nodes
   for (auto it = selected_first.begin(); it != selected_first.end(); ++it) {
     for (UInt i = 0; i < dim; ++i) {
       if (first_min[i] > coords(*it, i))
         first_min[i] = coords(*it, i);
       if (first_max[i] < coords(*it, i))
         first_max[i] = coords(*it, i);
     }
   }
   for (auto it = selected_second.begin(); it != selected_second.end(); ++it) {
     for (UInt i = 0; i < dim; ++i) {
       if (second_min[i] > coords(*it, i))
         second_min[i] = coords(*it, i);
       if (second_max[i] < coords(*it, i))
         second_max[i] = coords(*it, i);
     }
   }
 
   // find direction of pbc
   Int first_dir = -1;
 #ifndef AKANTU_NDEBUG
   Int second_dir = -2;
 #endif
   for (UInt i = 0; i < dim; ++i) {
     if (Math::are_float_equal(first_min[i], first_max[i])) {
       first_dir = i;
     }
 #ifndef AKANTU_NDEBUG
     if (Math::are_float_equal(second_min[i], second_max[i])) {
       second_dir = i;
     }
 #endif
   }
 
   AKANTU_DEBUG_ASSERT(first_dir == second_dir,
                       "Surface pair has not same direction. Surface "
                           << surface_pair.first << " dir=" << first_dir
                           << " ; Surface " << surface_pair.second
                           << " dir=" << second_dir);
   UInt dir = first_dir;
 
   // match pairs
   if (first_min[dir] < second_min[dir])
     MeshUtils::matchPBCPairs(mesh, dir, selected_first, selected_second,
                              pbc_pair);
   else
     MeshUtils::matchPBCPairs(mesh, dir, selected_second, selected_first,
                              pbc_pair);
 }
 
 /* -------------------------------------------------------------------------- */
 void MeshUtils::matchPBCPairs(const Mesh & mesh, const UInt dir,
                               Array<UInt> & selected_left,
                               Array<UInt> & selected_right,
                               std::map<UInt, UInt> & pbc_pair) {
 
   // tolerance is that large because most meshers generate points coordinates
   // with single precision only (it is the case of GMSH for instance)
   Real tolerance = 1e-7;
   const UInt dim = mesh.getSpatialDimension();
   Real normalization = mesh.getUpperBounds()(dir) - mesh.getLowerBounds()(dir);
 
   AKANTU_DEBUG_ASSERT(std::abs(normalization) > Math::getTolerance(),
                       "In matchPBCPairs: The normalization is zero. "
                           << "Did you compute the bounding box of the mesh?");
 
   auto odir_1 = UInt(-1), odir_2 = UInt(-1);
 
   if (dim == 3) {
     if (dir == _x) {
       odir_1 = _y;
       odir_2 = _z;
     } else if (dir == _y) {
       odir_1 = _x;
       odir_2 = _z;
     } else if (dir == _z) {
       odir_1 = _x;
       odir_2 = _y;
     }
   } else if (dim == 2) {
     if (dir == _x) {
       odir_1 = _y;
     } else if (dir == _y) {
       odir_1 = _x;
     }
   }
 
   CoordinatesComparison compare_nodes(dim, odir_1, odir_2, normalization,
                                       tolerance, mesh.getNodes());
 
   std::sort(selected_left.begin(), selected_left.end(), compare_nodes);
   std::sort(selected_right.begin(), selected_right.end(), compare_nodes);
 
   auto it_left = selected_left.begin();
   auto end_left = selected_left.end();
 
   auto it_right = selected_right.begin();
   auto end_right = selected_right.end();
 
   auto nit = mesh.getNodes().begin(dim);
 
   while ((it_left != end_left) && (it_right != end_right)) {
     UInt i1 = *it_left;
     UInt i2 = *it_right;
 
     Vector<Real> coords1 = nit[i1];
     Vector<Real> coords2 = nit[i2];
 
     AKANTU_DEBUG_TRACE("do I pair? " << i1 << "(" << coords1 << ") with" << i2
                                      << "(" << coords2 << ") in direction "
                                      << dir);
 
     Real dx = 0.0;
     Real dy = 0.0;
     if (dim >= 2)
       dx = coords1(odir_1) - coords2(odir_1);
     if (dim == 3)
       dy = coords1(odir_2) - coords2(odir_2);
 
     if (std::abs(dx * dx + dy * dy) / normalization < tolerance) {
       // then i match these pairs
       if (pbc_pair.count(i2)) {
         i2 = pbc_pair[i2];
       }
       pbc_pair[i1] = i2;
 
       AKANTU_DEBUG_TRACE("pairing " << i1 << "(" << coords1 << ") with" << i2
                                     << "(" << coords2 << ") in direction "
                                     << dir);
       ++it_left;
       ++it_right;
     } else if (compare_nodes(coords1, coords2)) {
       ++it_left;
     } else {
       ++it_right;
     }
   }
   AKANTU_DEBUG_INFO("found " << pbc_pair.size() << " pairs for direction "
                              << dir);
 }
 
 } // akantu
diff --git a/src/model/boundary_condition.hh b/src/model/boundary_condition.hh
index dd7775b2f..82a5b154b 100644
--- a/src/model/boundary_condition.hh
+++ b/src/model/boundary_condition.hh
@@ -1,101 +1,101 @@
 /**
  * @file   boundary_condition.hh
  *
  * @author Dana Christen <dana.christen@gmail.com>
+ * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Fri Jun 18 2010
- * @date last modification: Fri Dec 18 2015
+ * @date last modification: Wed Jan 31 2018
  *
  * @brief  XXX
  *
  * @section LICENSE
  *
- * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
- * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
- * Solides)
+ * 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
+ * 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
+ * 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_BOUNDARY_CONDITION_HH__
 #define __AKANTU_BOUNDARY_CONDITION_HH__
 
 #include "aka_common.hh"
 #include "boundary_condition_functor.hh"
 #include "fe_engine.hh"
 #include "mesh.hh"
 /* -------------------------------------------------------------------------- */
 
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 
 template <class ModelType> class BoundaryCondition {
 
   /* ------------------------------------------------------------------------ */
   /* Typedefs                                                                 */
   /* ------------------------------------------------------------------------ */
 private:
   /* ------------------------------------------------------------------------ */
   /* Constructors / Destructors / Initializers                                */
   /* ------------------------------------------------------------------------ */
 public:
   BoundaryCondition() : model(nullptr) {}
   /// Initialize the boundary conditions
   void initBC(ModelType & ptr, Array<Real> & primal, Array<Real> & dual);
   void initBC(ModelType & ptr, Array<Real> & primal,
               Array<Real> & primal_increment, Array<Real> & dual);
   /* ------------------------------------------------------------------------ */
   /* Methods and accessors                                                    */
   /* ------------------------------------------------------------------------ */
 public:
   // inline void initBoundaryCondition();
   template <typename FunctorType>
   /// Apply the boundary conditions
   inline void applyBC(const FunctorType & func);
 
   template <class FunctorType>
   inline void applyBC(const FunctorType & func, const std::string & group_name);
 
   template <class FunctorType>
   inline void applyBC(const FunctorType & func,
                       const ElementGroup & element_group);
 
   AKANTU_GET_MACRO_NOT_CONST(Model, *model, ModelType &);
   AKANTU_GET_MACRO_NOT_CONST(Primal, *primal, Array<Real> &);
   AKANTU_GET_MACRO_NOT_CONST(Dual, *dual, Array<Real> &);
 
   /* ------------------------------------------------------------------------ */
   /* Class Members                                                            */
   /* ------------------------------------------------------------------------ */
 
 public:
   template <class FunctorType, BC::Functor::Type type = FunctorType::type>
   struct TemplateFunctionWrapper;
 
 private:
   ModelType * model;
   Array<Real> * primal{nullptr};
   Array<Real> * dual{nullptr};
   Array<Real> * primal_increment{nullptr};
 };
 
 } // akantu
 
 #include "boundary_condition_tmpl.hh"
 
 #endif /* __AKANTU_BOUNDARY_CONDITION_HH__ */
diff --git a/src/model/boundary_condition_functor.hh b/src/model/boundary_condition_functor.hh
index 84cc245e3..4c54b5b09 100644
--- a/src/model/boundary_condition_functor.hh
+++ b/src/model/boundary_condition_functor.hh
@@ -1,217 +1,217 @@
 /**
  * @file   boundary_condition_functor.hh
  *
  * @author Dana Christen <dana.christen@gmail.com>
  * @author David Simon Kammer <david.kammer@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Fri May 03 2013
- * @date last modification: Thu Oct 15 2015
+ * @date last modification: Tue Feb 20 2018
  *
  * @brief  Definitions of the functors to apply boundary conditions
  *
  * @section LICENSE
  *
- * Copyright  (©)  2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de Lausanne)
+ * 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
+ * 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
+ * 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 "fe_engine.hh"
 #include "integration_point.hh"
 /* -------------------------------------------------------------------------- */
 
 #ifndef __AKANTU_BOUNDARY_CONDITION_FUNCTOR_HH__
 #define __AKANTU_BOUNDARY_CONDITION_FUNCTOR_HH__
 
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 namespace BC {
   using Axis = ::akantu::SpacialDirection;
 
   struct Functor {
     enum Type { _dirichlet, _neumann };
   };
 
   /* ------------------------------------------------------------------------ */
   /* Dirichlet                                                                */
   /* ------------------------------------------------------------------------ */
   namespace Dirichlet {
     /* ---------------------------------------------------------------------- */
     class DirichletFunctor : public Functor {
     protected:
       DirichletFunctor() = default;
       explicit DirichletFunctor(Axis ax) : axis(ax) {}
 
     public:
       void operator()(__attribute__((unused)) UInt node,
                       __attribute__((unused)) Vector<bool> & flags,
                       __attribute__((unused)) Vector<Real> & primal,
                       __attribute__((unused))
                       const Vector<Real> & coord) const {
         AKANTU_TO_IMPLEMENT();
       }
 
     public:
       static const Type type = _dirichlet;
 
     protected:
       Axis axis{_x};
     };
 
     /* ---------------------------------------------------------------------- */
     class FlagOnly : public DirichletFunctor {
     public:
       explicit FlagOnly(Axis ax = _x) : DirichletFunctor(ax) {}
 
     public:
       inline void operator()(UInt node, Vector<bool> & flags,
                              Vector<Real> & primal,
                              const Vector<Real> & coord) const;
     };
 
     /* ---------------------------------------------------------------------- */
     class FreeBoundary : public DirichletFunctor {
     public:
       explicit FreeBoundary(Axis ax = _x) : DirichletFunctor(ax) {}
 
     public:
       inline void operator()(UInt node, Vector<bool> & flags,
                              Vector<Real> & primal,
                              const Vector<Real> & coord) const;
     };
 
     /* ---------------------------------------------------------------------- */
     class FixedValue : public DirichletFunctor {
     public:
       FixedValue(Real val, Axis ax = _x) : DirichletFunctor(ax), value(val) {}
 
     public:
       inline void operator()(UInt node, Vector<bool> & flags,
                              Vector<Real> & primal,
                              const Vector<Real> & coord) const;
 
     protected:
       Real value;
     };
 
     /* ---------------------------------------------------------------------- */
     class IncrementValue : public DirichletFunctor {
     public:
       IncrementValue(Real val, Axis ax = _x)
           : DirichletFunctor(ax), value(val) {}
 
     public:
       inline void operator()(UInt node, Vector<bool> & flags,
                              Vector<Real> & primal,
                              const Vector<Real> & coord) const;
 
       inline void setIncrement(Real val) { this->value = val; }
 
     protected:
       Real value;
     };
 
     /* ---------------------------------------------------------------------- */
     class Increment : public DirichletFunctor {
     public:
       explicit Increment(const Vector<Real> & val)
           : DirichletFunctor(_x), value(val) {}
 
     public:
       inline void operator()(UInt node, Vector<bool> & flags,
                              Vector<Real> & primal,
                              const Vector<Real> & coord) const;
 
       inline void setIncrement(const Vector<Real> & val) { this->value = val; }
 
     protected:
       Vector<Real> value;
     };
 
   } // end namespace Dirichlet
 
   /* ------------------------------------------------------------------------ */
   /* Neumann                                                                  */
   /* ------------------------------------------------------------------------ */
   namespace Neumann {
     /* ---------------------------------------------------------------------- */
     class NeumannFunctor : public Functor {
 
     protected:
       NeumannFunctor() = default;
 
     public:
       virtual void operator()(const IntegrationPoint & quad_point,
                               Vector<Real> & dual, const Vector<Real> & coord,
                               const Vector<Real> & normals) const = 0;
 
       virtual ~NeumannFunctor() = default;
 
     public:
       static const Type type = _neumann;
     };
 
     /* ---------------------------------------------------------------------- */
     class FromHigherDim : public NeumannFunctor {
     public:
       explicit FromHigherDim(const Matrix<Real> & mat) : bc_data(mat) {}
       ~FromHigherDim() override = default;
 
     public:
       inline void operator()(const IntegrationPoint & quad_point,
                              Vector<Real> & dual, const Vector<Real> & coord,
                              const Vector<Real> & normals) const override;
 
     protected:
       Matrix<Real> bc_data;
     };
 
     /* ---------------------------------------------------------------------- */
     class FromSameDim : public NeumannFunctor {
     public:
       explicit FromSameDim(const Vector<Real> & vec) : bc_data(vec) {}
       ~FromSameDim() override = default;
 
     public:
       inline void operator()(const IntegrationPoint & quad_point,
                              Vector<Real> & dual, const Vector<Real> & coord,
                              const Vector<Real> & normals) const override;
 
     protected:
       Vector<Real> bc_data;
     };
 
     /* ---------------------------------------------------------------------- */
     class FreeBoundary : public NeumannFunctor {
     public:
       inline void operator()(const IntegrationPoint & quad_point,
                              Vector<Real> & dual, const Vector<Real> & coord,
                              const Vector<Real> & normals) const override;
     };
   } // end namespace Neumann
 } // end namespace BC
 
 } // akantu
 
 #include "boundary_condition_functor_inline_impl.cc"
 
 #endif /* __AKANTU_BOUNDARY_CONDITION_FUNCTOR_HH__ */
diff --git a/src/model/boundary_condition_functor_inline_impl.cc b/src/model/boundary_condition_functor_inline_impl.cc
index abe306794..41a7d2b87 100644
--- a/src/model/boundary_condition_functor_inline_impl.cc
+++ b/src/model/boundary_condition_functor_inline_impl.cc
@@ -1,156 +1,158 @@
 /**
  * @file   boundary_condition_functor_inline_impl.cc
  *
  * @author Dana Christen <dana.christen@gmail.com>
+ * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Fri May 03 2013
- * @date last modification: Thu Oct 15 2015
+ * @date last modification: Mon Feb 19 2018
  *
  * @brief  implementation of the BC::Functors
  *
  * @section LICENSE
  *
- * Copyright  (©)  2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de Lausanne)
+ * 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
+ * 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
+ * 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_functor.hh"
 /* -------------------------------------------------------------------------- */
 
 #ifndef __AKANTU_BOUNDARY_CONDITION_FUNCTOR_INLINE_IMPL_CC__
 #define __AKANTU_BOUNDARY_CONDITION_FUNCTOR_INLINE_IMPL_CC__
 
 /* -------------------------------------------------------------------------- */
 #define DIRICHLET_SANITY_CHECK                                                 \
   AKANTU_DEBUG_ASSERT(                                                         \
       coord.size() <= flags.size(),                                            \
       "The coordinates and flags vectors given to the boundary"                \
           << " condition functor have different sizes!");                      \
   AKANTU_DEBUG_ASSERT(                                                         \
       primal.size() <= coord.size(),                                           \
       "The primal vector and coordinates vector given"                         \
           << " to the boundary condition functor have different sizes!");
 
 #define NEUMANN_SANITY_CHECK                                                   \
   AKANTU_DEBUG_ASSERT(                                                         \
       coord.size() <= normals.size(),                                          \
       "The coordinates and normals vectors given to the"                       \
           << " boundary condition functor have different sizes!");             \
   AKANTU_DEBUG_ASSERT(                                                         \
       dual.size() <= coord.size(),                                             \
       "The dual vector and coordinates vector given to"                        \
           << " the boundary condition functor have different sizes!");
 
 namespace akantu {
 namespace BC {
   namespace Dirichlet {
     /* ---------------------------------------------------------------------- */
     inline void FlagOnly::
     operator()(__attribute__((unused)) UInt node, Vector<bool> & flags,
                __attribute__((unused)) Vector<Real> & primal,
                __attribute__((unused)) const Vector<Real> & coord) const {
 
       DIRICHLET_SANITY_CHECK;
 
       flags(this->axis) = true;
     }
 
     /* ---------------------------------------------------------------------- */
     inline void FreeBoundary::
     operator()(__attribute__((unused)) UInt node, Vector<bool> & flags,
                __attribute__((unused)) Vector<Real> & primal,
                __attribute__((unused)) const Vector<Real> & coord) const {
 
       DIRICHLET_SANITY_CHECK;
 
       flags(this->axis) = false;
     }
 
     /* ---------------------------------------------------------------------- */
     inline void FixedValue::operator()(__attribute__((unused)) UInt node,
                                        Vector<bool> & flags,
                                        Vector<Real> & primal,
                                        __attribute__((unused))
                                        const Vector<Real> & coord) const {
       DIRICHLET_SANITY_CHECK;
       flags(this->axis) = true;
       primal(this->axis) = value;
     }
 
     /* ---------------------------------------------------------------------- */
     inline void IncrementValue::operator()(__attribute__((unused)) UInt node,
                                            Vector<bool> & flags,
                                            Vector<Real> & primal,
                                            __attribute__((unused))
                                            const Vector<Real> & coord) const {
       DIRICHLET_SANITY_CHECK;
       flags(this->axis) = true;
       primal(this->axis) += value;
     }
 
     /* ---------------------------------------------------------------------- */
     inline void Increment::operator()(__attribute__((unused)) UInt node,
                                       Vector<bool> & flags,
                                       Vector<Real> & primal,
                                       __attribute__((unused))
                                       const Vector<Real> & coord) const {
       DIRICHLET_SANITY_CHECK;
       flags.set(true);
       primal += value;
     }
 
   } // end namespace Dirichlet
 
   /* ------------------------------------------------------------------------ */
   /* Neumann */
   /* ------------------------------------------------------------------------ */
   namespace Neumann {
     /* ---------------------------------------------------------------------- */
     inline void FreeBoundary::
     operator()(__attribute__((unused)) const IntegrationPoint & quad_point,
                Vector<Real> & dual,
                __attribute__((unused)) const Vector<Real> & coord,
                __attribute__((unused)) const Vector<Real> & normals) const {
       for (UInt i(0); i < dual.size(); ++i) {
         dual(i) = 0.0;
       }
     }
 
     /* ---------------------------------------------------------------------- */
     inline void FromHigherDim::operator()(__attribute__((unused))
                                           const IntegrationPoint & quad_point,
                                           Vector<Real> & dual,
                                           __attribute__((unused))
                                           const Vector<Real> & coord,
                                           const Vector<Real> & normals) const {
       dual.mul<false>(this->bc_data, normals);
     }
 
     /* ---------------------------------------------------------------------- */
     inline void FromSameDim::
     operator()(__attribute__((unused)) const IntegrationPoint & quad_point,
                Vector<Real> & dual,
                __attribute__((unused)) const Vector<Real> & coord,
                __attribute__((unused)) const Vector<Real> & normals) const {
       dual = this->bc_data;
     }
   } // namespace Neumann
 } // namespace BC
 
 } // namespace akantu
 
 #endif /* __AKANTU_BOUNDARY_CONDITION_FUNCTOR_INLINE_IMPL_CC__ */
diff --git a/src/model/boundary_condition_python_functor.cc b/src/model/boundary_condition_python_functor.cc
index edc531d6f..d1c42d775 100644
--- a/src/model/boundary_condition_python_functor.cc
+++ b/src/model/boundary_condition_python_functor.cc
@@ -1,57 +1,57 @@
 /**
  * @file   boundary_condition_python_functor.cc
  *
  * @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
+ * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
- * @date creation: Wed Aug 31 2011
- * @date last modification: Fri Nov 13 2015
+ * @date creation: Fri Jun 18 2010
+ * @date last modification: Wed Jan 31 2018
  *
  * @brief  Interface for BC::Functor written in python
  *
  * @section LICENSE
  *
- * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
- * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
- * Solides)
+ * 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
+ * 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
+ * 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_python_functor.hh"
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 
 namespace BC {
 
   void PythonFunctorDirichlet::operator()(UInt node, Vector<bool> & flags,
                                           Vector<Real> & primal,
                                           const Vector<Real> & coord) const {
 
     this->callFunctor<void>("operator", node, flags, primal, coord);
   }
 
   void PythonFunctorNeumann::operator()(const IntegrationPoint & quad_point,
                                         Vector<Real> & dual,
                                         const Vector<Real> & coord,
                                         const Vector<Real> & normals) const {
 
     this->callFunctor<void>("operator", quad_point, dual, coord, normals);
   }
 
 } // end namespace BC
 
 } // akantu
diff --git a/src/model/boundary_condition_python_functor.hh b/src/model/boundary_condition_python_functor.hh
index da7e44410..2380f5052 100644
--- a/src/model/boundary_condition_python_functor.hh
+++ b/src/model/boundary_condition_python_functor.hh
@@ -1,116 +1,117 @@
 /**
  * @file   boundary_condition_python_functor.hh
  *
  * @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
+ * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Thu Feb 21 2013
- * @date last modification: Fri Nov 13 2015
+ * @date last modification: Wed Jan 31 2018
  *
  * @brief  interface for BC::Functor writen in python
  *
  * @section LICENSE
  *
- * Copyright  (©)  2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de Lausanne)
+ * 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
+ * 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
+ * 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 "boundary_condition_functor.hh"
 /* -------------------------------------------------------------------------- */
 
 #ifndef __AKANTU_BOUNDARY_CONDITION_PYTHON_FUNCTOR_HH__
 #define __AKANTU_BOUNDARY_CONDITION_PYTHON_FUNCTOR_HH__
 /* -------------------------------------------------------------------------- */
 #include "boundary_condition_functor.hh"
 #include "python_functor.hh"
 /* -------------------------------------------------------------------------- */
 namespace akantu {
 
 namespace BC {
 
   class PythonFunctorDirichlet : public PythonFunctor, public Functor {
 
     /* ------------------------------------------------------------------------
      */
     /* Constructors/Destructors */
     /* ------------------------------------------------------------------------
      */
 
   public:
     PythonFunctorDirichlet(PyObject * obj) : PythonFunctor(obj) {}
 
     /* ------------------------------------------------------------------------
      */
     /* Methods */
     /* ------------------------------------------------------------------------
      */
 
   public:
     void operator()(UInt node, Vector<bool> & flags, Vector<Real> & primal,
                     const Vector<Real> & coord) const;
 
     /* ------------------------------------------------------------------------
      */
     /* Class Members */
     /* ------------------------------------------------------------------------
      */
 
   public:
     static const Type type = _dirichlet;
   };
 
   /* --------------------------------------------------------------------------
    */
 
   class PythonFunctorNeumann : public PythonFunctor, public Functor {
 
     /* ------------------------------------------------------------------------
      */
     /* Constructors/Destructors */
     /* ------------------------------------------------------------------------
      */
 
   public:
     PythonFunctorNeumann(PyObject * obj) : PythonFunctor(obj) {}
 
     /* ------------------------------------------------------------------------
      */
     /* Methods */
     /* ------------------------------------------------------------------------
      */
 
   public:
     void operator()(const IntegrationPoint & quad_point, Vector<Real> & dual,
                     const Vector<Real> & coord,
                     const Vector<Real> & normals) const;
 
     /* ------------------------------------------------------------------------
      */
     /* Class Members */
     /* ------------------------------------------------------------------------
      */
 
   public:
     static const Type type = _neumann;
   };
 
 } // end namespace BC
 
 } // akantu
 
 #endif /* __AKANTU_BOUNDARY_CONDITION_PYTHON_FUNCTOR_HH__ */
diff --git a/src/model/boundary_condition_tmpl.hh b/src/model/boundary_condition_tmpl.hh
index bb4c58039..f45d2ac88 100644
--- a/src/model/boundary_condition_tmpl.hh
+++ b/src/model/boundary_condition_tmpl.hh
@@ -1,256 +1,256 @@
 /**
  * @file   boundary_condition_tmpl.hh
  *
  * @author Dana Christen <dana.christen@gmail.com>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Fri May 03 2013
- * @date last modification: Fri Oct 16 2015
+ * @date last modification: Tue Feb 20 2018
  *
  * @brief  implementation of the applyBC
  *
  * @section LICENSE
  *
- * Copyright  (©)  2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de Lausanne)
+ * 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
+ * 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
+ * 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 "element_group.hh"
 /* -------------------------------------------------------------------------- */
 
 #ifndef __AKANTU_BOUNDARY_CONDITION_TMPL_HH__
 #define __AKANTU_BOUNDARY_CONDITION_TMPL_HH__
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 template <typename ModelType>
 void BoundaryCondition<ModelType>::initBC(ModelType & model,
                                           Array<Real> & primal,
                                           Array<Real> & dual) {
   this->model = &model;
   this->primal = &primal;
   this->dual = &dual;
 }
 
 /* -------------------------------------------------------------------------- */
 template <typename ModelType>
 void BoundaryCondition<ModelType>::initBC(ModelType & model,
                                           Array<Real> & primal,
                                           Array<Real> & primal_increment,
                                           Array<Real> & dual) {
   this->initBC(model, primal, dual);
   this->primal_increment = &primal_increment;
 }
 
 /* -------------------------------------------------------------------------- */
 /* Partial specialization for DIRICHLET functors */
 template <typename ModelType>
 template <typename FunctorType>
 struct BoundaryCondition<ModelType>::TemplateFunctionWrapper<
     FunctorType, BC::Functor::_dirichlet> {
   static inline void applyBC(const FunctorType & func,
                              const ElementGroup & group,
                              BoundaryCondition<ModelType> & bc_instance) {
     auto & model = bc_instance.getModel();
     auto & primal = bc_instance.getPrimal();
 
     const auto & coords = model.getMesh().getNodes();
     auto & boundary_flags = model.getBlockedDOFs();
     UInt dim = model.getMesh().getSpatialDimension();
 
     auto primal_iter = primal.begin(primal.getNbComponent());
     auto coords_iter = coords.begin(dim);
     auto flags_iter = boundary_flags.begin(boundary_flags.getNbComponent());
 
     for (auto n : group.getNodeGroup()) {
       Vector<bool> flag(flags_iter[n]);
       Vector<Real> primal(primal_iter[n]);
       Vector<Real> coords(coords_iter[n]);
       func(n, flag, primal, coords);
     }
   }
 };
 
 /* -------------------------------------------------------------------------- */
 /* Partial specialization for NEUMANN functors */
 template <typename ModelType>
 template <typename FunctorType>
 struct BoundaryCondition<ModelType>::TemplateFunctionWrapper<
     FunctorType, BC::Functor::_neumann> {
   static inline void applyBC(const FunctorType & func,
                              const ElementGroup & group,
                              BoundaryCondition<ModelType> & bc_instance) {
     UInt dim = bc_instance.getModel().getSpatialDimension();
     switch (dim) {
     case 1: {
       AKANTU_TO_IMPLEMENT();
       break;
     }
     case 2:
     case 3: {
       applyBC(func, group, bc_instance, _not_ghost);
       applyBC(func, group, bc_instance, _ghost);
       break;
     }
     }
   }
 
   static inline void applyBC(const FunctorType & func,
                              const ElementGroup & group,
                              BoundaryCondition<ModelType> & bc_instance,
                              GhostType ghost_type) {
     auto & model = bc_instance.getModel();
     auto & dual = bc_instance.getDual();
     const auto & mesh = model.getMesh();
     const auto & nodes_coords = mesh.getNodes();
     const auto & fem_boundary = model.getFEEngineBoundary();
 
     UInt dim = model.getSpatialDimension();
     UInt nb_degree_of_freedom = dual.getNbComponent();
 
     IntegrationPoint quad_point;
     quad_point.ghost_type = ghost_type;
 
     // Loop over the boundary element types
     for (auto && type : group.elementTypes(dim - 1, ghost_type)) {
       const auto & element_ids = group.getElements(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);
 
       Array<Real> * dual_before_integ = new Array<Real>(
           nb_elements * nb_quad_points, nb_degree_of_freedom, 0.);
       Array<Real> * quad_coords =
           new Array<Real>(nb_elements * nb_quad_points, dim);
 
       const auto & normals_on_quad =
           fem_boundary.getNormalsOnIntegrationPoints(type, ghost_type);
 
       fem_boundary.interpolateOnIntegrationPoints(
           nodes_coords, *quad_coords, dim, type, ghost_type, element_ids);
       auto normals_begin = normals_on_quad.begin(dim);
       decltype(normals_begin) normals_iter;
       auto quad_coords_iter = quad_coords->begin(dim);
       auto dual_iter = dual_before_integ->begin(nb_degree_of_freedom);
 
       quad_point.type = type;
       for (auto el : element_ids) {
         quad_point.element = el;
         normals_iter = normals_begin + el * nb_quad_points;
         for (auto && q : arange(nb_quad_points)) {
           quad_point.num_point = q;
           func(quad_point, *dual_iter, *quad_coords_iter, *normals_iter);
           ++dual_iter;
           ++quad_coords_iter;
           ++normals_iter;
         }
       }
 
       delete quad_coords;
 
       /* -------------------------------------------------------------------- */
       // Initialization of iterators
       auto dual_iter_mat = dual_before_integ->begin(nb_degree_of_freedom, 1);
       auto shapes_iter_begin = fem_boundary.getShapes(type, ghost_type)
                                    .begin(1, nb_nodes_per_element);
 
       Array<Real> * dual_by_shapes =
           new Array<Real>(nb_elements * nb_quad_points,
                           nb_degree_of_freedom * nb_nodes_per_element);
 
       auto dual_by_shapes_iter =
           dual_by_shapes->begin(nb_degree_of_freedom, nb_nodes_per_element);
 
       /* -------------------------------------------------------------------- */
       // Loop computing dual x shapes
       for (auto el : element_ids) {
         auto shapes_iter = shapes_iter_begin + el * nb_quad_points;
 
         for (UInt q(0); q < nb_quad_points;
              ++q, ++dual_iter_mat, ++dual_by_shapes_iter, ++shapes_iter) {
           dual_by_shapes_iter->template mul<false, false>(*dual_iter_mat,
                                                           *shapes_iter);
         }
       }
 
       delete dual_before_integ;
 
       Array<Real> * dual_by_shapes_integ = new Array<Real>(
           nb_elements, nb_degree_of_freedom * 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);
       delete dual_by_shapes;
 
       // assemble the result into force vector
       model.getDOFManager().assembleElementalArrayLocalArray(
           *dual_by_shapes_integ, dual, type, ghost_type, 1., element_ids);
       delete dual_by_shapes_integ;
     }
   }
 };
 
 /* -------------------------------------------------------------------------- */
 template <typename ModelType>
 template <typename FunctorType>
 inline void BoundaryCondition<ModelType>::applyBC(const FunctorType & func) {
   auto bit = model->getMesh().getGroupManager().element_group_begin();
   auto bend = model->getMesh().getGroupManager().element_group_end();
   for (; bit != bend; ++bit)
     applyBC(func, *bit);
 }
 
 /* -------------------------------------------------------------------------- */
 template <typename ModelType>
 template <typename FunctorType>
 inline void
 BoundaryCondition<ModelType>::applyBC(const FunctorType & func,
                                       const std::string & group_name) {
   try {
     const ElementGroup & element_group =
         model->getMesh().getElementGroup(group_name);
     applyBC(func, element_group);
   } catch (akantu::debug::Exception e) {
     AKANTU_EXCEPTION("Error applying a boundary condition onto \""
                      << group_name << "\"! [" << e.what() << "]");
   }
 }
 
 /* -------------------------------------------------------------------------- */
 template <typename ModelType>
 template <typename FunctorType>
 inline void
 BoundaryCondition<ModelType>::applyBC(const FunctorType & func,
                                       const ElementGroup & element_group) {
 #if !defined(AKANTU_NDEBUG)
   if (element_group.getDimension() != model->getSpatialDimension() - 1)
     AKANTU_DEBUG_WARNING("The group "
                          << element_group.getName()
                          << " does not contain only boundaries elements");
 #endif
 
   TemplateFunctionWrapper<FunctorType>::applyBC(func, element_group, *this);
 }
 
 #endif /* __AKANTU_BOUNDARY_CONDITION_TMPL_HH__ */
 
 } // namespace akantu
diff --git a/src/model/common/neighborhood_base.cc b/src/model/common/neighborhood_base.cc
index 1fbf3f5a4..aada85368 100644
--- a/src/model/common/neighborhood_base.cc
+++ b/src/model/common/neighborhood_base.cc
@@ -1,295 +1,295 @@
 /**
  * @file   neighborhood_base.cc
  *
  * @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Sat Sep 26 2015
- * @date last modification: Wed Nov 25 2015
+ * @date last modification: Wed Jan 31 2018
  *
  * @brief  Implementation of generic neighborhood base
  *
  * @section LICENSE
  *
- * Copyright (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne) Laboratory
- * (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * Copyright (©) 2015-2018 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
- * terms  of the  GNU Lesser  General Public  License as  published by  the Free
+ * 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
+ * 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 "neighborhood_base.hh"
 #include "grid_synchronizer.hh"
 #include "mesh_accessor.hh"
 #include "model.hh"
 /* -------------------------------------------------------------------------- */
 #include <fstream>
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 /* -------------------------------------------------------------------------- */
 NeighborhoodBase::NeighborhoodBase(Model & model,
                                    const ElementTypeMapReal & quad_coordinates,
                                    const ID & id, const MemoryID & memory_id)
     : Memory(id, memory_id), model(model), neighborhood_radius(0.),
       spatial_grid(nullptr), is_creating_grid(false),
       grid_synchronizer(nullptr), quad_coordinates(quad_coordinates),
       spatial_dimension(this->model.getMesh().getSpatialDimension()) {
 
   AKANTU_DEBUG_IN();
 
   this->registerDataAccessor(*this);
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 NeighborhoodBase::~NeighborhoodBase() = default;
 
 /* -------------------------------------------------------------------------- */
 // void NeighborhoodBase::createSynchronizerRegistry(
 //     DataAccessor<Element> * data_accessor) {
 //   this->synch_registry = new SynchronizerRegistry(*data_accessor);
 // }
 
 /* -------------------------------------------------------------------------- */
 void NeighborhoodBase::initNeighborhood() {
   AKANTU_DEBUG_IN();
 
   AKANTU_DEBUG_INFO("Creating the grid");
   this->createGrid();
 
   AKANTU_DEBUG_OUT();
 }
 
 /* ------------------------------------------------------------------------- */
 void NeighborhoodBase::createGrid() {
   AKANTU_DEBUG_IN();
 
   const Real safety_factor = 1.2; // for the cell grid spacing
   Mesh & mesh = this->model.getMesh();
 
   const auto & lower_bounds = mesh.getLocalLowerBounds();
   const auto & upper_bounds = mesh.getLocalUpperBounds();
   Vector<Real> center = 0.5 * (upper_bounds + lower_bounds);
   Vector<Real> spacing(spatial_dimension,
                        this->neighborhood_radius * safety_factor);
 
   spatial_grid = std::make_unique<SpatialGrid<IntegrationPoint>>(
       spatial_dimension, spacing, center);
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void NeighborhoodBase::updatePairList() {
   AKANTU_DEBUG_IN();
 
   //// loop over all quads -> all cells
   for (auto && cell_id : *spatial_grid) {
     AKANTU_DEBUG_INFO("Looping on next cell");
 
     for (auto && q1 : spatial_grid->getCell(cell_id)) {
       if (q1.ghost_type == _ghost)
         break;
       auto coords_type_1_it = this->quad_coordinates(q1.type, q1.ghost_type)
                                   .begin(spatial_dimension);
       auto q1_coords = Vector<Real>(coords_type_1_it[q1.global_num]);
 
       AKANTU_DEBUG_INFO("Current quadrature point in this cell: " << q1);
       auto cell_id = spatial_grid->getCellID(q1_coords);
 
       /// loop over all the neighboring cells of the current quad
       for (auto && neighbor_cell : cell_id.neighbors()) {
         // loop over the quadrature point in the current neighboring cell
         for (auto && q2 : spatial_grid->getCell(neighbor_cell)) {
           auto coords_type_2_it = this->quad_coordinates(q2.type, q2.ghost_type)
                                       .begin(spatial_dimension);
           auto q2_coords = Vector<Real>(coords_type_2_it[q2.global_num]);
 
           Real distance = q1_coords.distance(q2_coords);
 
           if (distance <= this->neighborhood_radius + Math::getTolerance() &&
               (q2.ghost_type == _ghost ||
                (q2.ghost_type == _not_ghost &&
                 q1.global_num <= q2.global_num))) { // storing only half lists
             pair_list[q2.ghost_type].push_back(std::make_pair(q1, q2));
           }
         }
       }
     }
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void NeighborhoodBase::savePairs(const std::string & filename) const {
   std::stringstream sstr;
 
   const Communicator & comm = model.getMesh().getCommunicator();
   Int prank = comm.whoAmI();
   sstr << filename << "." << prank;
 
   std::ofstream pout;
   pout.open(sstr.str().c_str());
 
   for (auto && ghost_type : ghost_types) {
     for (const auto & pair : pair_list[ghost_type]) {
       const auto & q1 = pair.first;
       const auto & q2 = pair.second;
       pout << q1 << " " << q2 << " " << std::endl;
     }
   }
 
   pout.close();
 
   if (comm.getNbProc() != 1)
     return;
 
   Mesh mesh_out(spatial_dimension);
   MeshAccessor mesh_accessor(mesh_out);
   auto & connectivity = mesh_accessor.getConnectivity(_segment_2);
   auto & tag = mesh_accessor.getData<UInt>("tag_1", _segment_2);
   auto & nodes = mesh_accessor.getNodes();
 
   std::map<IntegrationPoint, UInt> quad_to_nodes;
   UInt node = 0;
 
   IntegrationPoint q1, q2;
   bool inserted;
   for (auto && ghost_type : ghost_types) {
     for (const auto & pair : pair_list[ghost_type]) {
       std::tie(q1, q2) = pair;
 
       auto add_node = [&](auto && q) {
         std::tie(std::ignore, inserted) =
             quad_to_nodes.insert(std::make_pair(q, node));
 
         if (not inserted)
           return;
 
         auto coords_it = this->quad_coordinates(q.type, q.ghost_type)
                              .begin(spatial_dimension);
         auto && coords = Vector<Real>(coords_it[q.global_num]);
         nodes.push_back(coords);
         ++node;
       };
 
       add_node(q1);
       add_node(q2);
     }
   }
 
   for (auto && ghost_type : ghost_types) {
     for (const auto & pair : pair_list[ghost_type]) {
       std::tie(q1, q2) = pair;
 
       UInt node1 = quad_to_nodes[q1];
       UInt node2 = quad_to_nodes[q2];
 
       connectivity.push_back(Vector<UInt>{node1, node2});
       tag.push_back(node1 + 1);
       if (node1 != node2) {
         connectivity.push_back(Vector<UInt>{node2, node1});
         tag.push_back(node2 + 1);
       }
     }
   }
 
   mesh_out.write(filename + ".msh");
 }
 
 /* -------------------------------------------------------------------------- */
 void NeighborhoodBase::saveNeighborCoords(const std::string & filename) const {
   // this function is not optimized and only used for tests on small meshes
   // @todo maybe optimize this function for better performance?
   IntegrationPoint q2;
 
   std::stringstream sstr;
 
   const Communicator & comm = model.getMesh().getCommunicator();
   Int prank = comm.whoAmI();
   sstr << filename << "." << prank;
 
   std::ofstream pout;
   pout.open(sstr.str().c_str());
 
   /// loop over all the quads and write the position of their neighbors
   for (auto && cell_id : *spatial_grid) {
     for (auto && q1 : spatial_grid->getCell(cell_id)) {
       auto coords_type_1_it = this->quad_coordinates(q1.type, q1.ghost_type)
                                   .begin(spatial_dimension);
       auto && q1_coords = Vector<Real>(coords_type_1_it[q1.global_num]);
 
       pout << "#neighbors for quad " << q1.global_num << std::endl;
       pout << q1_coords << std::endl;
 
       for (auto && ghost_type2 : ghost_types) {
         for (auto && pair : pair_list[ghost_type2]) {
           if (q1 == pair.first && pair.second != q1) {
             q2 = pair.second;
           } else if (q1 == pair.second && pair.first != q1) {
             q2 = pair.first;
           } else {
             continue;
           }
 
           auto coords_type_2_it = this->quad_coordinates(q2.type, q2.ghost_type)
                                       .begin(spatial_dimension);
           auto && q2_coords = Vector<Real>(coords_type_2_it[q2.global_num]);
           pout << q2_coords << std::endl;
         }
       }
     }
   }
 }
 
 /* -------------------------------------------------------------------------- */
 void NeighborhoodBase::onElementsRemoved(
     const Array<Element> & element_list,
     const ElementTypeMapArray<UInt> & new_numbering,
     const RemovedElementsEvent & event) {
   AKANTU_DEBUG_IN();
 
   FEEngine & fem = this->model.getFEEngine();
   UInt nb_quad = 0;
   // Change the pairs in new global numbering
   for (auto ghost_type2 : ghost_types) {
     for (auto && pair : pair_list[ghost_type2]) {
       auto cleanPoint = [&](auto && q) {
         if (new_numbering.exists(q.type, q.ghost_type)) {
           UInt q_new_el = new_numbering(q.type, q.ghost_type)(q.element);
           AKANTU_DEBUG_ASSERT(q_new_el != UInt(-1),
                               "A local quadrature_point "
                               "as been removed instead of "
                               "just being renumbered");
           q.element = q_new_el;
           nb_quad = fem.getNbIntegrationPoints(q.type, q.ghost_type);
           q.global_num = nb_quad * q.element + q.num_point;
         }
       };
 
       cleanPoint(pair.first);
       cleanPoint(pair.second);
     }
   }
 
   this->grid_synchronizer->onElementsRemoved(element_list, new_numbering,
                                              event);
   AKANTU_DEBUG_OUT();
 }
 
 } // namespace akantu
diff --git a/src/model/common/neighborhood_base.hh b/src/model/common/neighborhood_base.hh
index e0c51f496..a9dabe632 100644
--- a/src/model/common/neighborhood_base.hh
+++ b/src/model/common/neighborhood_base.hh
@@ -1,151 +1,151 @@
 /**
  * @file   neighborhood_base.hh
  *
  * @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Sat Sep 26 2015
- * @date last modification: Wed Nov 25 2015
+ * @date last modification: Wed Jan 31 2018
  *
  * @brief  Generic neighborhood of quadrature points
  *
  * @section LICENSE
  *
- * Copyright (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne) Laboratory
- * (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * Copyright (©) 2015-2018 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
- * terms  of the  GNU Lesser  General Public  License as  published by  the Free
+ * 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
+ * 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_NEIGHBORHOOD_BASE_HH__
 #define __AKANTU_NEIGHBORHOOD_BASE_HH__
 /* -------------------------------------------------------------------------- */
 #include "aka_common.hh"
 #include "aka_memory.hh"
 #include "data_accessor.hh"
 #include "integration_point.hh"
 #include "synchronizer_registry.hh"
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 class Model;
 template <class T> class SpatialGrid;
 class GridSynchronizer;
 class RemovedElementsEvent;
 } // namespace akantu
 
 namespace akantu {
 class NeighborhoodBase : protected Memory,
                          public DataAccessor<Element>,
                          public SynchronizerRegistry {
   /* ------------------------------------------------------------------------ */
   /* Constructors/Destructors                                                 */
   /* ------------------------------------------------------------------------ */
 public:
   NeighborhoodBase(Model & model,
                    const ElementTypeMapArray<Real> & quad_coordinates,
                    const ID & id = "neighborhood",
                    const MemoryID & memory_id = 0);
   ~NeighborhoodBase() override;
 
   using PairList = std::vector<std::pair<IntegrationPoint, IntegrationPoint>>;
 
   /* ------------------------------------------------------------------------ */
   /* Methods                                                                  */
   /* ------------------------------------------------------------------------ */
 
 public:
   /// intialize the neighborhood
   virtual void initNeighborhood();
 
   // /// create a synchronizer registry
   // void createSynchronizerRegistry(DataAccessor * data_accessor);
 
   /// initialize the material computed parameter
   inline void insertIntegrationPoint(const IntegrationPoint & quad,
                                      const Vector<Real> & coords);
 
   /// create the pairs of quadrature points
   void updatePairList();
 
   /// save the pairs of quadrature points in a file
   void savePairs(const std::string & filename) const;
 
   /// save the coordinates of all neighbors of a quad
   void saveNeighborCoords(const std::string & filename) const;
 
   /// create grid synchronizer and exchange ghost cells
   virtual void createGridSynchronizer() = 0;
   virtual void synchronize(DataAccessor<Element> & data_accessor,
                            const SynchronizationTag & tag) = 0;
 
   /// inherited function from MeshEventHandler
   virtual void
   onElementsRemoved(const Array<Element> & element_list,
                     const ElementTypeMapArray<UInt> & new_numbering,
                     const RemovedElementsEvent & event);
 
 protected:
   /// create the grid
   void createGrid();
 
   /* ------------------------------------------------------------------------ */
   /* Accessors                                                                */
   /* ------------------------------------------------------------------------ */
 public:
   AKANTU_GET_MACRO(SpatialDimension, spatial_dimension, UInt);
   AKANTU_GET_MACRO(Model, model, const Model &);
   /// return the object handling synchronizers
   AKANTU_GET_MACRO(PairLists, pair_list, const PairList *);
 
   /* ------------------------------------------------------------------------ */
   /* Class Members                                                            */
   /* ------------------------------------------------------------------------ */
 protected:
   /// the model to which the neighborhood belongs
   Model & model;
 
   /// Radius of impact: to determine if two quadrature points influence each
   /// other
   Real neighborhood_radius;
 
   /**
    * the pairs of quadrature points
    * 0: not ghost to not ghost
    * 1: not ghost to ghost
    */
   PairList pair_list[2];
 
   /// the regular grid to construct/update the pair lists
   std::unique_ptr<SpatialGrid<IntegrationPoint>> spatial_grid;
 
   bool is_creating_grid;
 
   /// the grid synchronizer for parallel computations
   std::unique_ptr<GridSynchronizer> grid_synchronizer;
 
   /// the quadrature point positions
   const ElementTypeMapArray<Real> & quad_coordinates;
 
   /// the spatial dimension of the problem
   const UInt spatial_dimension;
 };
 
 } // namespace akantu
 
 #include "neighborhood_base_inline_impl.cc"
 
 #endif /* __AKANTU_NEIGHBORHOOD_BASE_HH__ */
diff --git a/src/model/common/neighborhood_base_inline_impl.cc b/src/model/common/neighborhood_base_inline_impl.cc
index ebed56d3f..70de7429f 100644
--- a/src/model/common/neighborhood_base_inline_impl.cc
+++ b/src/model/common/neighborhood_base_inline_impl.cc
@@ -1,50 +1,50 @@
 /**
  * @file   neighborhood_base_inline_impl.cc
  *
  * @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Thu Feb 21 2013
- * @date last modification: Wed Nov 25 2015
+ * @date last modification: Wed Jan 31 2018
  *
  * @brief  Inline implementation of neighborhood base functions
  *
  * @section LICENSE
  *
- * Copyright  (©)  2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de Lausanne)
+ * 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
+ * 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
+ * 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_grid_dynamic.hh"
 #include "neighborhood_base.hh"
 /* -------------------------------------------------------------------------- */
 
 #ifndef __AKANTU_NEIGHBORHOOD_BASE_INLINE_IMPL_CC__
 #define __AKANTU_NEIGHBORHOOD_BASE_INLINE_IMPL_CC__
 
 namespace akantu {
 
 inline void
 NeighborhoodBase::insertIntegrationPoint(const IntegrationPoint & quad,
                                          const Vector<Real> & coords) {
   this->spatial_grid->insert(quad, coords);
 }
 
 } // namespace akantu
 
 #endif /* __AKANTU_NEIGHBORHOOD_BASE_INLINE_IMPL_CC__ */
diff --git a/src/model/common/neighborhoods_criterion_evaluation/neighborhood_max_criterion.cc b/src/model/common/neighborhoods_criterion_evaluation/neighborhood_max_criterion.cc
index 6468159a4..bc55e366a 100644
--- a/src/model/common/neighborhoods_criterion_evaluation/neighborhood_max_criterion.cc
+++ b/src/model/common/neighborhoods_criterion_evaluation/neighborhood_max_criterion.cc
@@ -1,311 +1,311 @@
 /**
  * @file   neighborhood_max_criterion.cc
  *
  * @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
  *
  * @date creation: Thu Oct 15 2015
- * @date last modification: Tue Nov 24 2015
+ * @date last modification: Tue Feb 20 2018
  *
  * @brief  Implementation of class NeighborhoodMaxCriterion
  *
  * @section LICENSE
  *
- * Copyright (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne) Laboratory
- * (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * Copyright (©) 2015-2018 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
- * terms  of the  GNU Lesser  General Public  License as  published by  the Free
+ * 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
+ * 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 "neighborhood_max_criterion.hh"
 #include "grid_synchronizer.hh"
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 NeighborhoodMaxCriterion::NeighborhoodMaxCriterion(
     Model & model, const ElementTypeMapReal & quad_coordinates,
     const ID & criterion_id, const ID & id, const MemoryID & memory_id)
     : NeighborhoodBase(model, quad_coordinates, id, memory_id),
       Parsable(ParserType::_non_local, id),
       is_highest("is_highest", id, memory_id),
       criterion(criterion_id, id, memory_id) {
 
   AKANTU_DEBUG_IN();
 
   this->registerParam("radius", neighborhood_radius, 100.,
                       _pat_parsable | _pat_readable, "Non local radius");
 
   Mesh & mesh = this->model.getMesh();
   /// allocate the element type map arrays for _not_ghosts: One entry per quad
   GhostType ghost_type = _not_ghost;
   Mesh::type_iterator it = mesh.firstType(spatial_dimension, ghost_type);
   Mesh::type_iterator last_type = mesh.lastType(spatial_dimension, ghost_type);
 
   for (; it != last_type; ++it) {
     UInt new_size = this->quad_coordinates(*it, ghost_type).size();
     this->is_highest.alloc(new_size, 1, *it, ghost_type, true);
     this->criterion.alloc(new_size, 1, *it, ghost_type, true);
   }
 
   /// criterion needs allocation also for ghost
   ghost_type = _ghost;
   it = mesh.firstType(spatial_dimension, ghost_type);
   last_type = mesh.lastType(spatial_dimension, ghost_type);
   for (; it != last_type; ++it) {
     UInt new_size = this->quad_coordinates(*it, ghost_type).size();
     this->criterion.alloc(new_size, 1, *it, ghost_type, true);
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 NeighborhoodMaxCriterion::~NeighborhoodMaxCriterion() {
   AKANTU_DEBUG_IN();
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void NeighborhoodMaxCriterion::initNeighborhood() {
   AKANTU_DEBUG_IN();
 
   /// parse the input parameter
   const Parser & parser = getStaticParser();
   const ParserSection & section_neighborhood =
       *(parser.getSubSections(ParserType::_neighborhood).first);
   this->parseSection(section_neighborhood);
 
   AKANTU_DEBUG_INFO("Creating the grid");
   this->createGrid();
 
   /// insert the non-ghost quads into the grid
   this->insertAllQuads(_not_ghost);
 
   /// store the number of current ghost elements for each type in the mesh
   ElementTypeMap<UInt> nb_ghost_protected;
   Mesh & mesh = this->model.getMesh();
   Mesh::type_iterator it = mesh.firstType(spatial_dimension, _ghost);
   Mesh::type_iterator last_type = mesh.lastType(spatial_dimension, _ghost);
   for (; it != last_type; ++it)
     nb_ghost_protected(mesh.getNbElement(*it, _ghost), *it, _ghost);
 
   /// create the grid synchronizer
   this->createGridSynchronizer();
 
   /// insert the ghost quads into the grid
   this->insertAllQuads(_ghost);
 
   /// create the pair lists
   this->updatePairList();
 
   /// remove the unneccessary ghosts
   this->cleanupExtraGhostElements(nb_ghost_protected);
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void NeighborhoodMaxCriterion::createGridSynchronizer() {
   this->is_creating_grid = true;
   std::set<SynchronizationTag> tags;
   tags.insert(_gst_nh_criterion);
 
   std::stringstream sstr;
   sstr << getID() << ":grid_synchronizer";
   this->grid_synchronizer = std::make_unique<GridSynchronizer>(
       this->model.getMesh(), *spatial_grid, *this, tags, sstr.str(), 0, false);
   this->is_creating_grid = false;
 }
 
 /* -------------------------------------------------------------------------- */
 void NeighborhoodMaxCriterion::insertAllQuads(const GhostType & ghost_type) {
   IntegrationPoint q;
   q.ghost_type = ghost_type;
   Mesh & mesh = this->model.getMesh();
 
   Mesh::type_iterator it = mesh.firstType(spatial_dimension, ghost_type);
   Mesh::type_iterator last_type = mesh.lastType(spatial_dimension, ghost_type);
   for (; it != last_type; ++it) {
     UInt nb_element = mesh.getNbElement(*it, ghost_type);
     UInt nb_quad =
         this->model.getFEEngine().getNbIntegrationPoints(*it, ghost_type);
 
     const Array<Real> & quads = this->quad_coordinates(*it, ghost_type);
     q.type = *it;
 
     auto quad = quads.begin(spatial_dimension);
 
     for (UInt e = 0; e < nb_element; ++e) {
       q.element = e;
       for (UInt nq = 0; nq < nb_quad; ++nq) {
         q.num_point = nq;
         q.global_num = q.element * nb_quad + nq;
         spatial_grid->insert(q, *quad);
         ++quad;
       }
     }
   }
 }
 
 /* -------------------------------------------------------------------------- */
 void NeighborhoodMaxCriterion::findMaxQuads(
     std::vector<IntegrationPoint> & max_quads) {
   AKANTU_DEBUG_IN();
 
   /// clear the element type maps
   this->is_highest.clear();
   this->criterion.clear();
 
   /// update the values of the criterion
   this->model.updateDataForNonLocalCriterion(criterion);
 
   /// start the exchange the value of the criterion on the ghost elements
   this->model.asynchronousSynchronize(_gst_nh_criterion);
 
   /// compare to not-ghost neighbors
   checkNeighbors(_not_ghost);
 
   /// finish the exchange
   this->model.waitEndSynchronize(_gst_nh_criterion);
 
   /// compare to ghost neighbors
   checkNeighbors(_ghost);
 
   /// extract the quads with highest criterion in their neighborhood
   IntegrationPoint quad;
   quad.ghost_type = _not_ghost;
   Mesh & mesh = this->model.getMesh();
   Mesh::type_iterator it = mesh.firstType(spatial_dimension, _not_ghost);
   Mesh::type_iterator last_type = mesh.lastType(spatial_dimension, _not_ghost);
   for (; it != last_type; ++it) {
     quad.type = *it;
     Array<bool>::const_scalar_iterator is_highest_it =
         is_highest(*it, _not_ghost).begin();
     Array<bool>::const_scalar_iterator is_highest_end =
         is_highest(*it, _not_ghost).end();
 
     UInt nb_quadrature_points =
         this->model.getFEEngine().getNbIntegrationPoints(*it, _not_ghost);
     UInt q = 0;
 
     /// loop over is_highest for the current element type
     for (; is_highest_it != is_highest_end; ++is_highest_it, ++q) {
       if (*is_highest_it) {
         /// gauss point has the highest stress in his neighbourhood
         quad.element = q / nb_quadrature_points;
         quad.global_num = q;
         quad.num_point = q % nb_quadrature_points;
         max_quads.push_back(quad);
       }
     }
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void NeighborhoodMaxCriterion::checkNeighbors(const GhostType & ghost_type2) {
   AKANTU_DEBUG_IN();
 
   PairList::const_iterator first_pair = pair_list[ghost_type2].begin();
   PairList::const_iterator last_pair = pair_list[ghost_type2].end();
 
   // Compute the weights
   for (; first_pair != last_pair; ++first_pair) {
     const IntegrationPoint & lq1 = first_pair->first;
     const IntegrationPoint & lq2 = first_pair->second;
 
     Array<bool> & has_highest_eq_stress_1 =
         is_highest(lq1.type, lq1.ghost_type);
 
     const Array<Real> & criterion_1 = this->criterion(lq1.type, lq1.ghost_type);
     const Array<Real> & criterion_2 = this->criterion(lq2.type, lq2.ghost_type);
 
     if (criterion_1(lq1.global_num) < criterion_2(lq2.global_num))
       has_highest_eq_stress_1(lq1.global_num) = false;
     else if (ghost_type2 != _ghost) {
       Array<bool> & has_highest_eq_stress_2 =
           is_highest(lq2.type, lq2.ghost_type);
       has_highest_eq_stress_2(lq2.global_num) = false;
     }
   }
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void NeighborhoodMaxCriterion::cleanupExtraGhostElements(
     const ElementTypeMap<UInt> & nb_ghost_protected) {
 
   Mesh & mesh = this->model.getMesh();
   /// create remove elements event
   RemovedElementsEvent remove_elem(mesh);
   /// create set of ghosts to keep
   std::set<Element> relevant_ghost_elements;
   PairList::const_iterator first_pair = pair_list[_ghost].begin();
   PairList::const_iterator last_pair = pair_list[_ghost].end();
   for (; first_pair != last_pair; ++first_pair) {
     const IntegrationPoint & q2 = first_pair->second;
     relevant_ghost_elements.insert(q2);
   }
 
   Array<Element> ghosts_to_erase(0);
   Mesh::type_iterator it = mesh.firstType(spatial_dimension, _ghost);
   Mesh::type_iterator last_type = mesh.lastType(spatial_dimension, _ghost);
 
   Element element;
   element.ghost_type = _ghost;
 
   auto end = relevant_ghost_elements.end();
   for (; it != last_type; ++it) {
     element.type = *it;
     UInt nb_ghost_elem = mesh.getNbElement(*it, _ghost);
     UInt nb_ghost_elem_protected = 0;
     try {
       nb_ghost_elem_protected = nb_ghost_protected(*it, _ghost);
     } catch (...) {
     }
 
     if (!remove_elem.getNewNumbering().exists(*it, _ghost))
       remove_elem.getNewNumbering().alloc(nb_ghost_elem, 1, *it, _ghost);
     else
       remove_elem.getNewNumbering(*it, _ghost).resize(nb_ghost_elem);
     Array<UInt> & new_numbering = remove_elem.getNewNumbering(*it, _ghost);
     for (UInt g = 0; g < nb_ghost_elem; ++g) {
       element.element = g;
       if (element.element >= nb_ghost_elem_protected &&
           relevant_ghost_elements.find(element) == end) {
         ghosts_to_erase.push_back(element);
         new_numbering(element.element) = UInt(-1);
       }
     }
     /// renumber remaining ghosts
     UInt ng = 0;
     for (UInt g = 0; g < nb_ghost_elem; ++g) {
       if (new_numbering(g) != UInt(-1)) {
         new_numbering(g) = ng;
         ++ng;
       }
     }
   }
 
   mesh.sendEvent(remove_elem);
   this->onElementsRemoved(ghosts_to_erase, remove_elem.getNewNumbering(),
                           remove_elem);
 }
 
 } // namespace akantu
diff --git a/src/model/common/neighborhoods_criterion_evaluation/neighborhood_max_criterion.hh b/src/model/common/neighborhoods_criterion_evaluation/neighborhood_max_criterion.hh
index 67b7f51c9..8ff079040 100644
--- a/src/model/common/neighborhoods_criterion_evaluation/neighborhood_max_criterion.hh
+++ b/src/model/common/neighborhoods_criterion_evaluation/neighborhood_max_criterion.hh
@@ -1,117 +1,117 @@
 /**
  * @file   neighborhood_max_criterion.hh
  *
  * @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
  *
  * @date creation: Sat Sep 26 2015
- * @date last modification: Thu Oct 15 2015
+ * @date last modification: Wed Jan 31 2018
  *
  * @brief  Neighborhood to find a maximum value in a neighborhood
  *
  * @section LICENSE
  *
- * Copyright (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne) Laboratory
- * (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * Copyright (©) 2015-2018 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
- * terms  of the  GNU Lesser  General Public  License as  published by  the Free
+ * 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
+ * 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_NEIGHBORHOOD_MAX_CRITERION_BASE_HH__
 #define __AKANTU_NEIGHBORHOOD_MAX_CRITERION_BASE_HH__
 /* -------------------------------------------------------------------------- */
 #include "neighborhood_base.hh"
 #include "parsable.hh"
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 
 class NeighborhoodMaxCriterion : public NeighborhoodBase, public Parsable {
   /* ------------------------------------------------------------------------ */
   /* Constructors/Destructors                                                 */
   /* ------------------------------------------------------------------------ */
 public:
   NeighborhoodMaxCriterion(Model & model,
                            const ElementTypeMapReal & quad_coordinates,
                            const ID & criterion_id,
                            const ID & id = "neighborhood_max_criterion",
                            const MemoryID & memory_id = 0);
   ~NeighborhoodMaxCriterion() override;
 
   /* ------------------------------------------------------------------------ */
   /* Methods                                                                  */
   /* ------------------------------------------------------------------------ */
 
 public:
   /// initialize the neighborhood
   void initNeighborhood() override;
 
   /// create grid synchronizer and exchange ghost cells
   void createGridSynchronizer() override;
 
   /// find the quads which have the maximum criterion in their neighborhood
   void findMaxQuads(std::vector<IntegrationPoint> & max_quads);
 
 protected:
   /// remove unneccessary ghost elements
   void
   cleanupExtraGhostElements(const ElementTypeMap<UInt> & nb_ghost_protected);
 
   /// insert the quadrature points in the grid
   void insertAllQuads(const GhostType & ghost_type);
 
   /// compare criterion with neighbors
   void checkNeighbors(const GhostType & ghost_type);
 
   /* --------------------------------------------------------------------------
    */
   /* DataAccessor inherited members */
   /* --------------------------------------------------------------------------
    */
 public:
   virtual inline UInt getNbDataForElements(const Array<Element> & elements,
                                            SynchronizationTag tag) const;
 
   virtual inline void packElementData(CommunicationBuffer & buffer,
                                       const Array<Element> & elements,
                                       SynchronizationTag tag) const;
 
   virtual inline void unpackElementData(CommunicationBuffer & buffer,
                                         const Array<Element> & elements,
                                         SynchronizationTag tag);
 
   /* --------------------------------------------------------------------------
    */
   /* Accessors */
   /* --------------------------------------------------------------------------
    */
 public:
   /* ------------------------------------------------------------------------ */
   /* Class Members                                                            */
   /* ------------------------------------------------------------------------ */
 protected:
   /// a boolean to store the information if a quad has the max
   /// criterion in the neighborhood
   ElementTypeMapArray<bool> is_highest;
 
   /// an element type map to store the flattened internal of the criterion
   ElementTypeMapReal criterion;
 };
 
 } // akantu
 
 #include "neighborhood_max_criterion_inline_impl.cc"
 
 #endif /* __AKANTU_NEIGHBORHOOD_MAX_CRITERION_BASE_HH__ */
diff --git a/src/model/common/neighborhoods_criterion_evaluation/neighborhood_max_criterion_inline_impl.cc b/src/model/common/neighborhoods_criterion_evaluation/neighborhood_max_criterion_inline_impl.cc
index bb2d331cb..a74051e21 100644
--- a/src/model/common/neighborhoods_criterion_evaluation/neighborhood_max_criterion_inline_impl.cc
+++ b/src/model/common/neighborhoods_criterion_evaluation/neighborhood_max_criterion_inline_impl.cc
@@ -1,81 +1,82 @@
 /**
  * @file   neighborhood_max_criterion_inline_impl.cc
  *
  * @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
+ * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Sat Sep 26 2015
- * @date last modification: Thu Oct 15 2015
+ * @date last modification: Wed Jan 31 2018
  *
  * @brief  Implementation of inline functions for class NeighborhoodMaxCriterion
  *
  * @section LICENSE
  *
- * Copyright (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne) Laboratory
- * (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * Copyright (©) 2015-2018 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
- * terms  of the  GNU Lesser  General Public  License as  published by  the Free
+ * 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
+ * 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 "model.hh"
 #include "neighborhood_max_criterion.hh"
 /* -------------------------------------------------------------------------- */
 
 #ifndef __AKANTU_NEIGHBORHOOD_MAX_CRITERION_INLINE_IMPL_CC__
 #define __AKANTU_NEIGHBORHOOD_MAX_CRITERION_INLINE_IMPL_CC__
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 inline UInt
 NeighborhoodMaxCriterion::getNbDataForElements(const Array<Element> & elements,
                                                SynchronizationTag tag) const {
   UInt nb_quadrature_points = this->model.getNbIntegrationPoints(elements);
   UInt size = 0;
 
   if (tag == _gst_nh_criterion) {
     size += sizeof(Real) * nb_quadrature_points;
   }
 
   return size;
 }
 
 /* -------------------------------------------------------------------------- */
 inline void
 NeighborhoodMaxCriterion::packElementData(CommunicationBuffer & buffer,
                                           const Array<Element> & elements,
                                           SynchronizationTag tag) const {
   if (tag == _gst_nh_criterion) {
     this->packElementalDataHelper(criterion, buffer, elements, true,
                                   this->model.getFEEngine());
   }
 }
 
 /* -------------------------------------------------------------------------- */
 inline void
 NeighborhoodMaxCriterion::unpackElementData(CommunicationBuffer & buffer,
                                             const Array<Element> & elements,
                                             SynchronizationTag tag) {
   if (tag == _gst_nh_criterion) {
     this->unpackElementalDataHelper(criterion, buffer, elements, true,
                                     this->model.getFEEngine());
   }
 }
 
 /* -------------------------------------------------------------------------- */
 
 } // akantu
 
 #endif /* __AKANTU_NEIGHBORHOOD_MAX_CRITERION_INLINE_IMPL_CC__ */
diff --git a/src/model/common/non_local_toolbox/base_weight_function.hh b/src/model/common/non_local_toolbox/base_weight_function.hh
index 202b20073..94808505a 100644
--- a/src/model/common/non_local_toolbox/base_weight_function.hh
+++ b/src/model/common/non_local_toolbox/base_weight_function.hh
@@ -1,169 +1,169 @@
 /**
  * @file   base_weight_function.hh
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  * @author Cyprien Wolff <cyprien.wolff@epfl.ch>
  *
  * @date creation: Mon Aug 24 2015
- * @date last modification: Thu Oct 15 2015
+ * @date last modification: Fri Dec 08 2017
  *
  * @brief  Base weight function for non local materials
  *
  * @section LICENSE
  *
- * Copyright (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne) Laboratory
- * (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * Copyright (©) 2015-2018 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
- * terms  of the  GNU Lesser  General Public  License as  published by  the Free
+ * 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
+ * A PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 #include "data_accessor.hh"
 #include "model.hh"
 #include "non_local_manager.hh"
 #include "parsable.hh"
 /* -------------------------------------------------------------------------- */
 
 #ifndef __AKANTU_BASE_WEIGHT_FUNCTION_HH__
 #define __AKANTU_BASE_WEIGHT_FUNCTION_HH__
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 /*  Normal weight function                                                    */
 /* -------------------------------------------------------------------------- */
 class BaseWeightFunction : public Parsable, public DataAccessor<Element> {
 public:
   /* ------------------------------------------------------------------------ */
   /* Constructors/Destructors                                                 */
   /* ------------------------------------------------------------------------ */
   BaseWeightFunction(NonLocalManager & manager,
                      const std::string & type = "base")
       : Parsable(ParserType::_weight_function, "weight_function:" + type),
         manager(manager), type(type),
         spatial_dimension(manager.getModel().getMesh().getSpatialDimension()) {
     this->registerParam("update_rate", update_rate, UInt(1), _pat_parsmod,
                         "Update frequency");
   }
 
   ~BaseWeightFunction() override = default;
 
   /* ------------------------------------------------------------------------ */
   /* Methods                                                                  */
   /* ------------------------------------------------------------------------ */
   /// initialize the weight function
   virtual inline void init();
 
   /// update the internal parameters
   virtual void updateInternals(){};
 
   /* ------------------------------------------------------------------------ */
   /// set the non-local radius
   inline void setRadius(Real radius);
 
   /* ------------------------------------------------------------------------ */
   /// compute the weight for a given distance between two quadrature points
   inline Real operator()(Real r, const IntegrationPoint & q1,
                          const IntegrationPoint & q2);
 
   /// print function
   void printself(std::ostream & stream, int indent = 0) const override {
     std::string space;
     for (Int i = 0; i < indent; i++, space += AKANTU_INDENT)
       ;
     stream << space << "WeightFunction " << type << " [" << std::endl;
     Parsable::printself(stream, indent);
     stream << space << "]" << std::endl;
   }
 
   /* --------------------------------------------------------------------------
    */
   /* Accessors */
   /* --------------------------------------------------------------------------
    */
 
 public:
   /// get the radius
   Real getRadius() { return R; }
   /// get the update rate
   UInt getUpdateRate() { return update_rate; }
 
 public:
   /* ------------------------------------------------------------------------ */
   /* Data Accessor inherited members                                          */
   /* ------------------------------------------------------------------------ */
 
   UInt getNbData(const Array<Element> &,
                  const SynchronizationTag &) const override {
     return 0;
   }
 
   inline void packData(CommunicationBuffer &, const Array<Element> &,
                        const SynchronizationTag &) const override {}
 
   inline void unpackData(CommunicationBuffer &, const Array<Element> &,
                          const SynchronizationTag &) override {}
 
   /* ------------------------------------------------------------------------ */
   /* Accessors */
   /* ------------------------------------------------------------------------ */
 public:
   AKANTU_GET_MACRO(Type, type, const ID &);
 
 protected:
   /* ------------------------------------------------------------------------ */
   /* Class Members                                                            */
   /* ------------------------------------------------------------------------ */
   /// reference to the non-local manager
   NonLocalManager & manager;
 
   /// the non-local radius
   Real R;
 
   /// the non-local radius squared
   Real R2;
 
   /// the update rate
   UInt update_rate;
 
   /// name of the type of weight function
   const std::string type;
 
   /// the spatial dimension
   UInt spatial_dimension;
 };
 
 inline std::ostream & operator<<(std::ostream & stream,
                                  const BaseWeightFunction & _this) {
   _this.printself(stream);
   return stream;
 }
 
 } // namespace akantu
 
 #include "base_weight_function_inline_impl.cc"
 
 /* -------------------------------------------------------------------------- */
 /* Include all other weight function types                                    */
 /* -------------------------------------------------------------------------- */
 #if defined(AKANTU_DAMAGE_NON_LOCAL)
 #include "damaged_weight_function.hh"
 #include "remove_damaged_weight_function.hh"
 #include "remove_damaged_with_damage_rate_weight_function.hh"
 #include "stress_based_weight_function.hh"
 #endif
 /* -------------------------------------------------------------------------- */
 
 #endif /* __AKANTU_BASE_WEIGHT_FUNCTION_HH__ */
diff --git a/src/model/common/non_local_toolbox/base_weight_function_inline_impl.cc b/src/model/common/non_local_toolbox/base_weight_function_inline_impl.cc
index 0c185e079..d80ccb2cf 100644
--- a/src/model/common/non_local_toolbox/base_weight_function_inline_impl.cc
+++ b/src/model/common/non_local_toolbox/base_weight_function_inline_impl.cc
@@ -1,70 +1,71 @@
 /**
  * @file   base_weight_function_inline_impl.cc
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  * @author Cyprien Wolff <cyprien.wolff@epfl.ch>
  *
- * @date creation: Thu Feb 21 2013
- * @date last modification: Thu Oct 15 2015
+ * @date creation: Wed Sep 01 2010
+ * @date last modification: Wed Sep 27 2017
  *
  * @brief  Implementation of inline function of base weight function
  *
  * @section LICENSE
  *
- * Copyright  (©)  2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de Lausanne)
+ * 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
+ * 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
+ * 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 "base_weight_function.hh"
 /* -------------------------------------------------------------------------- */
 
 #ifndef __AKANTU_BASE_WEIGHT_FUNCTION_INLINE_IMPL_CC__
 #define __AKANTU_BASE_WEIGHT_FUNCTION_INLINE_IMPL_CC__
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 inline void BaseWeightFunction::init() {
   /// compute R^2 for a given non-local radius
   this->R2 = this->R * this->R;
 }
 
 /* -------------------------------------------------------------------------- */
 inline void BaseWeightFunction::setRadius(Real radius) {
   /// set the non-local radius and update R^2 accordingly
   this->R = radius;
   this->R2 = this->R * this->R;
 }
 
 /* -------------------------------------------------------------------------- */
 inline Real BaseWeightFunction::operator()(Real r, const IntegrationPoint &,
                                            const IntegrationPoint &) {
 
   /// initialize the weight
   Real w = 0;
   /// compute weight for given r
   if (r <= this->R) {
     Real alpha = (1. - r * r / this->R2);
     w = alpha * alpha;
     // *weight = 1 - sqrt(r / radius);
   }
 
   return w;
 }
 
 } // akantu
 #endif /* __AKANTU_BASE_WEIGHT_FUNCTION_INLINE_IMPL_CC__ */
diff --git a/src/model/common/non_local_toolbox/non_local_manager.cc b/src/model/common/non_local_toolbox/non_local_manager.cc
index 386c3ee82..7fb9868df 100644
--- a/src/model/common/non_local_toolbox/non_local_manager.cc
+++ b/src/model/common/non_local_toolbox/non_local_manager.cc
@@ -1,639 +1,638 @@
 /**
  * @file   non_local_manager.cc
  *
  * @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Fri Apr 13 2012
- * @date last modification: Wed Dec 16 2015
+ * @date last modification: Tue Jan 16 2018
  *
  * @brief  Implementation of non-local manager
  *
  * @section LICENSE
  *
- * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
- * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
- * Solides)
+ * 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
+ * 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
+ * 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 "non_local_manager.hh"
 #include "grid_synchronizer.hh"
 #include "model.hh"
 #include "non_local_neighborhood.hh"
 /* -------------------------------------------------------------------------- */
 #include <numeric>
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 NonLocalManager::NonLocalManager(Model & model,
                                  NonLocalManagerCallback & callback,
                                  const ID & id, const MemoryID & memory_id)
     : Memory(id, memory_id), Parsable(ParserType::_neighborhoods, id),
       spatial_dimension(model.getMesh().getSpatialDimension()), model(model),
       integration_points_positions("integration_points_positions", id,
                                    memory_id),
       volumes("volumes", id, memory_id), compute_stress_calls(0),
       dummy_registry(nullptr), dummy_grid(nullptr) {
   /// parse the neighborhood information from the input file
   const Parser & parser = getStaticParser();
 
   /// iterate over all the non-local sections and store them in a map
   std::pair<Parser::const_section_iterator, Parser::const_section_iterator>
       weight_sect = parser.getSubSections(ParserType::_non_local);
   Parser::const_section_iterator it = weight_sect.first;
   for (; it != weight_sect.second; ++it) {
     const ParserSection & section = *it;
     ID name = section.getName();
     this->weight_function_types[name] = section;
   }
 
   this->callback = &callback;
 }
 
 /* -------------------------------------------------------------------------- */
 NonLocalManager::~NonLocalManager() = default;
 
 /* -------------------------------------------------------------------------- */
 void NonLocalManager::initialize() {
   volumes.initialize(this->model.getFEEngine(),
                      _spatial_dimension = spatial_dimension);
 
   AKANTU_DEBUG_ASSERT(this->callback,
                       "A callback should be registered prior to this call");
   this->callback->insertIntegrationPointsInNeighborhoods(_not_ghost);
 
   auto & mesh = this->model.getMesh();
   mesh.registerEventHandler(*this, _ehp_non_local_manager);
 
   /// store the number of current ghost elements for each type in the mesh
   // ElementTypeMap<UInt> nb_ghost_protected;
   // for (auto type : mesh.elementTypes(spatial_dimension, _ghost))
   //   nb_ghost_protected(mesh.getNbElement(type, _ghost), type, _ghost);
 
   /// exchange the missing ghosts for the non-local neighborhoods
   this->createNeighborhoodSynchronizers();
 
   /// insert the ghost quadrature points of the non-local materials into the
   /// non-local neighborhoods
   this->callback->insertIntegrationPointsInNeighborhoods(_ghost);
 
   FEEngine & fee = this->model.getFEEngine();
   this->updatePairLists();
 
   /// cleanup the unneccessary ghost elements
   this->cleanupExtraGhostElements(); // nb_ghost_protected);
 
   this->callback->initializeNonLocal();
 
   this->setJacobians(fee, _ek_regular);
 
   this->initNonLocalVariables();
   this->computeWeights();
 }
 
 /* -------------------------------------------------------------------------- */
 void NonLocalManager::setJacobians(const FEEngine & fe_engine,
                                    const ElementKind & kind) {
   Mesh & mesh = this->model.getMesh();
   for (auto ghost_type : ghost_types) {
     for (auto type : mesh.elementTypes(spatial_dimension, ghost_type, kind)) {
       jacobians(type, ghost_type) =
           &fe_engine.getIntegratorInterface().getJacobians(type, ghost_type);
     }
   }
 }
 
 /* -------------------------------------------------------------------------- */
 void NonLocalManager::createNeighborhood(const ID & weight_func,
                                          const ID & neighborhood_id) {
 
   AKANTU_DEBUG_IN();
 
   auto weight_func_it = this->weight_function_types.find(weight_func);
   AKANTU_DEBUG_ASSERT(weight_func_it != weight_function_types.end(),
                       "No info found in the input file for the weight_function "
                           << weight_func << " in the neighborhood "
                           << neighborhood_id);
 
   const ParserSection & section = weight_func_it->second;
   const ID weight_func_type = section.getOption();
   /// create new neighborhood for given ID
   std::stringstream sstr;
   sstr << id << ":neighborhood:" << neighborhood_id;
 
   if (weight_func_type == "base_wf")
     neighborhoods[neighborhood_id] =
         std::make_unique<NonLocalNeighborhood<BaseWeightFunction>>(
             *this, this->integration_points_positions, sstr.str());
 #if defined(AKANTU_DAMAGE_NON_LOCAL)
   else if (weight_func_type == "remove_wf")
     neighborhoods[neighborhood_id] =
         std::make_unique<NonLocalNeighborhood<RemoveDamagedWeightFunction>>(
             *this, this->integration_points_positions, sstr.str());
   else if (weight_func_type == "stress_wf")
     neighborhoods[neighborhood_id] =
         std::make_unique<NonLocalNeighborhood<StressBasedWeightFunction>>(
             *this, this->integration_points_positions, sstr.str());
   else if (weight_func_type == "damage_wf")
     neighborhoods[neighborhood_id] =
         std::make_unique<NonLocalNeighborhood<DamagedWeightFunction>>(
             *this, this->integration_points_positions, sstr.str());
 #endif
   else
     AKANTU_EXCEPTION("error in weight function type provided in material file");
 
   neighborhoods[neighborhood_id]->parseSection(section);
   neighborhoods[neighborhood_id]->initNeighborhood();
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void NonLocalManager::createNeighborhoodSynchronizers() {
   /// exchange all the neighborhood IDs, so that every proc knows how many
   /// neighborhoods exist globally
   /// First: Compute locally the maximum ID size
   UInt max_id_size = 0;
   UInt current_size = 0;
   NeighborhoodMap::const_iterator it;
   for (it = neighborhoods.begin(); it != neighborhoods.end(); ++it) {
     current_size = it->first.size();
     if (current_size > max_id_size)
       max_id_size = current_size;
   }
 
   /// get the global maximum ID size on each proc
   const Communicator & static_communicator = model.getMesh().getCommunicator();
   static_communicator.allReduce(max_id_size, SynchronizerOperation::_max);
 
   /// get the rank for this proc and the total nb proc
   UInt prank = static_communicator.whoAmI();
   UInt psize = static_communicator.getNbProc();
 
   /// exchange the number of neighborhoods on each proc
   Array<Int> nb_neighborhoods_per_proc(psize);
   nb_neighborhoods_per_proc(prank) = neighborhoods.size();
   static_communicator.allGather(nb_neighborhoods_per_proc);
 
   /// compute the total number of neighborhoods
   UInt nb_neighborhoods_global = std::accumulate(
       nb_neighborhoods_per_proc.begin(), nb_neighborhoods_per_proc.end(), 0);
 
   /// allocate an array of chars to store the names of all neighborhoods
   Array<char> buffer(nb_neighborhoods_global, max_id_size);
 
   /// starting index on this proc
   UInt starting_index =
       std::accumulate(nb_neighborhoods_per_proc.begin(),
                       nb_neighborhoods_per_proc.begin() + prank, 0);
 
   it = neighborhoods.begin();
   /// store the names of local neighborhoods in the buffer
   for (UInt i = 0; i < neighborhoods.size(); ++i, ++it) {
     UInt c = 0;
     for (; c < it->first.size(); ++c)
       buffer(i + starting_index, c) = it->first[c];
 
     for (; c < max_id_size; ++c)
       buffer(i + starting_index, c) = char(0);
   }
 
   /// store the nb of data to send in the all gather
   Array<Int> buffer_size(nb_neighborhoods_per_proc);
   buffer_size *= max_id_size;
   /// exchange the names of all the neighborhoods with all procs
   static_communicator.allGatherV(buffer, buffer_size);
 
   for (UInt i = 0; i < nb_neighborhoods_global; ++i) {
     std::stringstream neighborhood_id;
     for (UInt c = 0; c < max_id_size; ++c) {
       if (buffer(i, c) == char(0))
         break;
       neighborhood_id << buffer(i, c);
     }
     global_neighborhoods.insert(neighborhood_id.str());
   }
 
   /// this proc does not know all the neighborhoods -> create dummy
   /// grid so that this proc can participate in the all gather for
   /// detecting the overlap of neighborhoods this proc doesn't know
   Vector<Real> grid_center(this->spatial_dimension,
                            std::numeric_limits<Real>::max());
   Vector<Real> spacing(this->spatial_dimension, 0.);
 
   dummy_grid = std::make_unique<SpatialGrid<IntegrationPoint>>(
       this->spatial_dimension, spacing, grid_center);
 
   for (auto & neighborhood_id : global_neighborhoods) {
     it = neighborhoods.find(neighborhood_id);
     if (it != neighborhoods.end()) {
       it->second->createGridSynchronizer();
     } else {
       dummy_synchronizers[neighborhood_id] = std::make_unique<GridSynchronizer>(
           this->model.getMesh(), *dummy_grid,
           std::string(this->id + ":" + neighborhood_id + ":grid_synchronizer"),
           this->memory_id, false);
     }
   }
 }
 
 /* -------------------------------------------------------------------------- */
 void NonLocalManager::synchronize(DataAccessor<Element> & data_accessor,
                                   const SynchronizationTag & tag) {
   for (auto & neighborhood_id : global_neighborhoods) {
     auto it = neighborhoods.find(neighborhood_id);
     if (it != neighborhoods.end()) {
       it->second->synchronize(data_accessor, tag);
     } else {
       auto synchronizer_it = dummy_synchronizers.find(neighborhood_id);
       if (synchronizer_it == dummy_synchronizers.end())
         continue;
 
       synchronizer_it->second->synchronizeOnce(data_accessor, tag);
     }
   }
 }
 
 /* -------------------------------------------------------------------------- */
 void NonLocalManager::averageInternals(const GhostType & ghost_type) {
   /// update the weights of the weight function
   if (ghost_type == _not_ghost)
     this->computeWeights();
 
   /// loop over all neighborhoods and compute the non-local variables
   for (auto & neighborhood : neighborhoods) {
     /// loop over all the non-local variables of the given neighborhood
     for (auto & non_local_variable : non_local_variables) {
       NonLocalVariable & non_local_var = *non_local_variable.second;
       neighborhood.second->weightedAverageOnNeighbours(
           non_local_var.local, non_local_var.non_local,
           non_local_var.nb_component, ghost_type);
     }
   }
 }
 
 /* -------------------------------------------------------------------------- */
 void NonLocalManager::computeWeights() {
   AKANTU_DEBUG_IN();
 
   this->updateWeightFunctionInternals();
   this->volumes.clear();
 
   for (const auto & global_neighborhood : global_neighborhoods) {
     auto it = neighborhoods.find(global_neighborhood);
 
     if (it != neighborhoods.end())
       it->second->updateWeights();
     else {
       dummy_synchronizers[global_neighborhood]->synchronize(dummy_accessor,
                                                             _gst_mnl_weight);
     }
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void NonLocalManager::updatePairLists() {
   AKANTU_DEBUG_IN();
 
   integration_points_positions.initialize(
       this->model.getFEEngine(), _nb_component = spatial_dimension,
       _spatial_dimension = spatial_dimension);
 
   /// compute the position of the quadrature points
   this->model.getFEEngine().computeIntegrationPointsCoordinates(
       integration_points_positions);
 
   for (auto & pair : neighborhoods)
     pair.second->updatePairList();
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void NonLocalManager::registerNonLocalVariable(const ID & variable_name,
                                                const ID & nl_variable_name,
                                                UInt nb_component) {
 
   AKANTU_DEBUG_IN();
 
   auto non_local_variable_it = non_local_variables.find(variable_name);
 
   if (non_local_variable_it == non_local_variables.end())
     non_local_variables[nl_variable_name] = std::make_unique<NonLocalVariable>(
         variable_name, nl_variable_name, this->id, nb_component);
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 ElementTypeMapReal &
 NonLocalManager::registerWeightFunctionInternal(const ID & field_name) {
 
   AKANTU_DEBUG_IN();
 
   auto it = this->weight_function_internals.find(field_name);
   if (it == weight_function_internals.end()) {
     weight_function_internals[field_name] =
         std::make_unique<ElementTypeMapReal>(field_name, this->id,
                                              this->memory_id);
   }
 
   AKANTU_DEBUG_OUT();
 
   return *(weight_function_internals[field_name]);
 }
 
 /* -------------------------------------------------------------------------- */
 void NonLocalManager::updateWeightFunctionInternals() {
   for (auto & pair : this->weight_function_internals) {
     auto & internals = *pair.second;
     internals.clear();
     for (auto ghost_type : ghost_types)
       this->callback->updateLocalInternal(internals, ghost_type, _ek_regular);
   }
 }
 
 /* -------------------------------------------------------------------------- */
 void NonLocalManager::initNonLocalVariables() {
   /// loop over all the non-local variables
   for (auto & pair : non_local_variables) {
     auto & variable = *pair.second;
     variable.non_local.initialize(this->model.getFEEngine(),
                                   _nb_component = variable.nb_component,
                                   _spatial_dimension = spatial_dimension);
   }
 }
 
 /* -------------------------------------------------------------------------- */
 void NonLocalManager::computeAllNonLocalStresses() {
 
   /// update the flattened version of the internals
   for (auto & pair : non_local_variables) {
     auto & variable = *pair.second;
     variable.local.clear();
     variable.non_local.clear();
     for (auto ghost_type : ghost_types) {
       this->callback->updateLocalInternal(variable.local, ghost_type,
                                           _ek_regular);
     }
   }
 
   this->volumes.clear();
 
   for (auto & pair : neighborhoods) {
     auto & neighborhood = *pair.second;
     neighborhood.asynchronousSynchronize(_gst_mnl_for_average);
   }
 
   this->averageInternals(_not_ghost);
 
   AKANTU_DEBUG_INFO("Wait distant non local stresses");
 
   for (auto & pair : neighborhoods) {
     auto & neighborhood = *pair.second;
     neighborhood.waitEndSynchronize(_gst_mnl_for_average);
   }
 
   this->averageInternals(_ghost);
 
   /// copy the results in the materials
   for (auto & pair : non_local_variables) {
     auto & variable = *pair.second;
     for (auto ghost_type : ghost_types) {
       this->callback->updateNonLocalInternal(variable.non_local, ghost_type,
                                              _ek_regular);
     }
   }
 
   this->callback->computeNonLocalStresses(_not_ghost);
 
   ++this->compute_stress_calls;
 }
 
 /* -------------------------------------------------------------------------- */
 void NonLocalManager::cleanupExtraGhostElements() {
   // ElementTypeMap<UInt> & nb_ghost_protected) {
 
   using ElementSet = std::set<Element>;
   ElementSet relevant_ghost_elements;
 
   /// loop over all the neighborhoods and get their protected ghosts
   for (auto & pair : neighborhoods) {
     auto & neighborhood = *pair.second;
     ElementSet to_keep_per_neighborhood;
 
     neighborhood.cleanupExtraGhostElements(to_keep_per_neighborhood);
     for (auto & element : to_keep_per_neighborhood)
       relevant_ghost_elements.insert(element);
   }
 
   // /// remove all unneccessary ghosts from the mesh
   // /// Create list of element to remove and new numbering for element to keep
   // Mesh & mesh = this->model.getMesh();
   // ElementSet ghost_to_erase;
 
   // RemovedElementsEvent remove_elem(mesh);
   // auto & new_numberings = remove_elem.getNewNumbering();
   // Element element;
   // element.ghost_type = _ghost;
 
   // for (auto & type : mesh.elementTypes(spatial_dimension, _ghost)) {
   //   element.type = type;
   //   UInt nb_ghost_elem = mesh.getNbElement(type, _ghost);
   //   // UInt nb_ghost_elem_protected = 0;
   //   // try {
   //   //   nb_ghost_elem_protected = nb_ghost_protected(type, _ghost);
   //   // } catch (...) {
   //   // }
 
   //   if (!new_numberings.exists(type, _ghost))
   //     new_numberings.alloc(nb_ghost_elem, 1, type, _ghost);
   //   else
   //     new_numberings(type, _ghost).resize(nb_ghost_elem);
 
   //   Array<UInt> & new_numbering = new_numberings(type, _ghost);
   //   for (UInt g = 0; g < nb_ghost_elem; ++g) {
   //     element.element = g;
   //     if (element.element >= nb_ghost_elem_protected &&
   //         relevant_ghost_elements.find(element) ==
   //             relevant_ghost_elements.end()) {
   //       remove_elem.getList().push_back(element);
   //       new_numbering(element.element) = UInt(-1);
   //     }
   //   }
   //   /// renumber remaining ghosts
   //   UInt ng = 0;
   //   for (UInt g = 0; g < nb_ghost_elem; ++g) {
   //     if (new_numbering(g) != UInt(-1)) {
   //       new_numbering(g) = ng;
   //       ++ng;
   //     }
   //   }
   // }
 
   // for (auto & type : mesh.elementTypes(spatial_dimension, _not_ghost)) {
   //   UInt nb_elem = mesh.getNbElement(type, _not_ghost);
   //   if (!new_numberings.exists(type, _not_ghost))
   //     new_numberings.alloc(nb_elem, 1, type, _not_ghost);
   //   Array<UInt> & new_numbering = new_numberings(type, _not_ghost);
   //   for (UInt e = 0; e < nb_elem; ++e) {
   //     new_numbering(e) = e;
   //   }
   // }
   // mesh.sendEvent(remove_elem);
 }
 
 /* -------------------------------------------------------------------------- */
 void NonLocalManager::onElementsRemoved(
     const Array<Element> & element_list,
     const ElementTypeMapArray<UInt> & new_numbering,
     __attribute__((unused)) const RemovedElementsEvent & event) {
 
   FEEngine & fee = this->model.getFEEngine();
   this->removeIntegrationPointsFromMap(
       event.getNewNumbering(), spatial_dimension, integration_points_positions,
       fee, _ek_regular);
   this->removeIntegrationPointsFromMap(event.getNewNumbering(), 1, volumes, fee,
                                        _ek_regular);
 
   /// loop over all the neighborhoods and call onElementsRemoved
   auto global_neighborhood_it = global_neighborhoods.begin();
   NeighborhoodMap::iterator it;
   for (; global_neighborhood_it != global_neighborhoods.end();
        ++global_neighborhood_it) {
     it = neighborhoods.find(*global_neighborhood_it);
     if (it != neighborhoods.end())
       it->second->onElementsRemoved(element_list, new_numbering, event);
     else
       dummy_synchronizers[*global_neighborhood_it]->onElementsRemoved(
           element_list, new_numbering, event);
   }
 }
 
 /* -------------------------------------------------------------------------- */
 void NonLocalManager::onElementsAdded(const Array<Element> &,
                                       const NewElementsEvent &) {
   this->resizeElementTypeMap(1, volumes, model.getFEEngine());
   this->resizeElementTypeMap(spatial_dimension, integration_points_positions,
                              model.getFEEngine());
 }
 
 /* -------------------------------------------------------------------------- */
 void NonLocalManager::resizeElementTypeMap(UInt nb_component,
                                            ElementTypeMapReal & element_map,
                                            const FEEngine & fee,
                                            const ElementKind el_kind) {
   Mesh & mesh = this->model.getMesh();
 
   for (auto gt : ghost_types) {
     for (auto type : mesh.elementTypes(spatial_dimension, gt, el_kind)) {
       UInt nb_element = mesh.getNbElement(type, gt);
       UInt nb_quads = fee.getNbIntegrationPoints(type, gt);
       if (!element_map.exists(type, gt))
         element_map.alloc(nb_element * nb_quads, nb_component, type, gt);
       else
         element_map(type, gt).resize(nb_element * nb_quads);
     }
   }
 }
 
 /* -------------------------------------------------------------------------- */
 void NonLocalManager::removeIntegrationPointsFromMap(
     const ElementTypeMapArray<UInt> & new_numbering, UInt nb_component,
     ElementTypeMapReal & element_map, const FEEngine & fee,
     const ElementKind el_kind) {
 
   for (auto gt : ghost_types) {
     for (auto type : new_numbering.elementTypes(_all_dimensions, gt, el_kind)) {
       if (element_map.exists(type, gt)) {
         const Array<UInt> & renumbering = new_numbering(type, gt);
 
         Array<Real> & vect = element_map(type, gt);
         UInt nb_quad_per_elem = fee.getNbIntegrationPoints(type, gt);
         Array<Real> tmp(renumbering.size() * nb_quad_per_elem, nb_component);
 
         AKANTU_DEBUG_ASSERT(
             tmp.size() == vect.size(),
             "Something strange append some mater was created or disappeared in "
                 << vect.getID() << "(" << vect.size() << "!=" << tmp.size()
                 << ") "
                    "!!");
 
         UInt new_size = 0;
         for (UInt i = 0; i < renumbering.size(); ++i) {
           UInt new_i = renumbering(i);
           if (new_i != UInt(-1)) {
             memcpy(tmp.storage() + new_i * nb_component * nb_quad_per_elem,
                    vect.storage() + i * nb_component * nb_quad_per_elem,
                    nb_component * nb_quad_per_elem * sizeof(Real));
             ++new_size;
           }
         }
         tmp.resize(new_size * nb_quad_per_elem);
         vect.copy(tmp);
       }
     }
   }
 }
 
 /* -------------------------------------------------------------------------- */
 UInt NonLocalManager::getNbData(const Array<Element> & elements,
                                 const ID & id) const {
   UInt size = 0;
   UInt nb_quadrature_points = this->model.getNbIntegrationPoints(elements);
   auto it = non_local_variables.find(id);
 
   AKANTU_DEBUG_ASSERT(it != non_local_variables.end(),
                       "The non-local variable " << id << " is not registered");
 
   size += it->second->nb_component * sizeof(Real) * nb_quadrature_points;
   return size;
 }
 
 /* -------------------------------------------------------------------------- */
 void NonLocalManager::packData(CommunicationBuffer & buffer,
                                const Array<Element> & elements,
                                const ID & id) const {
 
   auto it = non_local_variables.find(id);
 
   AKANTU_DEBUG_ASSERT(it != non_local_variables.end(),
                       "The non-local variable " << id << " is not registered");
 
   DataAccessor<Element>::packElementalDataHelper<Real>(
       it->second->local, buffer, elements, true, this->model.getFEEngine());
 }
 
 /* -------------------------------------------------------------------------- */
 void NonLocalManager::unpackData(CommunicationBuffer & buffer,
                                  const Array<Element> & elements,
                                  const ID & id) const {
   auto it = non_local_variables.find(id);
 
   AKANTU_DEBUG_ASSERT(it != non_local_variables.end(),
                       "The non-local variable " << id << " is not registered");
 
   DataAccessor<Element>::unpackElementalDataHelper<Real>(
       it->second->local, buffer, elements, true, this->model.getFEEngine());
 }
 
 } // namespace akantu
diff --git a/src/model/common/non_local_toolbox/non_local_manager.hh b/src/model/common/non_local_toolbox/non_local_manager.hh
index cca5c52f1..775fb4982 100644
--- a/src/model/common/non_local_toolbox/non_local_manager.hh
+++ b/src/model/common/non_local_toolbox/non_local_manager.hh
@@ -1,292 +1,292 @@
 /**
  * @file   non_local_manager.hh
  *
  * @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Fri Jun 18 2010
- * @date last modification: Tue Dec 08 2015
+ * @date last modification: Wed Nov 08 2017
  *
  * @brief  Classes that manages all the non-local neighborhoods
  *
  * @section LICENSE
  *
- * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
- * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
- * Solides)
+ * 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
+ * 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
+ * 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 "communication_buffer.hh"
 #include "data_accessor.hh"
 #include "mesh_events.hh"
 #include "non_local_manager_callback.hh"
 #include "parsable.hh"
 /* -------------------------------------------------------------------------- */
 #include <map>
 #include <set>
 /* -------------------------------------------------------------------------- */
 
 /* -------------------------------------------------------------------------- */
 #ifndef __AKANTU_NON_LOCAL_MANAGER_HH__
 #define __AKANTU_NON_LOCAL_MANAGER_HH__
 
 namespace akantu {
 class Model;
 class NonLocalNeighborhoodBase;
 class GridSynchronizer;
 class SynchronizerRegistry;
 class IntegrationPoint;
 template <typename T> class SpatialGrid;
 class FEEngine;
 } // namespace akantu
 
 namespace akantu {
 
 class NonLocalManager : protected Memory,
                         public MeshEventHandler,
                         public Parsable {
   /* ------------------------------------------------------------------------ */
   /* Constructors/Destructors                                                 */
   /* ------------------------------------------------------------------------ */
 public:
   NonLocalManager(Model & model, NonLocalManagerCallback & callback,
                   const ID & id = "non_local_manager",
                   const MemoryID & memory_id = 0);
   ~NonLocalManager() override;
   using NeighborhoodMap =
       std::map<ID, std::unique_ptr<NonLocalNeighborhoodBase>>;
 
   /* ------------------------------------------------------------------------ */
   /* Methods                                                                  */
   /* -----------------------------------------------------------------------  */
 public:
   /// register a new internal needed for the weight computations
   ElementTypeMapReal & registerWeightFunctionInternal(const ID & field_name);
 
   /// register a non-local variable
   void registerNonLocalVariable(const ID & variable_name,
                                 const ID & nl_variable_name, UInt nb_component);
 
   /// register non-local neighborhood
   inline void registerNeighborhood(const ID & neighborhood,
                                    const ID & weight_func_id);
 
   // void registerNonLocalManagerCallback(NonLocalManagerCallback & callback);
 
   /// average the internals and compute the non-local stresses
   virtual void computeAllNonLocalStresses();
 
   /// initialize the non-local manager: compute pair lists and weights for all
   /// neighborhoods
   virtual void initialize();
 
   /// synchronize once on a given tag using the neighborhoods synchronizer
   void synchronize(DataAccessor<Element> & data_accessor,
                    const SynchronizationTag &);
 
 protected:
   /// create the grid synchronizers for each neighborhood
   void createNeighborhoodSynchronizers();
 
   /// compute the weights in each neighborhood for non-local averaging
   void computeWeights();
 
   /// compute the weights in each neighborhood for non-local averaging
   void updatePairLists();
 
   /// average the non-local variables
   void averageInternals(const GhostType & ghost_type = _not_ghost);
 
   /// update the flattened version of the weight function internals
   void updateWeightFunctionInternals();
 
 protected:
   /// create a new neighborhood for a given domain ID
   void createNeighborhood(const ID & weight_func, const ID & neighborhood);
 
   /// set the values of the jacobians
   void setJacobians(const FEEngine & fe_engine, const ElementKind & kind);
 
   /// allocation of eelment type maps
   // void initElementTypeMap(UInt nb_component,
   //                         ElementTypeMapReal & element_map,
   //                         const FEEngine & fe_engine,
   //                         const ElementKind el_kind = _ek_regular);
 
   /// resizing of element type maps
   void resizeElementTypeMap(UInt nb_component, ElementTypeMapReal & element_map,
                             const FEEngine & fee,
                             const ElementKind el_kind = _ek_regular);
 
   /// remove integration points from element type maps
   void removeIntegrationPointsFromMap(
       const ElementTypeMapArray<UInt> & new_numbering, UInt nb_component,
       ElementTypeMapReal & element_map, const FEEngine & fee,
       const ElementKind el_kind = _ek_regular);
 
   /// allocate the non-local variables
   void initNonLocalVariables();
 
   /// cleanup unneccessary ghosts
   void
   cleanupExtraGhostElements(); // ElementTypeMap<UInt> & nb_ghost_protected);
 
   /* ------------------------------------------------------------------------ */
   /* DataAccessor kind of interface                                           */
   /* ------------------------------------------------------------------------ */
 public:
   /// get Nb data for synchronization in parallel
   UInt getNbData(const Array<Element> & elements, const ID & id) const;
 
   /// pack data for synchronization in parallel
   void packData(CommunicationBuffer & buffer, const Array<Element> & elements,
                 const ID & id) const;
 
   /// unpack data for synchronization in parallel
   void unpackData(CommunicationBuffer & buffer, const Array<Element> & elements,
                   const ID & id) const;
 
   /* ------------------------------------------------------------------------ */
   /* MeshEventHandler inherited members                                       */
   /* ------------------------------------------------------------------------ */
 public:
   void onElementsRemoved(const Array<Element> & element_list,
                          const ElementTypeMapArray<UInt> & new_numbering,
                          const RemovedElementsEvent & event) override;
   void onElementsAdded(const Array<Element> & element_list,
                        const NewElementsEvent & event) override;
   void onElementsChanged(const Array<Element> &, const Array<Element> &,
                          const ElementTypeMapArray<UInt> &,
                          const ChangedElementsEvent &) override {}
 
   void onNodesAdded(const Array<UInt> &, const NewNodesEvent &) override {}
   void onNodesRemoved(const Array<UInt> &, const Array<UInt> &,
                       const RemovedNodesEvent &) override{};
 
   /* ------------------------------------------------------------------------ */
   /* Accessors                                                                */
   /* ------------------------------------------------------------------------ */
 public:
   AKANTU_GET_MACRO(SpatialDimension, spatial_dimension, UInt);
   AKANTU_GET_MACRO(Model, model, const Model &);
   AKANTU_GET_MACRO_NOT_CONST(Model, model, Model &);
   AKANTU_GET_MACRO_NOT_CONST(Volumes, volumes, ElementTypeMapReal &)
   AKANTU_GET_MACRO(NbStressCalls, compute_stress_calls, UInt);
 
   /// return the fem object associated with a provided name
   inline NonLocalNeighborhoodBase & getNeighborhood(const ID & name) const;
 
   inline const Array<Real> & getJacobians(const ElementType & type,
                                           const GhostType & ghost_type) {
     return *jacobians(type, ghost_type);
   }
 
   /* ------------------------------------------------------------------------ */
   /* Class Members                                                            */
   /* ------------------------------------------------------------------------ */
 private:
   /// the spatial dimension
   const UInt spatial_dimension;
 
 protected:
   /// the non-local neighborhoods present
   NeighborhoodMap neighborhoods;
 
   /// list of all the non-local materials in the model
   //  std::vector<ID> non_local_materials;
 
   struct NonLocalVariable {
     NonLocalVariable(const ID & variable_name, const ID & nl_variable_name,
                      const ID & id, UInt nb_component)
         : local(variable_name, id, 0), non_local(nl_variable_name, id, 0),
           nb_component(nb_component) {}
     ElementTypeMapReal local;
     ElementTypeMapReal non_local;
     UInt nb_component;
   };
 
   /// the non-local variables associated to a certain neighborhood
   std::map<ID, std::unique_ptr<NonLocalVariable>> non_local_variables;
 
   /// reference to the model
   Model & model;
 
   /// jacobians for all the elements in the mesh
   ElementTypeMap<const Array<Real> *> jacobians;
 
   /// store the position of the quadrature points
   ElementTypeMapReal integration_points_positions;
 
   /// store the volume of each quadrature point for the non-local weight
   /// normalization
   ElementTypeMapReal volumes;
 
   /// counter for computeStress calls
   UInt compute_stress_calls;
 
   /// map to store weight function types from input file
   std::map<ID, ParserSection> weight_function_types;
 
   /// map to store the internals needed by the weight functions
   std::map<ID, std::unique_ptr<ElementTypeMapReal>> weight_function_internals;
   /* --------------------------------------------------------------------------
    */
   /// the following are members needed to make this processor participate in the
   /// grid creation of neighborhoods he doesn't own as a member. For details see
   /// createGridSynchronizers function
 
   /// synchronizer registry for dummy grid synchronizers
   std::unique_ptr<SynchronizerRegistry> dummy_registry;
 
   /// map of dummy synchronizers
   std::map<ID, std::unique_ptr<GridSynchronizer>> dummy_synchronizers;
 
   /// dummy spatial grid
   std::unique_ptr<SpatialGrid<IntegrationPoint>> dummy_grid;
 
   /// create a set of all neighborhoods present in the simulation
   std::set<ID> global_neighborhoods;
 
   class DummyDataAccessor : public DataAccessor<Element> {
   public:
     inline UInt getNbData(const Array<Element> &,
                           const SynchronizationTag &) const override {
       return 0;
     };
 
     inline void packData(CommunicationBuffer &, const Array<Element> &,
                          const SynchronizationTag &) const override{};
 
     inline void unpackData(CommunicationBuffer &, const Array<Element> &,
                            const SynchronizationTag &) override{};
   };
 
   DummyDataAccessor dummy_accessor;
 
   /* ------------------------------------------------------------------------ */
   NonLocalManagerCallback * callback;
 };
 
 } // namespace akantu
 
 /* -------------------------------------------------------------------------- */
 /* inline functions                                                           */
 /* -------------------------------------------------------------------------- */
 
 #include "non_local_manager_inline_impl.cc"
 
 #endif /* __AKANTU_NON_LOCAL_MANAGER_HH__ */
diff --git a/src/model/common/non_local_toolbox/non_local_manager_callback.hh b/src/model/common/non_local_toolbox/non_local_manager_callback.hh
index f29671b4d..b44a520e8 100644
--- a/src/model/common/non_local_toolbox/non_local_manager_callback.hh
+++ b/src/model/common/non_local_toolbox/non_local_manager_callback.hh
@@ -1,66 +1,68 @@
 /**
  * @file   non_local_manager_callback.hh
  *
- * @author Nicolas Richart
+ * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
- * @date creation  Sun Jul 09 2017
+ * @date creation: Fri Jul 21 2017
+ * @date last modification: Tue Sep 19 2017
  *
- * @brief Callback functions for the non local manager
+ * @brief  Callback functions for the non local manager
  *
  * @section LICENSE
  *
- * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * 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
+ * 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
+ * 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 "element_type_map.hh"
 /* -------------------------------------------------------------------------- */
 
 #ifndef __AKANTU_NON_LOCAL_MANAGER_CALLBACK_HH__
 #define __AKANTU_NON_LOCAL_MANAGER_CALLBACK_HH__
 
 namespace akantu {
 class NonLocalManager;
 } // namespace akantu
 
 namespace akantu {
 
 class NonLocalManagerCallback {
 public:
   virtual void initializeNonLocal() {}
 
   /* ------------------------------------------------------------------------ */
   virtual void
   insertIntegrationPointsInNeighborhoods(const GhostType & ghost_type) = 0;
 
   virtual void computeNonLocalStresses(const GhostType & ghost_type) = 0;
 
   /// update the values of the non local internal
   virtual void updateLocalInternal(ElementTypeMapReal & internal_flat,
                                    const GhostType & ghost_type,
                                    const ElementKind & kind) = 0;
 
   /// copy the results of the averaging in the materials
   virtual void updateNonLocalInternal(ElementTypeMapReal & internal_flat,
                                       const GhostType & ghost_type,
                                       const ElementKind & kind) = 0;
 };
 
 } // namespace akantu
 
 #endif /* __AKANTU_NON_LOCAL_MANAGER_CALLBACK_HH__ */
diff --git a/src/model/common/non_local_toolbox/non_local_manager_inline_impl.cc b/src/model/common/non_local_toolbox/non_local_manager_inline_impl.cc
index 8b63d0073..3649b1019 100644
--- a/src/model/common/non_local_toolbox/non_local_manager_inline_impl.cc
+++ b/src/model/common/non_local_toolbox/non_local_manager_inline_impl.cc
@@ -1,69 +1,68 @@
 /**
  * @file   non_local_manager_inline_impl.cc
  *
  * @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Fri Jun 18 2010
- * @date last modification: Wed Nov 25 2015
+ * @date last modification: Mon Sep 11 2017
  *
  * @brief  inline implementation of non-local manager functions
  *
  * @section LICENSE
  *
- * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
- * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
- * Solides)
+ * 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
+ * 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
+ * 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 "neighborhood_base.hh"
 /* -------------------------------------------------------------------------- */
 
 #ifndef __AKANTU_NON_LOCAL_MANAGER_INLINE_IMPL_CC__
 #define __AKANTU_NON_LOCAL_MANAGER_INLINE_IMPL_CC__
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 inline void NonLocalManager::registerNeighborhood(const ID & neighborhood,
                                                   const ID & weight_func_id) {
 
   /// check if neighborhood has already been created
   auto it = neighborhoods.find(neighborhood);
   if (it == neighborhoods.end()) {
     this->createNeighborhood(weight_func_id, neighborhood);
   }
 }
 
 /* -------------------------------------------------------------------------- */
 inline NonLocalNeighborhoodBase &
 NonLocalManager::getNeighborhood(const ID & name) const {
   AKANTU_DEBUG_IN();
 
   auto it = neighborhoods.find(name);
 
   AKANTU_DEBUG_ASSERT(it != neighborhoods.end(),
                       "The neighborhood " << name << " is not registered");
 
   AKANTU_DEBUG_OUT();
   return *(it->second);
 }
 
 } // namespace akantu
 
 #endif /* __AKANTU_NON_LOCAL_MANAGER_INLINE_IMPL_CC__ */
diff --git a/src/model/common/non_local_toolbox/non_local_neighborhood.hh b/src/model/common/non_local_toolbox/non_local_neighborhood.hh
index a847e9947..1dfd507e0 100644
--- a/src/model/common/non_local_toolbox/non_local_neighborhood.hh
+++ b/src/model/common/non_local_toolbox/non_local_neighborhood.hh
@@ -1,136 +1,135 @@
 /**
  * @file   non_local_neighborhood.hh
  *
  * @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Fri Jun 18 2010
- * @date last modification: Wed Nov 25 2015
+ * @date last modification: Wed Nov 08 2017
  *
  * @brief  Non-local neighborhood for non-local averaging based on
  * weight function
  *
  * @section LICENSE
  *
- * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
- * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
- * Solides)
+ * 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
+ * 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
+ * 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_NON_LOCAL_NEIGHBORHOOD_HH__
 #define __AKANTU_NON_LOCAL_NEIGHBORHOOD_HH__
 /* -------------------------------------------------------------------------- */
 #include "base_weight_function.hh"
 #include "non_local_neighborhood_base.hh"
 #include "parsable.hh"
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 class NonLocalManager;
 class BaseWeightFunction;
 } // namespace akantu
 
 namespace akantu {
 
 template <class WeightFunction = BaseWeightFunction>
 class NonLocalNeighborhood : public NonLocalNeighborhoodBase {
   /* ------------------------------------------------------------------------ */
   /* Constructors/Destructors                                                 */
   /* ------------------------------------------------------------------------ */
 public:
   NonLocalNeighborhood(NonLocalManager & manager,
                        const ElementTypeMapReal & quad_coordinates,
                        const ID & id = "neighborhood",
                        const MemoryID & memory_id = 0);
   ~NonLocalNeighborhood() override;
 
   /* ------------------------------------------------------------------------ */
   /* Methods                                                                  */
   /* ------------------------------------------------------------------------ */
 public:
   /// compute the weights for non-local averaging
   void computeWeights() override;
 
   /// save the pair of weights in a file
   void saveWeights(const std::string & filename) const override;
 
   /// compute the non-local counter part for a given element type map
   // compute the non-local counter part for a given element type map
   void
   weightedAverageOnNeighbours(const ElementTypeMapReal & to_accumulate,
                               ElementTypeMapReal & accumulated,
                               UInt nb_degree_of_freedom,
                               const GhostType & ghost_type2) const override;
 
   /// update the weights based on the weight function
   void updateWeights() override;
 
   /// register a new non-local variable in the neighborhood
   // void registerNonLocalVariable(const ID & id);
 protected:
   template <class Func>
   inline void foreach_weight(const GhostType & ghost_type, Func && func);
 
   template <class Func>
   inline void foreach_weight(const GhostType & ghost_type, Func && func) const;
 
   inline UInt getNbData(const Array<Element> & elements,
                         const SynchronizationTag & tag) const override;
 
   inline void packData(CommunicationBuffer & buffer,
                        const Array<Element> & elements,
                        const SynchronizationTag & tag) const override;
 
   inline void unpackData(CommunicationBuffer & buffer,
                          const Array<Element> & elements,
                          const SynchronizationTag & tag) override;
 
   /* ------------------------------------------------------------------------ */
   /* Accessor                                                                 */
   /* ------------------------------------------------------------------------ */
 public:
   AKANTU_GET_MACRO(NonLocalManager, non_local_manager, const NonLocalManager &);
   AKANTU_GET_MACRO_NOT_CONST(NonLocalManager, non_local_manager,
                              NonLocalManager &);
 
   /* ------------------------------------------------------------------------ */
   /* Class Members                                                            */
   /* ------------------------------------------------------------------------ */
 private:
   /// Pointer to non-local manager class
   NonLocalManager & non_local_manager;
 
   /// the weights associated to the pairs
   std::array<std::unique_ptr<Array<Real>>, 2> pair_weight;
 
   /// weight function
   std::unique_ptr<WeightFunction> weight_function;
 };
 
 } // namespace akantu
 
 /* -------------------------------------------------------------------------- */
 /* Implementation of template functions                                       */
 /* -------------------------------------------------------------------------- */
 #include "non_local_neighborhood_tmpl.hh"
 /* -------------------------------------------------------------------------- */
 /* inline functions                                                           */
 /* -------------------------------------------------------------------------- */
 #include "non_local_neighborhood_inline_impl.cc"
 
 #endif /* __AKANTU_NON_LOCAL_NEIGHBORHOOD_HH__ */
diff --git a/src/model/common/non_local_toolbox/non_local_neighborhood_base.cc b/src/model/common/non_local_toolbox/non_local_neighborhood_base.cc
index 81cf8934a..3e98bcc82 100644
--- a/src/model/common/non_local_toolbox/non_local_neighborhood_base.cc
+++ b/src/model/common/non_local_toolbox/non_local_neighborhood_base.cc
@@ -1,117 +1,117 @@
 /**
  * @file   non_local_neighborhood_base.cc
  *
  * @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Sat Sep 26 2015
- * @date last modification: Wed Nov 25 2015
+ * @date last modification: Fri Dec 08 2017
  *
  * @brief  Implementation of non-local neighborhood base
  *
  * @section LICENSE
  *
- * Copyright (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne) Laboratory
- * (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * Copyright (©) 2015-2018 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
- * terms  of the  GNU Lesser  General Public  License as  published by  the Free
+ * 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
+ * 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 "non_local_neighborhood_base.hh"
 #include "grid_synchronizer.hh"
 #include "model.hh"
 /* -------------------------------------------------------------------------- */
 #include <memory>
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 NonLocalNeighborhoodBase::NonLocalNeighborhoodBase(
     Model & model, const ElementTypeMapReal & quad_coordinates, const ID & id,
     const MemoryID & memory_id)
     : NeighborhoodBase(model, quad_coordinates, id, memory_id),
       Parsable(ParserType::_non_local, id) {
 
   AKANTU_DEBUG_IN();
 
   this->registerParam("radius", neighborhood_radius, 100.,
                       _pat_parsable | _pat_readable, "Non local radius");
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 NonLocalNeighborhoodBase::~NonLocalNeighborhoodBase() = default;
 
 /* -------------------------------------------------------------------------- */
 void NonLocalNeighborhoodBase::createGridSynchronizer() {
   this->is_creating_grid = true;
 
   this->grid_synchronizer = std::make_unique<GridSynchronizer>(
       this->model.getMesh(), *spatial_grid, *this,
       std::set<SynchronizationTag>{_gst_mnl_weight, _gst_mnl_for_average},
       std::string(getID() + ":grid_synchronizer"), this->memory_id, false);
 
   this->is_creating_grid = false;
 }
 
 /* -------------------------------------------------------------------------- */
 void NonLocalNeighborhoodBase::synchronize(
     DataAccessor<Element> & data_accessor, const SynchronizationTag & tag) {
   if (not grid_synchronizer)
     return;
 
   grid_synchronizer->synchronizeOnce(data_accessor, tag);
 }
 
 /* -------------------------------------------------------------------------- */
 void NonLocalNeighborhoodBase::cleanupExtraGhostElements(
     std::set<Element> & relevant_ghost_elements) {
 
   for (auto && pair : pair_list[_ghost]) {
     const auto & q2 = pair.second;
     relevant_ghost_elements.insert(q2);
   }
 
   Array<Element> ghosts_to_erase(0);
   auto & mesh = this->model.getMesh();
 
   Element element;
   element.ghost_type = _ghost;
 
   auto end = relevant_ghost_elements.end();
   for (auto & type : mesh.elementTypes(spatial_dimension, _ghost)) {
     element.type = type;
     UInt nb_ghost_elem = mesh.getNbElement(type, _ghost);
     for (UInt g = 0; g < nb_ghost_elem; ++g) {
       element.element = g;
       if (relevant_ghost_elements.find(element) == end) {
         ghosts_to_erase.push_back(element);
       }
     }
   }
 
   /// remove the unneccessary ghosts from the synchronizer
   // this->grid_synchronizer->removeElements(ghosts_to_erase);
   mesh.eraseElements(ghosts_to_erase);
 }
 
 /* -------------------------------------------------------------------------- */
 void NonLocalNeighborhoodBase::registerNonLocalVariable(const ID & id) {
   this->non_local_variables.insert(id);
 }
 
 } // namespace akantu
diff --git a/src/model/common/non_local_toolbox/non_local_neighborhood_base.hh b/src/model/common/non_local_toolbox/non_local_neighborhood_base.hh
index 3d6cfbe06..238705e74 100644
--- a/src/model/common/non_local_toolbox/non_local_neighborhood_base.hh
+++ b/src/model/common/non_local_toolbox/non_local_neighborhood_base.hh
@@ -1,128 +1,129 @@
 /**
  * @file   non_local_neighborhood_base.hh
  *
  * @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Sat Sep 26 2015
- * @date last modification: Wed Nov 25 2015
+ * @date last modification: Tue Feb 20 2018
  *
  * @brief  Non-local neighborhood base class
  *
  * @section LICENSE
  *
- * Copyright (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne) Laboratory
- * (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * Copyright (©) 2015-2018 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
- * terms  of the  GNU Lesser  General Public  License as  published by  the Free
+ * 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
+ * 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 "neighborhood_base.hh"
 #include "parsable.hh"
 /* -------------------------------------------------------------------------- */
 
 #ifndef __AKANTU_NON_LOCAL_NEIGHBORHOOD_BASE_HH__
 #define __AKANTU_NON_LOCAL_NEIGHBORHOOD_BASE_HH__
 
 namespace akantu {
 class Model;
 }
 /* -------------------------------------------------------------------------- */
 namespace akantu {
 
 class NonLocalNeighborhoodBase : public NeighborhoodBase, public Parsable {
   /* ------------------------------------------------------------------------ */
   /* Constructors/Destructors                                                 */
   /* ------------------------------------------------------------------------ */
 public:
   NonLocalNeighborhoodBase(Model & model,
                            const ElementTypeMapReal & quad_coordinates,
                            const ID & id = "non_local_neighborhood",
                            const MemoryID & memory_id = 0);
   ~NonLocalNeighborhoodBase() override;
 
   /* ------------------------------------------------------------------------ */
   /* Methods                                                                  */
   /* ------------------------------------------------------------------------ */
 public:
   /// create grid synchronizer and exchange ghost cells
   void createGridSynchronizer() override;
 
   void synchronize(DataAccessor<Element> & data_accessor,
                    const SynchronizationTag & tag) override;
 
   /// compute weights, for instance needed for non-local damage computation
   virtual void computeWeights(){};
 
   // compute the non-local counter part for a given element type map
   virtual void
   weightedAverageOnNeighbours(const ElementTypeMapReal & to_accumulate,
                               ElementTypeMapReal & accumulated,
                               UInt nb_degree_of_freedom,
                               const GhostType & ghost_type2) const = 0;
 
   /// update the weights for the non-local averaging
   virtual void updateWeights() = 0;
 
   /// update the weights for the non-local averaging
   virtual void saveWeights(const std::string &) const { AKANTU_TO_IMPLEMENT(); }
 
   /// register a new non-local variable in the neighborhood
   virtual void registerNonLocalVariable(const ID & id);
 
   /// clean up the unneccessary ghosts
   void cleanupExtraGhostElements(std::set<Element> & relevant_ghost_elements);
 
 protected:
   /// create the grid
   void createGrid();
 
   /* --------------------------------------------------------------------------
    */
   /* DataAccessor inherited members */
   /* --------------------------------------------------------------------------
    */
 public:
   inline UInt getNbData(const Array<Element> &,
                         const SynchronizationTag &) const override {
     return 0;
   }
 
   inline void packData(CommunicationBuffer &, const Array<Element> &,
                        const SynchronizationTag &) const override {}
 
   inline void unpackData(CommunicationBuffer &, const Array<Element> &,
                          const SynchronizationTag &) override {}
 
   /* --------------------------------------------------------------------------
    */
   /* Accessors */
   /* --------------------------------------------------------------------------
    */
 public:
   AKANTU_GET_MACRO(NonLocalVariables, non_local_variables,
                    const std::set<ID> &);
 
   /* ------------------------------------------------------------------------ */
   /* Class Members                                                            */
   /* ------------------------------------------------------------------------ */
 protected:
   /// list of non-local variables associated to the neighborhood
   std::set<ID> non_local_variables;
 };
 
 } // namespace akantu
 
 #endif /* __AKANTU_NON_LOCAL_NEIGHBORHOOD_BASE_HH__ */
diff --git a/src/model/common/non_local_toolbox/non_local_neighborhood_inline_impl.cc b/src/model/common/non_local_toolbox/non_local_neighborhood_inline_impl.cc
index 389da6687..50e9cf512 100644
--- a/src/model/common/non_local_toolbox/non_local_neighborhood_inline_impl.cc
+++ b/src/model/common/non_local_toolbox/non_local_neighborhood_inline_impl.cc
@@ -1,86 +1,87 @@
 /**
  * @file   non_local_neighborhood_inline_impl.cc
  *
  * @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Tue Oct 06 2015
- * @date last modification: Wed Nov 25 2015
+ * @date last modification: Thu Jul 06 2017
  *
  * @brief  Implementation of inline functions of non-local neighborhood class
  *
  * @section LICENSE
  *
- * Copyright (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne) Laboratory
- * (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * Copyright (©) 2015-2018 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
- * terms  of the  GNU Lesser  General Public  License as  published by  the Free
+ * 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
+ * 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 "non_local_neighborhood.hh"
 /* -------------------------------------------------------------------------- */
 
 #ifndef __AKANTU_NON_LOCAL_NEIGHBORHOOD_INLINE_IMPL_CC__
 #define __AKANTU_NON_LOCAL_NEIGHBORHOOD_INLINE_IMPL_CC__
 
 namespace akantu {
 /* -------------------------------------------------------------------------- */
 template <class WeightFunction>
 inline UInt NonLocalNeighborhood<WeightFunction>::getNbData(
     const Array<Element> & elements, const SynchronizationTag & tag) const {
   UInt size = 0;
 
   if (tag == _gst_mnl_for_average) {
     for (auto & variable_id : non_local_variables) {
       size += this->non_local_manager.getNbData(elements, variable_id);
     }
   }
 
   size += this->weight_function->getNbData(elements, tag);
 
   return size;
 }
 
 /* -------------------------------------------------------------------------- */
 template <class WeightFunction>
 inline void NonLocalNeighborhood<WeightFunction>::packData(
     CommunicationBuffer & buffer, const Array<Element> & elements,
     const SynchronizationTag & tag) const {
   if (tag == _gst_mnl_for_average) {
     for (auto & variable_id : non_local_variables) {
       this->non_local_manager.packData(buffer, elements, variable_id);
     }
   }
 
   this->weight_function->packData(buffer, elements, tag);
 }
 
 /* -------------------------------------------------------------------------- */
 template <class WeightFunction>
 inline void NonLocalNeighborhood<WeightFunction>::unpackData(
     CommunicationBuffer & buffer, const Array<Element> & elements,
     const SynchronizationTag & tag) {
   if (tag == _gst_mnl_for_average) {
     for (auto & variable_id : non_local_variables) {
       this->non_local_manager.unpackData(buffer, elements, variable_id);
     }
   }
 
   this->weight_function->unpackData(buffer, elements, tag);
 }
 
 } // namespace akantu
 
 #endif /* __AKANTU_NON_LOCAL_NEIGHBORHOOD_INLINE_IMPL_CC__ */
diff --git a/src/model/common/non_local_toolbox/non_local_neighborhood_tmpl.hh b/src/model/common/non_local_toolbox/non_local_neighborhood_tmpl.hh
index e6283a065..51ea76127 100644
--- a/src/model/common/non_local_toolbox/non_local_neighborhood_tmpl.hh
+++ b/src/model/common/non_local_toolbox/non_local_neighborhood_tmpl.hh
@@ -1,276 +1,276 @@
 /**
  * @file   non_local_neighborhood_tmpl.hh
  *
  * @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Mon Sep 28 2015
- * @date last modification: Wed Nov 25 2015
+ * @date last modification: Tue Feb 20 2018
  *
  * @brief  Implementation of class non-local neighborhood
  *
  * @section LICENSE
  *
- * Copyright (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne) Laboratory
- * (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * Copyright (©) 2015-2018 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
- * terms  of the  GNU Lesser  General Public  License as  published by  the Free
+ * 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
+ * A PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 #include "communicator.hh"
 #include "non_local_manager.hh"
 #include "non_local_neighborhood.hh"
 /* -------------------------------------------------------------------------- */
 #include <fstream>
 /* -------------------------------------------------------------------------- */
 
 #ifndef __AKANTU_NON_LOCAL_NEIGHBORHOOD_TMPL_HH__
 #define __AKANTU_NON_LOCAL_NEIGHBORHOOD_TMPL_HH__
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 template <class WeightFunction>
 template <class Func>
 inline void NonLocalNeighborhood<WeightFunction>::foreach_weight(
     const GhostType & ghost_type, Func && func) {
   auto weight_it =
       pair_weight[ghost_type]->begin(pair_weight[ghost_type]->getNbComponent());
 
   for (auto & pair : pair_list[ghost_type]) {
     std::forward<decltype(func)>(func)(pair.first, pair.second, *weight_it);
     ++weight_it;
   }
 }
 
 /* -------------------------------------------------------------------------- */
 template <class WeightFunction>
 template <class Func>
 inline void NonLocalNeighborhood<WeightFunction>::foreach_weight(
     const GhostType & ghost_type, Func && func) const {
   auto weight_it =
       pair_weight[ghost_type]->begin(pair_weight[ghost_type]->getNbComponent());
 
   for (auto & pair : pair_list[ghost_type]) {
     std::forward<decltype(func)>(func)(pair.first, pair.second, *weight_it);
     ++weight_it;
   }
 }
 
 /* -------------------------------------------------------------------------- */
 template <class WeightFunction>
 NonLocalNeighborhood<WeightFunction>::NonLocalNeighborhood(
     NonLocalManager & manager, const ElementTypeMapReal & quad_coordinates,
     const ID & id, const MemoryID & memory_id)
     : NonLocalNeighborhoodBase(manager.getModel(), quad_coordinates, id,
                                memory_id),
       non_local_manager(manager) {
   AKANTU_DEBUG_IN();
 
   this->weight_function = std::make_unique<WeightFunction>(manager);
 
   this->registerSubSection(ParserType::_weight_function, "weight_parameter",
                            *weight_function);
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <class WeightFunction>
 NonLocalNeighborhood<WeightFunction>::~NonLocalNeighborhood() = default;
 
 /* -------------------------------------------------------------------------- */
 template <class WeightFunction>
 void NonLocalNeighborhood<WeightFunction>::computeWeights() {
   AKANTU_DEBUG_IN();
 
   this->weight_function->setRadius(this->neighborhood_radius);
   Vector<Real> q1_coord(this->spatial_dimension);
   Vector<Real> q2_coord(this->spatial_dimension);
 
   UInt nb_weights_per_pair = 2; /// w1: q1->q2, w2: q2->q1
 
   /// get the elementtypemap for the neighborhood volume for each quadrature
   /// point
   ElementTypeMapReal & quadrature_points_volumes =
       this->non_local_manager.getVolumes();
 
   /// update the internals of the weight function if applicable (not
   /// all the weight functions have internals and do noting in that
   /// case)
   weight_function->updateInternals();
 
   for (auto ghost_type : ghost_types) {
     /// allocate the array to store the weight, if it doesn't exist already
     if (!(pair_weight[ghost_type])) {
       pair_weight[ghost_type] =
           std::make_unique<Array<Real>>(0, nb_weights_per_pair);
     }
 
     /// resize the array to the correct size
     pair_weight[ghost_type]->resize(pair_list[ghost_type].size());
     /// set entries to zero
     pair_weight[ghost_type]->clear();
 
     /// loop over all pairs in the current pair list array and their
     /// corresponding weights
     auto first_pair = pair_list[ghost_type].begin();
     auto last_pair = pair_list[ghost_type].end();
     auto weight_it = pair_weight[ghost_type]->begin(nb_weights_per_pair);
 
     // Compute the weights
     for (; first_pair != last_pair; ++first_pair, ++weight_it) {
       Vector<Real> & weight = *weight_it;
       const IntegrationPoint & q1 = first_pair->first;
       const IntegrationPoint & q2 = first_pair->second;
 
       /// get the coordinates for the given pair of quads
       auto coords_type_1_it = this->quad_coordinates(q1.type, q1.ghost_type)
                                   .begin(this->spatial_dimension);
       q1_coord = coords_type_1_it[q1.global_num];
       auto coords_type_2_it = this->quad_coordinates(q2.type, q2.ghost_type)
                                   .begin(this->spatial_dimension);
       q2_coord = coords_type_2_it[q2.global_num];
 
       Array<Real> & quad_volumes_1 =
           quadrature_points_volumes(q1.type, q1.ghost_type);
       const Array<Real> & jacobians_2 =
           this->non_local_manager.getJacobians(q2.type, q2.ghost_type);
       const Real & q2_wJ = jacobians_2(q2.global_num);
 
       /// compute distance between the two quadrature points
       Real r = q1_coord.distance(q2_coord);
 
       /// compute the weight for averaging on q1 based on the distance
       Real w1 = this->weight_function->operator()(r, q1, q2);
       weight(0) = q2_wJ * w1;
 
       quad_volumes_1(q1.global_num) += weight(0);
 
       if (q2.ghost_type != _ghost && q1.global_num != q2.global_num) {
         const Array<Real> & jacobians_1 =
             this->non_local_manager.getJacobians(q1.type, q1.ghost_type);
         Array<Real> & quad_volumes_2 =
             quadrature_points_volumes(q2.type, q2.ghost_type);
         /// compute the weight for averaging on q2
         const Real & q1_wJ = jacobians_1(q1.global_num);
         Real w2 = this->weight_function->operator()(r, q2, q1);
         weight(1) = q1_wJ * w2;
         quad_volumes_2(q2.global_num) += weight(1);
       } else
         weight(1) = 0.;
     }
   }
 
   ///  normalize the weights
   for (auto ghost_type : ghost_types) {
     foreach_weight(ghost_type, [&](const auto & q1, const auto & q2,
                                    auto & weight) {
       auto & quad_volumes_1 = quadrature_points_volumes(q1.type, q1.ghost_type);
       auto & quad_volumes_2 = quadrature_points_volumes(q2.type, q2.ghost_type);
 
       Real q1_volume = quad_volumes_1(q1.global_num);
       auto ghost_type2 = q2.ghost_type;
       weight(0) *= 1. / q1_volume;
       if (ghost_type2 != _ghost) {
         Real q2_volume = quad_volumes_2(q2.global_num);
         weight(1) *= 1. / q2_volume;
       }
     });
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <class WeightFunction>
 void NonLocalNeighborhood<WeightFunction>::saveWeights(
     const std::string & filename) const {
   std::ofstream pout;
 
   std::stringstream sstr;
 
   const Communicator & comm = model.getMesh().getCommunicator();
 
   Int prank = comm.whoAmI();
   sstr << filename << "." << prank;
 
   pout.open(sstr.str().c_str());
 
   for (UInt gt = _not_ghost; gt <= _ghost; ++gt) {
     auto ghost_type = (GhostType)gt;
 
     AKANTU_DEBUG_ASSERT((pair_weight[ghost_type]),
                         "the weights have not been computed yet");
 
     Array<Real> & weights = *(pair_weight[ghost_type]);
     auto weights_it = weights.begin(2);
     for (UInt i = 0; i < weights.size(); ++i, ++weights_it)
       pout << "w1: " << (*weights_it)(0) << " w2: " << (*weights_it)(1)
            << std::endl;
   }
 }
 
 /* -------------------------------------------------------------------------- */
 template <class WeightFunction>
 void NonLocalNeighborhood<WeightFunction>::weightedAverageOnNeighbours(
     const ElementTypeMapReal & to_accumulate, ElementTypeMapReal & accumulated,
     UInt nb_degree_of_freedom, const GhostType & ghost_type2) const {
 
   auto it = non_local_variables.find(accumulated.getName());
   // do averaging only for variables registered in the neighborhood
   if (it == non_local_variables.end())
     return;
 
   foreach_weight(
       ghost_type2,
       [ghost_type2, nb_degree_of_freedom, &to_accumulate,
        &accumulated](const auto & q1, const auto & q2, auto & weight) {
         const Vector<Real> to_acc_1 =
             to_accumulate(q1.type, q1.ghost_type)
                 .begin(nb_degree_of_freedom)[q1.global_num];
         const Vector<Real> to_acc_2 =
             to_accumulate(q2.type, q2.ghost_type)
                 .begin(nb_degree_of_freedom)[q2.global_num];
         Vector<Real> acc_1 = accumulated(q1.type, q1.ghost_type)
                                  .begin(nb_degree_of_freedom)[q1.global_num];
         Vector<Real> acc_2 = accumulated(q2.type, q2.ghost_type)
                                  .begin(nb_degree_of_freedom)[q2.global_num];
 
         acc_1 += weight(0) * to_acc_2;
 
         if (ghost_type2 != _ghost) {
           acc_2 += weight(1) * to_acc_1;
         }
       });
 }
 
 /* -------------------------------------------------------------------------- */
 template <class WeightFunction>
 void NonLocalNeighborhood<WeightFunction>::updateWeights() {
   // Update the weights for the non local variable averaging
   if (this->weight_function->getUpdateRate() &&
       (this->non_local_manager.getNbStressCalls() %
            this->weight_function->getUpdateRate() ==
        0)) {
     SynchronizerRegistry::synchronize(_gst_mnl_weight);
     this->computeWeights();
   }
 }
 
 } // namespace akantu
 
 #endif /* __AKANTU_NON_LOCAL_NEIGHBORHOOD_TMPL__ */
diff --git a/src/model/dof_manager.cc b/src/model/dof_manager.cc
index 7aaa2fccc..9f282345d 100644
--- a/src/model/dof_manager.cc
+++ b/src/model/dof_manager.cc
@@ -1,604 +1,605 @@
 /**
  * @file   dof_manager.cc
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
- * @date   Wed Aug 12 09:52:30 2015
+ * @date creation: Tue Aug 18 2015
+ * @date last modification: Wed Feb 21 2018
  *
  * @brief  Implementation of the common parts of the DOFManagers
  *
  * @section LICENSE
  *
- * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * Copyright (©) 2015-2018 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
- * terms  of the  GNU Lesser  General Public  License as  published by  the Free
+ * 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
+ * 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 "dof_manager.hh"
 #include "communicator.hh"
 #include "element_group.hh"
 #include "mesh.hh"
 #include "mesh_utils.hh"
 #include "node_group.hh"
 #include "non_linear_solver.hh"
 #include "sparse_matrix.hh"
 #include "time_step_solver.hh"
 /* -------------------------------------------------------------------------- */
 #include <memory>
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 DOFManager::DOFManager(const ID & id, const MemoryID & memory_id)
     : Memory(id, memory_id),
       communicator(Communicator::getStaticCommunicator()) {}
 
 /* -------------------------------------------------------------------------- */
 DOFManager::DOFManager(Mesh & mesh, const ID & id, const MemoryID & memory_id)
     : Memory(id, memory_id), mesh(&mesh), local_system_size(0),
       pure_local_system_size(0), system_size(0),
       communicator(mesh.getCommunicator()) {
   this->mesh->registerEventHandler(*this, _ehp_dof_manager);
 }
 
 /* -------------------------------------------------------------------------- */
 DOFManager::~DOFManager() = default;
 
 /* -------------------------------------------------------------------------- */
 // void DOFManager::getEquationsNumbers(const ID &, Array<UInt> &) {
 //   AKANTU_TO_IMPLEMENT();
 // }
 
 /* -------------------------------------------------------------------------- */
 std::vector<ID> DOFManager::getDOFIDs() const {
   std::vector<ID> keys;
   for (const auto & dof_data : this->dofs)
     keys.push_back(dof_data.first);
 
   return keys;
 }
 
 /* -------------------------------------------------------------------------- */
 void DOFManager::assembleElementalArrayLocalArray(
     const Array<Real> & elementary_vect, Array<Real> & array_assembeled,
     const ElementType & type, const GhostType & ghost_type, Real scale_factor,
     const Array<UInt> & filter_elements) {
   AKANTU_DEBUG_IN();
 
   UInt nb_element;
   UInt nb_nodes_per_element = Mesh::getNbNodesPerElement(type);
   UInt nb_degree_of_freedom =
       elementary_vect.getNbComponent() / nb_nodes_per_element;
 
   UInt * filter_it = nullptr;
   if (filter_elements != empty_filter) {
     nb_element = filter_elements.size();
     filter_it = filter_elements.storage();
   } else {
     nb_element = this->mesh->getNbElement(type, ghost_type);
   }
 
   AKANTU_DEBUG_ASSERT(elementary_vect.size() == nb_element,
                       "The vector elementary_vect("
                           << elementary_vect.getID()
                           << ") has not the good size.");
 
   const Array<UInt> & connectivity =
       this->mesh->getConnectivity(type, ghost_type);
   // Array<UInt>::const_vector_iterator conn_begin =
   //     connectivity.begin(nb_nodes_per_element);
   // Array<UInt>::const_vector_iterator conn_it = conn_begin;
 
   Array<Real>::const_matrix_iterator elem_it =
       elementary_vect.begin(nb_degree_of_freedom, nb_nodes_per_element);
 
   for (UInt el = 0; el < nb_element; ++el, ++elem_it) {
     UInt element = el;
     if (filter_it != nullptr) {
       // conn_it = conn_begin + *filter_it;
       element = *filter_it;
     }
 
     // const Vector<UInt> & conn = *conn_it;
     const Matrix<Real> & elemental_val = *elem_it;
     for (UInt n = 0; n < nb_nodes_per_element; ++n) {
       UInt offset_node = connectivity(element, n) * nb_degree_of_freedom;
       Vector<Real> assemble(array_assembeled.storage() + offset_node,
                             nb_degree_of_freedom);
       Vector<Real> elem_val = elemental_val(n);
       assemble.aXplusY(elem_val, scale_factor);
     }
 
     if (filter_it != nullptr)
       ++filter_it;
     //    else
     //      ++conn_it;
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void DOFManager::assembleElementalArrayToResidual(
     const ID & dof_id, const Array<Real> & elementary_vect,
     const ElementType & type, const GhostType & ghost_type, Real scale_factor,
     const Array<UInt> & filter_elements) {
   AKANTU_DEBUG_IN();
 
   UInt nb_nodes_per_element = Mesh::getNbNodesPerElement(type);
   UInt nb_degree_of_freedom =
       elementary_vect.getNbComponent() / nb_nodes_per_element;
   Array<Real> array_localy_assembeled(this->mesh->getNbNodes(),
                                       nb_degree_of_freedom);
 
   array_localy_assembeled.clear();
 
   this->assembleElementalArrayLocalArray(
       elementary_vect, array_localy_assembeled, type, ghost_type, scale_factor,
       filter_elements);
 
   this->assembleToResidual(dof_id, array_localy_assembeled, 1);
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void DOFManager::assembleElementalArrayToLumpedMatrix(
     const ID & dof_id, const Array<Real> & elementary_vect,
     const ID & lumped_mtx, const ElementType & type,
     const GhostType & ghost_type, Real scale_factor,
     const Array<UInt> & filter_elements) {
   AKANTU_DEBUG_IN();
 
   UInt nb_nodes_per_element = Mesh::getNbNodesPerElement(type);
   UInt nb_degree_of_freedom =
       elementary_vect.getNbComponent() / nb_nodes_per_element;
   Array<Real> array_localy_assembeled(this->mesh->getNbNodes(),
                                       nb_degree_of_freedom);
 
   array_localy_assembeled.clear();
 
   this->assembleElementalArrayLocalArray(
       elementary_vect, array_localy_assembeled, type, ghost_type, scale_factor,
       filter_elements);
 
   this->assembleToLumpedMatrix(dof_id, array_localy_assembeled, lumped_mtx, 1);
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void DOFManager::assembleMatMulDOFsToResidual(const ID & A_id,
                                               Real scale_factor) {
   for (auto & pair : this->dofs) {
     const auto & dof_id = pair.first;
     auto & dof_data = *pair.second;
 
     this->assembleMatMulVectToResidual(dof_id, A_id, *dof_data.dof,
                                        scale_factor);
   }
 }
 
 /* -------------------------------------------------------------------------- */
 DOFManager::DOFData::DOFData(const ID & dof_id)
     : support_type(_dst_generic), group_support("__mesh__"), dof(nullptr),
       blocked_dofs(nullptr), increment(nullptr), previous(nullptr),
       solution(0, 1, dof_id + ":solution"),
       local_equation_number(0, 1, dof_id + ":local_equation_number") {}
 
 /* -------------------------------------------------------------------------- */
 DOFManager::DOFData::~DOFData() = default;
 
 /* -------------------------------------------------------------------------- */
 DOFManager::DOFData & DOFManager::getNewDOFData(const ID & dof_id) {
   auto it = this->dofs.find(dof_id);
   if (it != this->dofs.end()) {
     AKANTU_EXCEPTION("This dof array has already been registered");
   }
 
   std::unique_ptr<DOFData> dofs_storage = std::make_unique<DOFData>(dof_id);
   this->dofs[dof_id] = std::move(dofs_storage);
   return *dofs_storage;
 }
 
 /* -------------------------------------------------------------------------- */
 void DOFManager::registerDOFsInternal(const ID & dof_id,
                                       Array<Real> & dofs_array) {
   DOFData & dofs_storage = this->getDOFData(dof_id);
   dofs_storage.dof = &dofs_array;
 
   UInt nb_local_dofs = 0;
   UInt nb_pure_local = 0;
 
   const DOFSupportType & support_type = dofs_storage.support_type;
 
   switch (support_type) {
   case _dst_nodal: {
     UInt nb_nodes = 0;
     const ID & group = dofs_storage.group_support;
 
     NodeGroup * node_group = nullptr;
     if (group == "__mesh__") {
       nb_nodes = this->mesh->getNbNodes();
     } else {
       node_group = &this->mesh->getElementGroup(group).getNodeGroup();
       nb_nodes = node_group->size();
     }
 
     nb_local_dofs = nb_nodes;
     AKANTU_DEBUG_ASSERT(
         dofs_array.size() == nb_local_dofs,
         "The array of dof is too shot to be associated to nodes.");
 
     for (UInt n = 0; n < nb_nodes; ++n) {
       UInt node = n;
       if (node_group)
         node = node_group->getNodes()(n);
 
       nb_pure_local += this->mesh->isLocalOrMasterNode(node) ? 1 : 0;
     }
 
     nb_pure_local *= dofs_array.getNbComponent();
     nb_local_dofs *= dofs_array.getNbComponent();
     break;
   }
   case _dst_generic: {
     nb_local_dofs = nb_pure_local =
         dofs_array.size() * dofs_array.getNbComponent();
     break;
   }
   default: { AKANTU_EXCEPTION("This type of dofs is not handled yet."); }
   }
 
   this->pure_local_system_size += nb_pure_local;
   this->local_system_size += nb_local_dofs;
 
   communicator.allReduce(nb_pure_local, SynchronizerOperation::_sum);
 
   this->system_size += nb_pure_local;
 }
 
 /* -------------------------------------------------------------------------- */
 void DOFManager::registerDOFs(const ID & dof_id, Array<Real> & dofs_array,
                               const DOFSupportType & support_type) {
   DOFData & dofs_storage = this->getNewDOFData(dof_id);
   dofs_storage.support_type = support_type;
 
   this->registerDOFsInternal(dof_id, dofs_array);
 }
 
 /* -------------------------------------------------------------------------- */
 void DOFManager::registerDOFs(const ID & dof_id, Array<Real> & dofs_array,
                               const ID & support_group) {
   DOFData & dofs_storage = this->getNewDOFData(dof_id);
   dofs_storage.support_type = _dst_nodal;
   dofs_storage.group_support = support_group;
 
   this->registerDOFsInternal(dof_id, dofs_array);
 }
 
 /* -------------------------------------------------------------------------- */
 void DOFManager::registerDOFsPrevious(const ID & dof_id, Array<Real> & array) {
   DOFData & dof = this->getDOFData(dof_id);
 
   if (dof.previous != nullptr) {
     AKANTU_EXCEPTION("The previous dofs array for "
                      << dof_id << " has already been registered");
   }
 
   dof.previous = &array;
 }
 
 /* -------------------------------------------------------------------------- */
 void DOFManager::registerDOFsIncrement(const ID & dof_id, Array<Real> & array) {
   DOFData & dof = this->getDOFData(dof_id);
 
   if (dof.increment != nullptr) {
     AKANTU_EXCEPTION("The dofs increment array for "
                      << dof_id << " has already been registered");
   }
 
   dof.increment = &array;
 }
 
 /* -------------------------------------------------------------------------- */
 void DOFManager::registerDOFsDerivative(const ID & dof_id, UInt order,
                                         Array<Real> & dofs_derivative) {
   DOFData & dof = this->getDOFData(dof_id);
   std::vector<Array<Real> *> & derivatives = dof.dof_derivatives;
 
   if (derivatives.size() < order) {
     derivatives.resize(order, nullptr);
   } else {
     if (derivatives[order - 1] != nullptr) {
       AKANTU_EXCEPTION("The dof derivatives of order "
                        << order << " already been registered for this dof ("
                        << dof_id << ")");
     }
   }
 
   derivatives[order - 1] = &dofs_derivative;
 }
 
 /* -------------------------------------------------------------------------- */
 void DOFManager::registerBlockedDOFs(const ID & dof_id,
                                      Array<bool> & blocked_dofs) {
   DOFData & dof = this->getDOFData(dof_id);
 
   if (dof.blocked_dofs != nullptr) {
     AKANTU_EXCEPTION("The blocked dofs array for "
                      << dof_id << " has already been registered");
   }
 
   dof.blocked_dofs = &blocked_dofs;
 }
 
 /* -------------------------------------------------------------------------- */
 void DOFManager::splitSolutionPerDOFs() {
   auto it = this->dofs.begin();
   auto end = this->dofs.end();
 
   for (; it != end; ++it) {
     DOFData & dof_data = *it->second;
     dof_data.solution.resize(dof_data.dof->size() *
                              dof_data.dof->getNbComponent());
     this->getSolutionPerDOFs(it->first, dof_data.solution);
   }
 }
 
 /* -------------------------------------------------------------------------- */
 SparseMatrix &
 DOFManager::registerSparseMatrix(const ID & matrix_id,
                                  std::unique_ptr<SparseMatrix> & matrix) {
   SparseMatricesMap::const_iterator it = this->matrices.find(matrix_id);
   if (it != this->matrices.end()) {
     AKANTU_EXCEPTION("The matrix " << matrix_id << " already exists in "
                                    << this->id);
   }
 
   SparseMatrix & ret = *matrix;
   this->matrices[matrix_id] = std::move(matrix);
   return ret;
 }
 
 /* -------------------------------------------------------------------------- */
 /// Get an instance of a new SparseMatrix
 Array<Real> & DOFManager::getNewLumpedMatrix(const ID & id) {
   ID matrix_id = this->id + ":lumped_mtx:" + id;
   LumpedMatricesMap::const_iterator it = this->lumped_matrices.find(matrix_id);
   if (it != this->lumped_matrices.end()) {
     AKANTU_EXCEPTION("The lumped matrix " << matrix_id << " already exists in "
                                           << this->id);
   }
 
   auto mtx =
       std::make_unique<Array<Real>>(this->local_system_size, 1, matrix_id);
   this->lumped_matrices[matrix_id] = std::move(mtx);
   return *this->lumped_matrices[matrix_id];
 }
 
 /* -------------------------------------------------------------------------- */
 NonLinearSolver & DOFManager::registerNonLinearSolver(
     const ID & non_linear_solver_id,
     std::unique_ptr<NonLinearSolver> & non_linear_solver) {
   NonLinearSolversMap::const_iterator it =
       this->non_linear_solvers.find(non_linear_solver_id);
   if (it != this->non_linear_solvers.end()) {
     AKANTU_EXCEPTION("The non linear solver " << non_linear_solver_id
                                               << " already exists in "
                                               << this->id);
   }
 
   NonLinearSolver & ret = *non_linear_solver;
   this->non_linear_solvers[non_linear_solver_id] = std::move(non_linear_solver);
 
   return ret;
 }
 
 /* -------------------------------------------------------------------------- */
 TimeStepSolver & DOFManager::registerTimeStepSolver(
     const ID & time_step_solver_id,
     std::unique_ptr<TimeStepSolver> & time_step_solver) {
   TimeStepSolversMap::const_iterator it =
       this->time_step_solvers.find(time_step_solver_id);
   if (it != this->time_step_solvers.end()) {
     AKANTU_EXCEPTION("The non linear solver " << time_step_solver_id
                                               << " already exists in "
                                               << this->id);
   }
 
   TimeStepSolver & ret = *time_step_solver;
   this->time_step_solvers[time_step_solver_id] = std::move(time_step_solver);
   return ret;
 }
 
 /* -------------------------------------------------------------------------- */
 SparseMatrix & DOFManager::getMatrix(const ID & id) {
   ID matrix_id = this->id + ":mtx:" + id;
   SparseMatricesMap::const_iterator it = this->matrices.find(matrix_id);
   if (it == this->matrices.end()) {
     AKANTU_SILENT_EXCEPTION("The matrix " << matrix_id << " does not exists in "
                                           << this->id);
   }
 
   return *(it->second);
 }
 
 /* -------------------------------------------------------------------------- */
 bool DOFManager::hasMatrix(const ID & id) const {
   ID mtx_id = this->id + ":mtx:" + id;
   auto it = this->matrices.find(mtx_id);
   return it != this->matrices.end();
 }
 
 /* -------------------------------------------------------------------------- */
 Array<Real> & DOFManager::getLumpedMatrix(const ID & id) {
   ID matrix_id = this->id + ":lumped_mtx:" + id;
   LumpedMatricesMap::const_iterator it = this->lumped_matrices.find(matrix_id);
   if (it == this->lumped_matrices.end()) {
     AKANTU_SILENT_EXCEPTION("The lumped matrix "
                             << matrix_id << " does not exists in " << this->id);
   }
 
   return *(it->second);
 }
 
 /* -------------------------------------------------------------------------- */
 const Array<Real> & DOFManager::getLumpedMatrix(const ID & id) const {
   ID matrix_id = this->id + ":lumped_mtx:" + id;
   auto it = this->lumped_matrices.find(matrix_id);
   if (it == this->lumped_matrices.end()) {
     AKANTU_SILENT_EXCEPTION("The lumped matrix "
                             << matrix_id << " does not exists in " << this->id);
   }
 
   return *(it->second);
 }
 
 /* -------------------------------------------------------------------------- */
 bool DOFManager::hasLumpedMatrix(const ID & id) const {
   ID mtx_id = this->id + ":lumped_mtx:" + id;
   auto it = this->lumped_matrices.find(mtx_id);
   return it != this->lumped_matrices.end();
 }
 
 /* -------------------------------------------------------------------------- */
 NonLinearSolver & DOFManager::getNonLinearSolver(const ID & id) {
   ID non_linear_solver_id = this->id + ":nls:" + id;
   NonLinearSolversMap::const_iterator it =
       this->non_linear_solvers.find(non_linear_solver_id);
   if (it == this->non_linear_solvers.end()) {
     AKANTU_EXCEPTION("The non linear solver " << non_linear_solver_id
                                               << " does not exists in "
                                               << this->id);
   }
 
   return *(it->second);
 }
 
 /* -------------------------------------------------------------------------- */
 bool DOFManager::hasNonLinearSolver(const ID & id) const {
   ID solver_id = this->id + ":nls:" + id;
   auto it = this->non_linear_solvers.find(solver_id);
   return it != this->non_linear_solvers.end();
 }
 
 /* -------------------------------------------------------------------------- */
 TimeStepSolver & DOFManager::getTimeStepSolver(const ID & id) {
   ID time_step_solver_id = this->id + ":tss:" + id;
   TimeStepSolversMap::const_iterator it =
       this->time_step_solvers.find(time_step_solver_id);
   if (it == this->time_step_solvers.end()) {
     AKANTU_EXCEPTION("The non linear solver " << time_step_solver_id
                                               << " does not exists in "
                                               << this->id);
   }
 
   return *(it->second);
 }
 
 /* -------------------------------------------------------------------------- */
 bool DOFManager::hasTimeStepSolver(const ID & solver_id) const {
   ID time_step_solver_id = this->id + ":tss:" + solver_id;
   auto it = this->time_step_solvers.find(time_step_solver_id);
   return it != this->time_step_solvers.end();
 }
 
 /* -------------------------------------------------------------------------- */
 void DOFManager::savePreviousDOFs(const ID & dofs_id) {
   this->getPreviousDOFs(dofs_id).copy(this->getDOFs(dofs_id));
 }
 
 /* -------------------------------------------------------------------------- */
 /* Mesh Events                                                                */
 /* -------------------------------------------------------------------------- */
 std::pair<UInt, UInt>
 DOFManager::updateNodalDOFs(const ID & dof_id, const Array<UInt> & nodes_list) {
   auto & dof_data = this->getDOFData(dof_id);
   UInt nb_new_local_dofs = 0;
   UInt nb_new_pure_local = 0;
 
   nb_new_local_dofs = nodes_list.size();
   for (const auto & node : nodes_list) {
     nb_new_pure_local += this->mesh->isLocalOrMasterNode(node) ? 1 : 0;
   }
 
   const auto & dof_array = *dof_data.dof;
   nb_new_pure_local *= dof_array.getNbComponent();
   nb_new_local_dofs *= dof_array.getNbComponent();
 
   this->pure_local_system_size += nb_new_pure_local;
   this->local_system_size += nb_new_local_dofs;
 
   UInt nb_new_global = nb_new_pure_local;
   communicator.allReduce(nb_new_global, SynchronizerOperation::_sum);
 
   this->system_size += nb_new_global;
 
   return std::make_pair(nb_new_local_dofs, nb_new_pure_local);
 }
 
 /* -------------------------------------------------------------------------- */
 void DOFManager::onNodesAdded(const Array<UInt> & nodes_list,
                               const NewNodesEvent &) {
   for (auto & pair : this->dofs) {
     const auto & dof_id = pair.first;
     auto & dof_data = this->getDOFData(dof_id);
     if (dof_data.support_type != _dst_nodal)
       continue;
 
     const auto & group = dof_data.group_support;
 
     if (group == "__mesh__") {
       this->updateNodalDOFs(dof_id, nodes_list);
     } else {
       const auto & node_group =
           this->mesh->getElementGroup(group).getNodeGroup();
       Array<UInt> new_nodes_list;
       for (const auto & node : nodes_list) {
         if (node_group.find(node) != UInt(-1))
           new_nodes_list.push_back(node);
       }
 
       this->updateNodalDOFs(dof_id, new_nodes_list);
     }
   }
 }
 
 /* -------------------------------------------------------------------------- */
 void DOFManager::onNodesRemoved(const Array<UInt> &, const Array<UInt> &,
                                 const RemovedNodesEvent &) {}
 
 /* -------------------------------------------------------------------------- */
 void DOFManager::onElementsAdded(const Array<Element> &,
                                  const NewElementsEvent &) {}
 
 /* -------------------------------------------------------------------------- */
 void DOFManager::onElementsRemoved(const Array<Element> &,
                                    const ElementTypeMapArray<UInt> &,
                                    const RemovedElementsEvent &) {}
 
 /* -------------------------------------------------------------------------- */
 void DOFManager::onElementsChanged(const Array<Element> &,
                                    const Array<Element> &,
                                    const ElementTypeMapArray<UInt> &,
                                    const ChangedElementsEvent &) {}
 
 /* -------------------------------------------------------------------------- */
 
 } // namespace akantu
diff --git a/src/model/dof_manager.hh b/src/model/dof_manager.hh
index 981501a3c..4539874d8 100644
--- a/src/model/dof_manager.hh
+++ b/src/model/dof_manager.hh
@@ -1,475 +1,476 @@
 /**
  * @file   dof_manager.hh
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
- * @date   Wed Jul 22 11:43:43 2015
+ * @date creation: Tue Aug 18 2015
+ * @date last modification: Wed Feb 21 2018
  *
  * @brief  Class handling the different types of dofs
  *
  * @section LICENSE
  *
- * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * Copyright (©) 2015-2018 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
- * terms  of the  GNU Lesser  General Public  License as  published by  the Free
+ * 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
+ * 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_factory.hh"
 #include "aka_memory.hh"
 #include "mesh.hh"
 /* -------------------------------------------------------------------------- */
 #include <map>
 #include <set>
 /* -------------------------------------------------------------------------- */
 
 #ifndef __AKANTU_DOF_MANAGER_HH__
 #define __AKANTU_DOF_MANAGER_HH__
 
 namespace akantu {
 class TermsToAssemble;
 class NonLinearSolver;
 class TimeStepSolver;
 class SparseMatrix;
 } // namespace akantu
 
 namespace akantu {
 
 class DOFManager : protected Memory, protected MeshEventHandler {
   /* ------------------------------------------------------------------------ */
   /* Constructors/Destructors                                                 */
   /* ------------------------------------------------------------------------ */
 public:
   DOFManager(const ID & id = "dof_manager", const MemoryID & memory_id = 0);
   DOFManager(Mesh & mesh, const ID & id = "dof_manager",
              const MemoryID & memory_id = 0);
   ~DOFManager() override;
 
   /* ------------------------------------------------------------------------ */
   /* Methods                                                                  */
   /* ------------------------------------------------------------------------ */
 private:
   /// common function to help registering dofs
   void registerDOFsInternal(const ID & dof_id, Array<Real> & dofs_array);
 
 public:
   /// register an array of degree of freedom
   virtual void registerDOFs(const ID & dof_id, Array<Real> & dofs_array,
                             const DOFSupportType & support_type);
 
   /// the dof as an implied type of _dst_nodal and is defined only on a subset
   /// of nodes
   virtual void registerDOFs(const ID & dof_id, Array<Real> & dofs_array,
                             const ID & group_support);
 
   /// register an array of previous values of the degree of freedom
   virtual void registerDOFsPrevious(const ID & dof_id,
                                     Array<Real> & dofs_array);
 
   /// register an array of increment of degree of freedom
   virtual void registerDOFsIncrement(const ID & dof_id,
                                      Array<Real> & dofs_array);
 
   /// register an array of derivatives for a particular dof array
   virtual void registerDOFsDerivative(const ID & dof_id, UInt order,
                                       Array<Real> & dofs_derivative);
 
   /// register array representing the blocked degree of freedoms
   virtual void registerBlockedDOFs(const ID & dof_id,
                                    Array<bool> & blocked_dofs);
 
   /// Assemble an array to the global residual array
   virtual void assembleToResidual(const ID & dof_id,
                                   const Array<Real> & array_to_assemble,
                                   Real scale_factor = 1.) = 0;
 
   /// Assemble an array to the global lumped matrix array
   virtual void assembleToLumpedMatrix(const ID & dof_id,
                                       const Array<Real> & array_to_assemble,
                                       const ID & lumped_mtx,
                                       Real scale_factor = 1.) = 0;
 
   /**
    * Assemble elementary values to a local array of the size nb_nodes *
    * nb_dof_per_node. The dof number is implicitly considered as
    * conn(el, n) * nb_nodes_per_element + d.
    * With 0 < n < nb_nodes_per_element and 0 < d < nb_dof_per_node
    **/
   virtual void assembleElementalArrayLocalArray(
       const Array<Real> & elementary_vect, Array<Real> & array_assembeled,
       const ElementType & type, const GhostType & ghost_type,
       Real scale_factor = 1.,
       const Array<UInt> & filter_elements = empty_filter);
 
   /**
    * Assemble elementary values to the global residual array. The dof number is
    * implicitly considered as conn(el, n) * nb_nodes_per_element + d.
    * With 0 < n < nb_nodes_per_element and 0 < d < nb_dof_per_node
    **/
   virtual void assembleElementalArrayToResidual(
       const ID & dof_id, const Array<Real> & elementary_vect,
       const ElementType & type, const GhostType & ghost_type,
       Real scale_factor = 1.,
       const Array<UInt> & filter_elements = empty_filter);
 
   /**
    * Assemble elementary values to a global array corresponding to a lumped
    * matrix
    */
   virtual void assembleElementalArrayToLumpedMatrix(
       const ID & dof_id, const Array<Real> & elementary_vect,
       const ID & lumped_mtx, const ElementType & type,
       const GhostType & ghost_type, Real scale_factor = 1.,
       const Array<UInt> & filter_elements = empty_filter);
 
   /**
    * Assemble elementary values to the global residual array. The dof number is
    * implicitly considered as conn(el, n) * nb_nodes_per_element + d.  With 0 <
    * n < nb_nodes_per_element and 0 < d < nb_dof_per_node
    **/
   virtual void assembleElementalMatricesToMatrix(
       const ID & matrix_id, const ID & dof_id,
       const Array<Real> & elementary_mat, const ElementType & type,
       const GhostType & ghost_type = _not_ghost,
       const MatrixType & elemental_matrix_type = _symmetric,
       const Array<UInt> & filter_elements = empty_filter) = 0;
 
   /// multiply a vector by a matrix and assemble the result to the residual
   virtual void assembleMatMulVectToResidual(const ID & dof_id, const ID & A_id,
                                             const Array<Real> & x,
                                             Real scale_factor = 1) = 0;
 
   /// multiply the dofs by a matrix and assemble the result to the residual
   virtual void assembleMatMulDOFsToResidual(const ID & A_id,
                                             Real scale_factor = 1);
 
   /// multiply a vector by a lumped matrix and assemble the result to the
   /// residual
   virtual void assembleLumpedMatMulVectToResidual(const ID & dof_id,
                                                   const ID & A_id,
                                                   const Array<Real> & x,
                                                   Real scale_factor = 1) = 0;
 
   /// assemble coupling terms between to dofs
   virtual void assemblePreassembledMatrix(const ID & dof_id_m,
                                           const ID & dof_id_n,
                                           const ID & matrix_id,
                                           const TermsToAssemble & terms) = 0;
 
   /// sets the residual to 0
   virtual void clearResidual() = 0;
   /// sets the matrix to 0
   virtual void clearMatrix(const ID & mtx) = 0;
   /// sets the lumped matrix to 0
   virtual void clearLumpedMatrix(const ID & mtx) = 0;
 
   /// splits the solution storage from a global view to the per dof storages
   void splitSolutionPerDOFs();
 
   /// extract a lumped matrix part corresponding to a given dof
   virtual void getLumpedMatrixPerDOFs(const ID & dof_id, const ID & lumped_mtx,
                                       Array<Real> & lumped) = 0;
 
 protected:
   /// minimum functionality to implement per derived version of the DOFManager
   /// to allow the splitSolutionPerDOFs function to work
   virtual void getSolutionPerDOFs(const ID & dof_id,
                                   Array<Real> & solution_array) = 0;
 
 protected:
   /* ------------------------------------------------------------------------ */
   /// register a matrix
   SparseMatrix & registerSparseMatrix(const ID & matrix_id,
                                       std::unique_ptr<SparseMatrix> & matrix);
 
   /// register a non linear solver instantiated by a derived class
   NonLinearSolver &
   registerNonLinearSolver(const ID & non_linear_solver_id,
                           std::unique_ptr<NonLinearSolver> & non_linear_solver);
 
   /// register a time step solver instantiated by a derived class
   TimeStepSolver &
   registerTimeStepSolver(const ID & time_step_solver_id,
                          std::unique_ptr<TimeStepSolver> & time_step_solver);
 
   /* ------------------------------------------------------------------------ */
   /* Accessors                                                                */
   /* ------------------------------------------------------------------------ */
 public:
   /// Get the equation numbers corresponding to a dof_id. This might be used to
   /// access the matrix.
   inline const Array<UInt> & getEquationsNumbers(const ID & dof_id) const;
 
   /// Global number of dofs
   AKANTU_GET_MACRO(SystemSize, this->system_size, UInt);
 
   /// Local number of dofs
   AKANTU_GET_MACRO(LocalSystemSize, this->local_system_size, UInt);
 
   /// Retrieve all the registered DOFs
   std::vector<ID> getDOFIDs() const;
 
   /* ------------------------------------------------------------------------ */
   /* DOFs and derivatives accessors                                          */
   /* ------------------------------------------------------------------------ */
   /// Get a reference to the registered dof array for a given id
   inline Array<Real> & getDOFs(const ID & dofs_id);
 
   /// Get the support type of a given dof
   inline DOFSupportType getSupportType(const ID & dofs_id) const;
 
   /// are the dofs registered
   inline bool hasDOFs(const ID & dofs_id) const;
 
   /// Get a reference to the registered dof derivatives array for a given id
   inline Array<Real> & getDOFsDerivatives(const ID & dofs_id, UInt order);
 
   /// Does the dof has derivatives
   inline bool hasDOFsDerivatives(const ID & dofs_id, UInt order) const;
 
   /// Get a reference to the blocked dofs array registered for the given id
   inline const Array<bool> & getBlockedDOFs(const ID & dofs_id) const;
 
   /// Does the dof has a blocked array
   inline bool hasBlockedDOFs(const ID & dofs_id) const;
 
   /// Get a reference to the registered dof increment array for a given id
   inline Array<Real> & getDOFsIncrement(const ID & dofs_id);
 
   /// Does the dof has a increment array
   inline bool hasDOFsIncrement(const ID & dofs_id) const;
 
   /// Does the dof has a previous array
   inline Array<Real> & getPreviousDOFs(const ID & dofs_id);
 
   /// Get a reference to the registered dof array for previous step values a
   /// given id
   inline bool hasPreviousDOFs(const ID & dofs_id) const;
 
   /// saves the values from dofs to previous dofs
   virtual void savePreviousDOFs(const ID & dofs_id);
 
   /// Get a reference to the solution array registered for the given id
   inline const Array<Real> & getSolution(const ID & dofs_id) const;
 
   /* ------------------------------------------------------------------------ */
   /* Matrices accessors                                                       */
   /* ------------------------------------------------------------------------ */
   /// Get an instance of a new SparseMatrix
   virtual SparseMatrix & getNewMatrix(const ID & matrix_id,
                                       const MatrixType & matrix_type) = 0;
 
   /// Get an instance of a new SparseMatrix as a copy of the SparseMatrix
   /// matrix_to_copy_id
   virtual SparseMatrix & getNewMatrix(const ID & matrix_id,
                                       const ID & matrix_to_copy_id) = 0;
 
   /// Get the reference of an existing matrix
   SparseMatrix & getMatrix(const ID & matrix_id);
 
   /// check if the given matrix exists
   bool hasMatrix(const ID & matrix_id) const;
 
   /// Get an instance of a new lumped matrix
   virtual Array<Real> & getNewLumpedMatrix(const ID & matrix_id);
   /// Get the lumped version of a given matrix
   const Array<Real> & getLumpedMatrix(const ID & matrix_id) const;
   /// Get the lumped version of a given matrix
   Array<Real> & getLumpedMatrix(const ID & matrix_id);
 
   /// check if the given matrix exists
   bool hasLumpedMatrix(const ID & matrix_id) const;
 
   /* ------------------------------------------------------------------------ */
   /* Non linear system solver                                                 */
   /* ------------------------------------------------------------------------ */
   /// Get instance of a non linear solver
   virtual NonLinearSolver & getNewNonLinearSolver(
       const ID & nls_solver_id,
       const NonLinearSolverType & _non_linear_solver_type) = 0;
 
   /// get instance of a non linear solver
   virtual NonLinearSolver & getNonLinearSolver(const ID & nls_solver_id);
 
   /// check if the given solver exists
   bool hasNonLinearSolver(const ID & solver_id) const;
 
   /* ------------------------------------------------------------------------ */
   /* Time-Step Solver                                                         */
   /* ------------------------------------------------------------------------ */
   /// Get instance of a time step solver
   virtual TimeStepSolver &
   getNewTimeStepSolver(const ID & time_step_solver_id,
                        const TimeStepSolverType & type,
                        NonLinearSolver & non_linear_solver) = 0;
 
   /// get instance of a time step solver
   virtual TimeStepSolver & getTimeStepSolver(const ID & time_step_solver_id);
 
   /// check if the given solver exists
   bool hasTimeStepSolver(const ID & solver_id) const;
 
   /* ------------------------------------------------------------------------ */
   const Mesh & getMesh() {
     if (mesh) {
       return *mesh;
     } else {
       AKANTU_EXCEPTION("No mesh registered in this dof manager");
     }
   }
 
   /* ------------------------------------------------------------------------ */
   AKANTU_GET_MACRO(Communicator, communicator, const auto &);
   AKANTU_GET_MACRO_NOT_CONST(Communicator, communicator, auto &);
 
   /* ------------------------------------------------------------------------ */
   /* MeshEventHandler interface                                               */
   /* ------------------------------------------------------------------------ */
 protected:
   /// helper function for the DOFManager::onNodesAdded method
   virtual std::pair<UInt, UInt> updateNodalDOFs(const ID & dof_id,
                                                 const Array<UInt> & nodes_list);
 
 public:
   /// function to implement to react on  akantu::NewNodesEvent
   void onNodesAdded(const Array<UInt> & nodes_list,
                     const NewNodesEvent & event) override;
   /// function to implement to react on  akantu::RemovedNodesEvent
   void onNodesRemoved(const Array<UInt> & nodes_list,
                       const Array<UInt> & new_numbering,
                       const RemovedNodesEvent & event) override;
   /// function to implement to react on  akantu::NewElementsEvent
   void onElementsAdded(const Array<Element> & elements_list,
                        const NewElementsEvent & event) override;
   /// function to implement to react on  akantu::RemovedElementsEvent
   void onElementsRemoved(const Array<Element> & elements_list,
                          const ElementTypeMapArray<UInt> & new_numbering,
                          const RemovedElementsEvent & event) override;
   /// function to implement to react on  akantu::ChangedElementsEvent
   void onElementsChanged(const Array<Element> & old_elements_list,
                          const Array<Element> & new_elements_list,
                          const ElementTypeMapArray<UInt> & new_numbering,
                          const ChangedElementsEvent & event) override;
 
 protected:
   struct DOFData;
   inline DOFData & getDOFData(const ID & dof_id);
   inline const DOFData & getDOFData(const ID & dof_id) const;
   template <class _DOFData>
   inline _DOFData & getDOFDataTyped(const ID & dof_id);
   template <class _DOFData>
   inline const _DOFData & getDOFDataTyped(const ID & dof_id) const;
 
   virtual DOFData & getNewDOFData(const ID & dof_id);
 
   /* ------------------------------------------------------------------------ */
   /* Class Members                                                            */
   /* ------------------------------------------------------------------------ */
 protected:
   /// dof representations in the dof manager
   struct DOFData {
     DOFData() = delete;
     explicit DOFData(const ID & dof_id);
     virtual ~DOFData();
 
     /// DOF support type (nodal, general) this is needed to determine how the
     /// dof are shared among processors
     DOFSupportType support_type;
 
     ID group_support;
 
     /// Degree of freedom array
     Array<Real> * dof;
 
     /// Blocked degree of freedoms array
     Array<bool> * blocked_dofs;
 
     /// Degree of freedoms increment
     Array<Real> * increment;
 
     /// Degree of freedoms at previous step
     Array<Real> * previous;
 
     /// Solution associated to the dof
     Array<Real> solution;
 
     /// local numbering equation numbers
     Array<UInt> local_equation_number;
 
     /* ---------------------------------------------------------------------- */
     /* data for dynamic simulations                                           */
     /* ---------------------------------------------------------------------- */
     /// Degree of freedom derivatives arrays
     std::vector<Array<Real> *> dof_derivatives;
   };
 
   /// type to store dofs information
   using DOFStorage = std::map<ID, std::unique_ptr<DOFData>>;
 
   /// type to store all the matrices
   using SparseMatricesMap = std::map<ID, std::unique_ptr<SparseMatrix>>;
 
   /// type to store all the lumped matrices
   using LumpedMatricesMap = std::map<ID, std::unique_ptr<Array<Real>>>;
 
   /// type to store all the non linear solver
   using NonLinearSolversMap = std::map<ID, std::unique_ptr<NonLinearSolver>>;
 
   /// type to store all the time step solver
   using TimeStepSolversMap = std::map<ID, std::unique_ptr<TimeStepSolver>>;
 
   /// store a reference to the dof arrays
   DOFStorage dofs;
 
   /// list of sparse matrices that where created
   SparseMatricesMap matrices;
 
   /// list of lumped matrices
   LumpedMatricesMap lumped_matrices;
 
   /// non linear solvers storage
   NonLinearSolversMap non_linear_solvers;
 
   /// time step solvers storage
   TimeStepSolversMap time_step_solvers;
 
   /// reference to the underlying mesh
   Mesh * mesh{nullptr};
 
   /// Total number of degrees of freedom (size with the ghosts)
   UInt local_system_size{0};
 
   /// Number of purely local dofs (size without the ghosts)
   UInt pure_local_system_size{0};
 
   /// Total number of degrees of freedom
   UInt system_size{0};
 
   /// Communicator used for this manager, should be the same as in the mesh if a
   /// mesh is registered
   Communicator & communicator;
 };
 
 using DefaultDOFManagerFactory =
     Factory<DOFManager, ID, const ID &, const MemoryID &>;
 using DOFManagerFactory =
     Factory<DOFManager, ID, Mesh &, const ID &, const MemoryID &>;
 
 } // namespace akantu
 
 #include "dof_manager_inline_impl.cc"
 
 #endif /* __AKANTU_DOF_MANAGER_HH__ */
diff --git a/src/model/dof_manager_default.cc b/src/model/dof_manager_default.cc
index c4b511c60..6e917a7d9 100644
--- a/src/model/dof_manager_default.cc
+++ b/src/model/dof_manager_default.cc
@@ -1,921 +1,922 @@
 /**
  * @file   dof_manager_default.cc
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
- * @date   Tue Aug 11 16:21:01 2015
+ * @date creation: Tue Aug 18 2015
+ * @date last modification: Thu Feb 08 2018
  *
  * @brief  Implementation of the default DOFManager
  *
  * @section LICENSE
  *
- * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * Copyright (©) 2015-2018 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
- * terms  of the  GNU Lesser  General Public  License as  published by  the Free
+ * 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
+ * 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 "dof_manager_default.hh"
 #include "communicator.hh"
 #include "dof_synchronizer.hh"
 #include "element_group.hh"
 #include "node_synchronizer.hh"
 #include "non_linear_solver_default.hh"
 #include "sparse_matrix_aij.hh"
 #include "terms_to_assemble.hh"
 #include "time_step_solver_default.hh"
 /* -------------------------------------------------------------------------- */
 #include <algorithm>
 #include <memory>
 #include <numeric>
 #include <unordered_map>
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 inline void DOFManagerDefault::addSymmetricElementalMatrixToSymmetric(
     SparseMatrixAIJ & matrix, const Matrix<Real> & elementary_mat,
     const Vector<UInt> & equation_numbers, UInt max_size) {
   for (UInt i = 0; i < elementary_mat.rows(); ++i) {
     UInt c_irn = equation_numbers(i);
     if (c_irn < max_size) {
       for (UInt j = i; j < elementary_mat.cols(); ++j) {
         UInt c_jcn = equation_numbers(j);
         if (c_jcn < max_size) {
           matrix(c_irn, c_jcn) += elementary_mat(i, j);
         }
       }
     }
   }
 }
 
 /* -------------------------------------------------------------------------- */
 inline void DOFManagerDefault::addUnsymmetricElementalMatrixToSymmetric(
     SparseMatrixAIJ & matrix, const Matrix<Real> & elementary_mat,
     const Vector<UInt> & equation_numbers, UInt max_size) {
   for (UInt i = 0; i < elementary_mat.rows(); ++i) {
     UInt c_irn = equation_numbers(i);
     if (c_irn < max_size) {
       for (UInt j = 0; j < elementary_mat.cols(); ++j) {
         UInt c_jcn = equation_numbers(j);
         if (c_jcn < max_size) {
           if (c_jcn >= c_irn) {
             matrix(c_irn, c_jcn) += elementary_mat(i, j);
           }
         }
       }
     }
   }
 }
 
 /* -------------------------------------------------------------------------- */
 inline void DOFManagerDefault::addElementalMatrixToUnsymmetric(
     SparseMatrixAIJ & matrix, const Matrix<Real> & elementary_mat,
     const Vector<UInt> & equation_numbers, UInt max_size) {
   for (UInt i = 0; i < elementary_mat.rows(); ++i) {
     UInt c_irn = equation_numbers(i);
     if (c_irn < max_size) {
       for (UInt j = 0; j < elementary_mat.cols(); ++j) {
         UInt c_jcn = equation_numbers(j);
         if (c_jcn < max_size) {
           matrix(c_irn, c_jcn) += elementary_mat(i, j);
         }
       }
     }
   }
 }
 
 /* -------------------------------------------------------------------------- */
 DOFManagerDefault::DOFManagerDefault(const ID & id, const MemoryID & memory_id)
     : DOFManager(id, memory_id), residual(0, 1, std::string(id + ":residual")),
       global_residual(nullptr),
       global_solution(0, 1, std::string(id + ":global_solution")),
       global_blocked_dofs(0, 1, std::string(id + ":global_blocked_dofs")),
       previous_global_blocked_dofs(
           0, 1, std::string(id + ":previous_global_blocked_dofs")),
       dofs_type(0, 1, std::string(id + ":dofs_type")),
       data_cache(0, 1, std::string(id + ":data_cache_array")),
 
       global_equation_number(0, 1, "global_equation_number"),
       synchronizer(nullptr) {}
 
 /* -------------------------------------------------------------------------- */
 DOFManagerDefault::DOFManagerDefault(Mesh & mesh, const ID & id,
                                      const MemoryID & memory_id)
     : DOFManager(mesh, id, memory_id),
       residual(0, 1, std::string(id + ":residual")), global_residual(nullptr),
       global_solution(0, 1, std::string(id + ":global_solution")),
       global_blocked_dofs(0, 1, std::string(id + ":global_blocked_dofs")),
       previous_global_blocked_dofs(
           0, 1, std::string(id + ":previous_global_blocked_dofs")),
       dofs_type(0, 1, std::string(id + ":dofs_type")),
       data_cache(0, 1, std::string(id + ":data_cache_array")),
       jacobian_release(0),
       global_equation_number(0, 1, "global_equation_number"),
       first_global_dof_id(0), synchronizer(nullptr) {
   if (this->mesh->isDistributed())
     this->synchronizer = std::make_unique<DOFSynchronizer>(
         *this, this->id + ":dof_synchronizer", this->memory_id);
 }
 
 /* -------------------------------------------------------------------------- */
 DOFManagerDefault::~DOFManagerDefault() = default;
 
 /* -------------------------------------------------------------------------- */
 template <typename T>
 void DOFManagerDefault::assembleToGlobalArray(
     const ID & dof_id, const Array<T> & array_to_assemble,
     Array<T> & global_array, T scale_factor) {
   AKANTU_DEBUG_IN();
   const Array<UInt> & equation_number = this->getLocalEquationNumbers(dof_id);
 
   UInt nb_degree_of_freedoms =
       array_to_assemble.size() * array_to_assemble.getNbComponent();
 
   AKANTU_DEBUG_ASSERT(equation_number.size() == nb_degree_of_freedoms,
                       "The array to assemble does not have a correct size."
                           << " (" << array_to_assemble.getID() << ")");
 
   typename Array<T>::const_scalar_iterator arr_it =
       array_to_assemble.begin_reinterpret(nb_degree_of_freedoms);
   Array<UInt>::const_scalar_iterator equ_it = equation_number.begin();
 
   for (UInt d = 0; d < nb_degree_of_freedoms; ++d, ++arr_it, ++equ_it) {
     global_array(*equ_it) += scale_factor * (*arr_it);
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 DOFManagerDefault::DOFDataDefault::DOFDataDefault(const ID & dof_id)
     : DOFData(dof_id), associated_nodes(0, 1, dof_id + "associated_nodes") {}
 
 /* -------------------------------------------------------------------------- */
 DOFManager::DOFData & DOFManagerDefault::getNewDOFData(const ID & dof_id) {
   this->dofs[dof_id] = std::make_unique<DOFDataDefault>(dof_id);
   return *this->dofs[dof_id];
 }
 
 /* -------------------------------------------------------------------------- */
 class GlobalDOFInfoDataAccessor : public DataAccessor<UInt> {
 public:
   using size_type =
       typename std::unordered_map<UInt, std::vector<UInt>>::size_type;
 
   GlobalDOFInfoDataAccessor() = default;
 
   void addDOFToNode(UInt node, UInt dof) { dofs_per_node[node].push_back(dof); }
   UInt getNthDOFForNode(UInt nth_dof, UInt node) const {
     auto it = dofs_per_node.find(node);
     AKANTU_DEBUG_ASSERT(it != dofs_per_node.end(),
                         "Did not find the node " << node);
     return it->second[nth_dof];
   }
 
   UInt getNbData(const Array<UInt> & nodes,
                  const SynchronizationTag & tag) const override {
     if (tag == _gst_size) {
       return nodes.size() * sizeof(size_type);
     }
 
     if (tag == _gst_update) {
       UInt total_size = 0;
       for (auto node : nodes) {
         auto it = dofs_per_node.find(node);
         if (it != dofs_per_node.end())
           total_size += CommunicationBuffer::sizeInBuffer(it->second);
       }
       return total_size;
     }
 
     return 0;
   }
 
   void packData(CommunicationBuffer & buffer, const Array<UInt> & nodes,
                 const SynchronizationTag & tag) const override {
     for (auto node : nodes) {
       auto it = dofs_per_node.find(node);
       if (tag == _gst_size) {
         if (it != dofs_per_node.end()) {
           buffer << it->second.size();
         } else {
           buffer << 0;
         }
       } else if (tag == _gst_update) {
         if (it != dofs_per_node.end())
           buffer << it->second;
       }
     }
   }
 
   void unpackData(CommunicationBuffer & buffer, const Array<UInt> & nodes,
                   const SynchronizationTag & tag) override {
     for (auto node : nodes) {
       auto it = dofs_per_node.find(node);
       if (tag == _gst_size) {
         size_type size;
         buffer >> size;
         if (size != 0)
           dofs_per_node[node].resize(size);
       } else if (tag == _gst_update) {
         if (it != dofs_per_node.end())
           buffer >> it->second;
       }
     }
   }
 
 protected:
   std::unordered_map<UInt, std::vector<UInt>> dofs_per_node;
 };
 
 /* -------------------------------------------------------------------------- */
 void DOFManagerDefault::registerDOFsInternal(const ID & dof_id, UInt nb_dofs,
                                              UInt nb_pure_local_dofs) {
   // auto prank = this->communicator.whoAmI();
   // auto psize = this->communicator.getNbProc();
 
   // access the relevant data to update
   auto & dof_data = this->getDOFDataTyped<DOFDataDefault>(dof_id);
   const auto & support_type = dof_data.support_type;
 
   const auto & group = dof_data.group_support;
 
   if (support_type == _dst_nodal and group != "__mesh__") {
     auto & support_nodes =
         this->mesh->getElementGroup(group).getNodeGroup().getNodes();
     this->updateDOFsData(
         dof_data, nb_dofs, nb_pure_local_dofs,
         [&support_nodes](UInt node) -> UInt { return support_nodes[node]; });
   } else {
 
     this->updateDOFsData(dof_data, nb_dofs, nb_pure_local_dofs,
                          [](UInt node) -> UInt { return node; });
   }
 
   // update the synchronizer if needed
   if (this->synchronizer)
     this->synchronizer->registerDOFs(dof_id);
 }
 
 /* -------------------------------------------------------------------------- */
 void DOFManagerDefault::registerDOFs(const ID & dof_id,
                                      Array<Real> & dofs_array,
                                      const DOFSupportType & support_type) {
   // stores the current numbers of dofs
   UInt nb_dofs_old = this->local_system_size;
   UInt nb_pure_local_dofs_old = this->pure_local_system_size;
 
   // update or create the dof_data
   DOFManager::registerDOFs(dof_id, dofs_array, support_type);
 
   UInt nb_dofs = this->local_system_size - nb_dofs_old;
   UInt nb_pure_local_dofs =
       this->pure_local_system_size - nb_pure_local_dofs_old;
 
   this->registerDOFsInternal(dof_id, nb_dofs, nb_pure_local_dofs);
 }
 
 /* -------------------------------------------------------------------------- */
 void DOFManagerDefault::registerDOFs(const ID & dof_id,
                                      Array<Real> & dofs_array,
                                      const ID & group_support) {
   // stores the current numbers of dofs
   UInt nb_dofs_old = this->local_system_size;
   UInt nb_pure_local_dofs_old = this->pure_local_system_size;
 
   // update or create the dof_data
   DOFManager::registerDOFs(dof_id, dofs_array, group_support);
 
   UInt nb_dofs = this->local_system_size - nb_dofs_old;
   UInt nb_pure_local_dofs =
       this->pure_local_system_size - nb_pure_local_dofs_old;
 
   this->registerDOFsInternal(dof_id, nb_dofs, nb_pure_local_dofs);
 }
 
 /* -------------------------------------------------------------------------- */
 SparseMatrix & DOFManagerDefault::getNewMatrix(const ID & id,
                                                const MatrixType & matrix_type) {
   ID matrix_id = this->id + ":mtx:" + id;
   std::unique_ptr<SparseMatrix> sm =
       std::make_unique<SparseMatrixAIJ>(*this, matrix_type, matrix_id);
   return this->registerSparseMatrix(matrix_id, sm);
 }
 
 /* -------------------------------------------------------------------------- */
 SparseMatrix & DOFManagerDefault::getNewMatrix(const ID & id,
                                                const ID & matrix_to_copy_id) {
 
   ID matrix_id = this->id + ":mtx:" + id;
   SparseMatrixAIJ & sm_to_copy = this->getMatrix(matrix_to_copy_id);
   std::unique_ptr<SparseMatrix> sm =
       std::make_unique<SparseMatrixAIJ>(sm_to_copy, matrix_id);
   return this->registerSparseMatrix(matrix_id, sm);
 }
 
 /* -------------------------------------------------------------------------- */
 SparseMatrixAIJ & DOFManagerDefault::getMatrix(const ID & id) {
   SparseMatrix & matrix = DOFManager::getMatrix(id);
 
   return dynamic_cast<SparseMatrixAIJ &>(matrix);
 }
 
 /* -------------------------------------------------------------------------- */
 NonLinearSolver &
 DOFManagerDefault::getNewNonLinearSolver(const ID & id,
                                          const NonLinearSolverType & type) {
   ID non_linear_solver_id = this->id + ":nls:" + id;
   std::unique_ptr<NonLinearSolver> nls;
   switch (type) {
 #if defined(AKANTU_IMPLICIT)
   case _nls_newton_raphson:
   case _nls_newton_raphson_modified: {
     nls = std::make_unique<NonLinearSolverNewtonRaphson>(
         *this, type, non_linear_solver_id, this->memory_id);
     break;
   }
   case _nls_linear: {
     nls = std::make_unique<NonLinearSolverLinear>(
         *this, type, non_linear_solver_id, this->memory_id);
     break;
   }
 #endif
   case _nls_lumped: {
     nls = std::make_unique<NonLinearSolverLumped>(
         *this, type, non_linear_solver_id, this->memory_id);
     break;
   }
   default:
     AKANTU_EXCEPTION("The asked type of non linear solver is not supported by "
                      "this dof manager");
   }
 
   return this->registerNonLinearSolver(non_linear_solver_id, nls);
 }
 
 /* -------------------------------------------------------------------------- */
 TimeStepSolver &
 DOFManagerDefault::getNewTimeStepSolver(const ID & id,
                                         const TimeStepSolverType & type,
                                         NonLinearSolver & non_linear_solver) {
   ID time_step_solver_id = this->id + ":tss:" + id;
 
   std::unique_ptr<TimeStepSolver> tss = std::make_unique<TimeStepSolverDefault>(
       *this, type, non_linear_solver, time_step_solver_id, this->memory_id);
 
   return this->registerTimeStepSolver(time_step_solver_id, tss);
 }
 
 /* -------------------------------------------------------------------------- */
 void DOFManagerDefault::clearResidual() {
   this->residual.resize(this->local_system_size);
   this->residual.clear();
 }
 
 /* -------------------------------------------------------------------------- */
 void DOFManagerDefault::clearMatrix(const ID & mtx) {
   this->getMatrix(mtx).clear();
 }
 
 /* -------------------------------------------------------------------------- */
 void DOFManagerDefault::clearLumpedMatrix(const ID & mtx) {
   this->getLumpedMatrix(mtx).clear();
 }
 
 /* -------------------------------------------------------------------------- */
 void DOFManagerDefault::updateGlobalBlockedDofs() {
   auto it = this->dofs.begin();
   auto end = this->dofs.end();
 
   this->previous_global_blocked_dofs.copy(this->global_blocked_dofs);
   this->global_blocked_dofs.resize(this->local_system_size);
   this->global_blocked_dofs.clear();
 
   for (; it != end; ++it) {
     if (!this->hasBlockedDOFs(it->first))
       continue;
 
     DOFData & dof_data = *it->second;
     this->assembleToGlobalArray(it->first, *dof_data.blocked_dofs,
                                 this->global_blocked_dofs, true);
   }
 }
 
 /* -------------------------------------------------------------------------- */
 template <typename T>
 void DOFManagerDefault::getArrayPerDOFs(const ID & dof_id,
                                         const Array<T> & global_array,
                                         Array<T> & local_array) const {
   AKANTU_DEBUG_IN();
 
   const Array<UInt> & equation_number = this->getLocalEquationNumbers(dof_id);
 
   UInt nb_degree_of_freedoms = equation_number.size();
   local_array.resize(nb_degree_of_freedoms / local_array.getNbComponent());
 
   auto loc_it = local_array.begin_reinterpret(nb_degree_of_freedoms);
   auto equ_it = equation_number.begin();
 
   for (UInt d = 0; d < nb_degree_of_freedoms; ++d, ++loc_it, ++equ_it) {
     (*loc_it) = global_array(*equ_it);
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 // void DOFManagerDefault::getEquationsNumbers(const ID & dof_id,
 //                                             Array<UInt> & equation_numbers) {
 //   AKANTU_DEBUG_IN();
 //   this->getArrayPerDOFs(dof_id, this->global_equation_number,
 //   equation_numbers); AKANTU_DEBUG_OUT();
 // }
 
 /* -------------------------------------------------------------------------- */
 void DOFManagerDefault::getSolutionPerDOFs(const ID & dof_id,
                                            Array<Real> & solution_array) {
   AKANTU_DEBUG_IN();
   this->getArrayPerDOFs(dof_id, this->global_solution, solution_array);
   AKANTU_DEBUG_OUT();
 }
 /* -------------------------------------------------------------------------- */
 void DOFManagerDefault::getLumpedMatrixPerDOFs(const ID & dof_id,
                                                const ID & lumped_mtx,
                                                Array<Real> & lumped) {
   AKANTU_DEBUG_IN();
   this->getArrayPerDOFs(dof_id, this->getLumpedMatrix(lumped_mtx), lumped);
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void DOFManagerDefault::assembleToResidual(
     const ID & dof_id, const Array<Real> & array_to_assemble,
     Real scale_factor) {
   AKANTU_DEBUG_IN();
 
   this->assembleToGlobalArray(dof_id, array_to_assemble, this->residual,
                               scale_factor);
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void DOFManagerDefault::assembleToLumpedMatrix(
     const ID & dof_id, const Array<Real> & array_to_assemble,
     const ID & lumped_mtx, Real scale_factor) {
   AKANTU_DEBUG_IN();
 
   Array<Real> & lumped = this->getLumpedMatrix(lumped_mtx);
   this->assembleToGlobalArray(dof_id, array_to_assemble, lumped, scale_factor);
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void DOFManagerDefault::assembleMatMulVectToResidual(const ID & dof_id,
                                                      const ID & A_id,
                                                      const Array<Real> & x,
                                                      Real scale_factor) {
   SparseMatrixAIJ & A = this->getMatrix(A_id);
 
   // Array<Real> data_cache(this->local_system_size, 1, 0.);
   this->data_cache.resize(this->local_system_size);
   this->data_cache.clear();
 
   this->assembleToGlobalArray(dof_id, x, data_cache, 1.);
 
   A.matVecMul(data_cache, this->residual, scale_factor, 1.);
 }
 
 /* -------------------------------------------------------------------------- */
 void DOFManagerDefault::assembleLumpedMatMulVectToResidual(
     const ID & dof_id, const ID & A_id, const Array<Real> & x,
     Real scale_factor) {
   const Array<Real> & A = this->getLumpedMatrix(A_id);
 
   //  Array<Real> data_cache(this->local_system_size, 1, 0.);
   this->data_cache.resize(this->local_system_size);
   this->data_cache.clear();
 
   this->assembleToGlobalArray(dof_id, x, data_cache, scale_factor);
 
   auto A_it = A.begin();
   auto A_end = A.end();
   auto x_it = data_cache.begin();
   auto r_it = this->residual.begin();
 
   for (; A_it != A_end; ++A_it, ++x_it, ++r_it) {
     *r_it += *A_it * *x_it;
   }
 }
 
 /* -------------------------------------------------------------------------- */
 void DOFManagerDefault::assembleElementalMatricesToMatrix(
     const ID & matrix_id, const ID & dof_id, const Array<Real> & elementary_mat,
     const ElementType & type, const GhostType & ghost_type,
     const MatrixType & elemental_matrix_type,
     const Array<UInt> & filter_elements) {
   AKANTU_DEBUG_IN();
 
   DOFData & dof_data = this->getDOFData(dof_id);
 
   AKANTU_DEBUG_ASSERT(dof_data.support_type == _dst_nodal,
                       "This function applies only on Nodal dofs");
 
   this->addToProfile(matrix_id, dof_id, type, ghost_type);
 
   const Array<UInt> & equation_number = this->getLocalEquationNumbers(dof_id);
   SparseMatrixAIJ & A = this->getMatrix(matrix_id);
 
   UInt nb_element;
   UInt * filter_it = nullptr;
   if (filter_elements != empty_filter) {
     nb_element = filter_elements.size();
     filter_it = filter_elements.storage();
   } else {
     if (dof_data.group_support != "__mesh__") {
       const Array<UInt> & group_elements =
           this->mesh->getElementGroup(dof_data.group_support)
               .getElements(type, ghost_type);
       nb_element = group_elements.size();
       filter_it = group_elements.storage();
     } else {
       nb_element = this->mesh->getNbElement(type, ghost_type);
     }
   }
 
   AKANTU_DEBUG_ASSERT(elementary_mat.size() == nb_element,
                       "The vector elementary_mat("
                           << elementary_mat.getID()
                           << ") has not the good size.");
 
   UInt nb_nodes_per_element = Mesh::getNbNodesPerElement(type);
 
   UInt nb_degree_of_freedom = dof_data.dof->getNbComponent();
 
   const Array<UInt> & connectivity =
       this->mesh->getConnectivity(type, ghost_type);
   auto conn_begin = connectivity.begin(nb_nodes_per_element);
   auto conn_it = conn_begin;
 
   UInt size_mat = nb_nodes_per_element * nb_degree_of_freedom;
 
   Vector<UInt> element_eq_nb(nb_degree_of_freedom * nb_nodes_per_element);
   Array<Real>::const_matrix_iterator el_mat_it =
       elementary_mat.begin(size_mat, size_mat);
 
   for (UInt e = 0; e < nb_element; ++e, ++el_mat_it) {
     if (filter_it)
       conn_it = conn_begin + *filter_it;
 
     this->extractElementEquationNumber(equation_number, *conn_it,
                                        nb_degree_of_freedom, element_eq_nb);
     std::transform(element_eq_nb.storage(),
                    element_eq_nb.storage() + element_eq_nb.size(),
                    element_eq_nb.storage(), [&](UInt & local) -> UInt {
                      return this->localToGlobalEquationNumber(local);
                    });
 
     if (filter_it)
       ++filter_it;
     else
       ++conn_it;
 
     if (A.getMatrixType() == _symmetric)
       if (elemental_matrix_type == _symmetric)
         this->addSymmetricElementalMatrixToSymmetric(A, *el_mat_it,
                                                      element_eq_nb, A.size());
       else
         this->addUnsymmetricElementalMatrixToSymmetric(A, *el_mat_it,
                                                        element_eq_nb, A.size());
     else
       this->addElementalMatrixToUnsymmetric(A, *el_mat_it, element_eq_nb,
                                             A.size());
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void DOFManagerDefault::assemblePreassembledMatrix(
     const ID & dof_id_m, const ID & dof_id_n, const ID & matrix_id,
     const TermsToAssemble & terms) {
   const Array<UInt> & equation_number_m =
       this->getLocalEquationNumbers(dof_id_m);
   const Array<UInt> & equation_number_n =
       this->getLocalEquationNumbers(dof_id_n);
   SparseMatrixAIJ & A = this->getMatrix(matrix_id);
 
   for (const auto & term : terms) {
     UInt gi = this->localToGlobalEquationNumber(equation_number_m(term.i()));
     UInt gj = this->localToGlobalEquationNumber(equation_number_n(term.j()));
     A.add(gi, gj, term);
   }
 }
 
 /* -------------------------------------------------------------------------- */
 void DOFManagerDefault::addToProfile(const ID & matrix_id, const ID & dof_id,
                                      const ElementType & type,
                                      const GhostType & ghost_type) {
   AKANTU_DEBUG_IN();
 
   const DOFData & dof_data = this->getDOFData(dof_id);
 
   if (dof_data.support_type != _dst_nodal)
     return;
 
   auto mat_dof = std::make_pair(matrix_id, dof_id);
   auto type_pair = std::make_pair(type, ghost_type);
 
   auto prof_it = this->matrix_profiled_dofs.find(mat_dof);
   if (prof_it != this->matrix_profiled_dofs.end() &&
       std::find(prof_it->second.begin(), prof_it->second.end(), type_pair) !=
           prof_it->second.end())
     return;
 
   UInt nb_degree_of_freedom_per_node = dof_data.dof->getNbComponent();
 
   const Array<UInt> & equation_number = this->getLocalEquationNumbers(dof_id);
 
   SparseMatrixAIJ & A = this->getMatrix(matrix_id);
 
   UInt size = A.size();
 
   UInt nb_nodes_per_element = Mesh::getNbNodesPerElement(type);
 
   const auto & connectivity = this->mesh->getConnectivity(type, ghost_type);
   auto cbegin = connectivity.begin(nb_nodes_per_element);
   auto cit = cbegin;
 
   UInt nb_elements = connectivity.size();
   UInt * ge_it = nullptr;
   if (dof_data.group_support != "__mesh__") {
     const Array<UInt> & group_elements =
         this->mesh->getElementGroup(dof_data.group_support)
             .getElements(type, ghost_type);
     ge_it = group_elements.storage();
     nb_elements = group_elements.size();
   }
 
   UInt size_mat = nb_nodes_per_element * nb_degree_of_freedom_per_node;
   Vector<UInt> element_eq_nb(size_mat);
 
   for (UInt e = 0; e < nb_elements; ++e) {
     if (ge_it)
       cit = cbegin + *ge_it;
 
     this->extractElementEquationNumber(
         equation_number, *cit, nb_degree_of_freedom_per_node, element_eq_nb);
     std::transform(element_eq_nb.storage(),
                    element_eq_nb.storage() + element_eq_nb.size(),
                    element_eq_nb.storage(), [&](UInt & local) -> UInt {
                      return this->localToGlobalEquationNumber(local);
                    });
 
     if (ge_it)
       ++ge_it;
     else
       ++cit;
 
     for (UInt i = 0; i < size_mat; ++i) {
       UInt c_irn = element_eq_nb(i);
       if (c_irn < size) {
         for (UInt j = 0; j < size_mat; ++j) {
           UInt c_jcn = element_eq_nb(j);
           if (c_jcn < size) {
             A.add(c_irn, c_jcn);
           }
         }
       }
     }
   }
 
   this->matrix_profiled_dofs[mat_dof].push_back(type_pair);
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void DOFManagerDefault::applyBoundary(const ID & matrix_id) {
   SparseMatrixAIJ & J = this->getMatrix(matrix_id);
 
   if (this->jacobian_release == J.getValueRelease()) {
     auto are_equal =
         std::equal(global_blocked_dofs.begin(), global_blocked_dofs.end(),
                    previous_global_blocked_dofs.begin());
 
     if (not are_equal)
       J.applyBoundary();
 
     previous_global_blocked_dofs.copy(global_blocked_dofs);
   } else {
     J.applyBoundary();
   }
 
   this->jacobian_release = J.getValueRelease();
 }
 
 /* -------------------------------------------------------------------------- */
 const Array<Real> & DOFManagerDefault::getGlobalResidual() {
   if (this->synchronizer) {
     if (not this->global_residual) {
       this->global_residual =
           std::make_unique<Array<Real>>(0, 1, "global_residual");
     }
 
     if (this->synchronizer->getCommunicator().whoAmI() == 0) {
       this->global_residual->resize(this->system_size);
       this->synchronizer->gather(this->residual, *this->global_residual);
     } else {
       this->synchronizer->gather(this->residual);
     }
 
     return *this->global_residual;
   } else {
     return this->residual;
   }
 }
 
 /* -------------------------------------------------------------------------- */
 const Array<Real> & DOFManagerDefault::getResidual() const {
   return this->residual;
 }
 
 /* -------------------------------------------------------------------------- */
 void DOFManagerDefault::setGlobalSolution(const Array<Real> & solution) {
   if (this->synchronizer) {
     if (this->synchronizer->getCommunicator().whoAmI() == 0) {
       this->synchronizer->scatter(this->global_solution, solution);
     } else {
       this->synchronizer->scatter(this->global_solution);
     }
   } else {
     AKANTU_DEBUG_ASSERT(solution.size() == this->global_solution.size(),
                         "Sequential call to this function needs the solution "
                         "to be the same size as the global_solution");
     this->global_solution.copy(solution);
   }
 }
 
 /* -------------------------------------------------------------------------- */
 void DOFManagerDefault::onNodesAdded(const Array<UInt> & nodes_list,
                                      const NewNodesEvent & event) {
   DOFManager::onNodesAdded(nodes_list, event);
 
   if (this->synchronizer)
     this->synchronizer->onNodesAdded(nodes_list);
 }
 
 /* -------------------------------------------------------------------------- */
 std::pair<UInt, UInt>
 DOFManagerDefault::updateNodalDOFs(const ID & dof_id,
                                    const Array<UInt> & nodes_list) {
   UInt nb_new_local_dofs, nb_new_pure_local;
   std::tie(nb_new_local_dofs, nb_new_pure_local) =
       DOFManager::updateNodalDOFs(dof_id, nodes_list);
 
   auto & dof_data = this->getDOFDataTyped<DOFDataDefault>(dof_id);
   updateDOFsData(dof_data, nb_new_local_dofs, nb_new_pure_local,
                  [&nodes_list](UInt pos) -> UInt { return nodes_list[pos]; });
 
   return std::make_pair(nb_new_local_dofs, nb_new_pure_local);
 }
 
 /* -------------------------------------------------------------------------- */
 void DOFManagerDefault::updateDOFsData(
     DOFDataDefault & dof_data, UInt nb_new_local_dofs, UInt nb_new_pure_local,
     const std::function<UInt(UInt)> & getNode) {
   auto prank = this->communicator.whoAmI();
   auto psize = this->communicator.getNbProc();
 
   // access the relevant data to update
   const auto & support_type = dof_data.support_type;
 
   GlobalDOFInfoDataAccessor data_accessor;
 
   // resize all relevant arrays
   this->residual.resize(this->local_system_size);
   this->dofs_type.resize(this->local_system_size);
   this->global_solution.resize(this->local_system_size);
   this->global_blocked_dofs.resize(this->local_system_size);
   this->previous_global_blocked_dofs.resize(this->local_system_size);
   this->global_equation_number.resize(this->local_system_size);
 
   for (auto & lumped_matrix : lumped_matrices)
     lumped_matrix.second->resize(this->local_system_size);
 
   dof_data.local_equation_number.reserve(dof_data.local_equation_number.size() +
                                          nb_new_local_dofs);
 
   // determine the first local/global dof id to use
   Array<UInt> nb_dofs_per_proc(psize);
   nb_dofs_per_proc(prank) = nb_new_pure_local;
   this->communicator.allGather(nb_dofs_per_proc);
 
   this->first_global_dof_id += std::accumulate(
       nb_dofs_per_proc.begin(), nb_dofs_per_proc.begin() + prank, 0);
   UInt first_dof_id = this->local_system_size - nb_new_local_dofs;
 
   if (support_type == _dst_nodal) {
     dof_data.associated_nodes.reserve(dof_data.associated_nodes.size() +
                                       nb_new_local_dofs);
   }
 
   // update per dof info
   for (UInt d = 0; d < nb_new_local_dofs; ++d) {
     UInt local_eq_num = first_dof_id + d;
     dof_data.local_equation_number.push_back(local_eq_num);
 
     bool is_local_dof = true;
 
     // determine the dof type
     switch (support_type) {
     case _dst_nodal: {
       UInt node = getNode(d / dof_data.dof->getNbComponent());
 
       this->dofs_type(local_eq_num) = this->mesh->getNodeType(node);
       dof_data.associated_nodes.push_back(node);
 
       is_local_dof = this->mesh->isLocalOrMasterNode(node);
 
       if (is_local_dof) {
         data_accessor.addDOFToNode(node, first_global_dof_id);
       }
 
       break;
     }
     case _dst_generic: {
       this->dofs_type(local_eq_num) = _nt_normal;
       break;
     }
     default: { AKANTU_EXCEPTION("This type of dofs is not handled yet."); }
     }
 
     // update global id for local dofs
     if (is_local_dof) {
       this->global_equation_number(local_eq_num) = this->first_global_dof_id;
       this->global_to_local_mapping[this->first_global_dof_id] = local_eq_num;
       ++this->first_global_dof_id;
     } else {
       this->global_equation_number(local_eq_num) = 0;
     }
   }
 
   // synchronize the global numbering for slaves
   if (support_type == _dst_nodal && this->synchronizer) {
     auto nb_dofs_per_node = dof_data.dof->getNbComponent();
 
     auto & node_synchronizer = this->mesh->getNodeSynchronizer();
     node_synchronizer.synchronizeOnce(data_accessor, _gst_size);
     node_synchronizer.synchronizeOnce(data_accessor, _gst_update);
 
     std::vector<UInt> counters(nb_new_local_dofs / nb_dofs_per_node);
 
     for (UInt d = 0; d < nb_new_local_dofs; ++d) {
       UInt local_eq_num = first_dof_id + d;
       if (not this->isSlaveDOF(local_eq_num))
         continue;
 
       UInt node = d / nb_dofs_per_node;
       UInt dof_count = counters[node]++;
       node = getNode(node);
 
       UInt global_dof_id = data_accessor.getNthDOFForNode(dof_count, node);
 
       this->global_equation_number(local_eq_num) = global_dof_id;
       this->global_to_local_mapping[global_dof_id] = local_eq_num;
     }
   }
 }
 
 /* -------------------------------------------------------------------------- */
 // register in factory
 static bool default_dof_manager_is_registered[[gnu::unused]] =
     DefaultDOFManagerFactory::getInstance().registerAllocator(
         "default", [](const ID & id,
                       const MemoryID & mem_id) -> std::unique_ptr<DOFManager> {
           return std::make_unique<DOFManagerDefault>(id, mem_id);
         });
 
 static bool dof_manager_is_registered[[gnu::unused]] =
     DOFManagerFactory::getInstance().registerAllocator(
         "default", [](Mesh & mesh, const ID & id,
                       const MemoryID & mem_id) -> std::unique_ptr<DOFManager> {
           return std::make_unique<DOFManagerDefault>(mesh, id, mem_id);
         });
 } // namespace akantu
diff --git a/src/model/dof_manager_default.hh b/src/model/dof_manager_default.hh
index 8acd160f9..e8efa3b50 100644
--- a/src/model/dof_manager_default.hh
+++ b/src/model/dof_manager_default.hh
@@ -1,360 +1,361 @@
 /**
  * @file   dof_manager_default.hh
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
- * @date   Tue Aug 11 14:06:18 2015
+ * @date creation: Tue Aug 18 2015
+ * @date last modification: Wed Jan 31 2018
  *
  * @brief  Default implementation of the dof manager
  *
  * @section LICENSE
  *
- * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * Copyright (©) 2015-2018 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
- * terms  of the  GNU Lesser  General Public  License as  published by  the Free
+ * 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
+ * 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 "dof_manager.hh"
 /* -------------------------------------------------------------------------- */
 #include <functional>
 #include <unordered_map>
 /* -------------------------------------------------------------------------- */
 
 #ifndef __AKANTU_DOF_MANAGER_DEFAULT_HH__
 #define __AKANTU_DOF_MANAGER_DEFAULT_HH__
 
 namespace akantu {
 class SparseMatrixAIJ;
 class NonLinearSolverDefault;
 class TimeStepSolverDefault;
 class DOFSynchronizer;
 } // namespace akantu
 
 namespace akantu {
 
 class DOFManagerDefault : public DOFManager {
   /* ------------------------------------------------------------------------ */
   /* Constructors/Destructors                                                 */
   /* ------------------------------------------------------------------------ */
 public:
   DOFManagerDefault(const ID & id = "dof_manager_default",
                     const MemoryID & memory_id = 0);
   DOFManagerDefault(Mesh & mesh, const ID & id = "dof_manager_default",
                     const MemoryID & memory_id = 0);
   ~DOFManagerDefault() override;
 
 protected:
   struct DOFDataDefault : public DOFData {
     explicit DOFDataDefault(const ID & dof_id);
 
     /// associated node for _dst_nodal dofs only
     Array<UInt> associated_nodes;
   };
 
   /* ------------------------------------------------------------------------ */
   /* Methods                                                                  */
   /* ------------------------------------------------------------------------ */
 private:
   void registerDOFsInternal(const ID & dof_id, UInt nb_dofs,
                             UInt nb_pure_local_dofs);
 
 public:
   /// register an array of degree of freedom
   void registerDOFs(const ID & dof_id, Array<Real> & dofs_array,
                     const DOFSupportType & support_type) override;
 
   /// the dof as an implied type of _dst_nodal and is defined only on a subset
   /// of nodes
   void registerDOFs(const ID & dof_id, Array<Real> & dofs_array,
                     const ID & group_support) override;
 
   /// Assemble an array to the global residual array
   void assembleToResidual(const ID & dof_id,
                           const Array<Real> & array_to_assemble,
                           Real scale_factor = 1.) override;
 
   /// Assemble an array to the global lumped matrix array
   void assembleToLumpedMatrix(const ID & dof_id,
                               const Array<Real> & array_to_assemble,
                               const ID & lumped_mtx,
                               Real scale_factor = 1.) override;
   /**
    * Assemble elementary values to the global matrix. The dof number is
    * implicitly considered as conn(el, n) * nb_nodes_per_element + d.
    * With 0 < n < nb_nodes_per_element and 0 < d < nb_dof_per_node
    **/
   void assembleElementalMatricesToMatrix(
       const ID & matrix_id, const ID & dof_id,
       const Array<Real> & elementary_mat, const ElementType & type,
       const GhostType & ghost_type, const MatrixType & elemental_matrix_type,
       const Array<UInt> & filter_elements) override;
 
   /// multiply a vector by a matrix and assemble the result to the residual
   void assembleMatMulVectToResidual(const ID & dof_id, const ID & A_id,
                                     const Array<Real> & x,
                                     Real scale_factor = 1) override;
 
   /// multiply a vector by a lumped matrix and assemble the result to the
   /// residual
   void assembleLumpedMatMulVectToResidual(const ID & dof_id, const ID & A_id,
                                           const Array<Real> & x,
                                           Real scale_factor = 1) override;
 
   /// assemble coupling terms between to dofs
   void assemblePreassembledMatrix(const ID & dof_id_m, const ID & dof_id_n,
                                   const ID & matrix_id,
                                   const TermsToAssemble & terms) override;
 
 protected:
   /// Assemble an array to the global residual array
   template <typename T>
   void assembleToGlobalArray(const ID & dof_id,
                              const Array<T> & array_to_assemble,
                              Array<T> & global_array, T scale_factor);
 
 public:
   /// clear the residual
   void clearResidual() override;
 
   /// sets the matrix to 0
   void clearMatrix(const ID & mtx) override;
 
   /// sets the lumped matrix to 0
   void clearLumpedMatrix(const ID & mtx) override;
 
   /// update the global dofs vector
   virtual void updateGlobalBlockedDofs();
 
   /// apply boundary conditions to jacobian matrix
   virtual void applyBoundary(const ID & matrix_id = "J");
 
   // void getEquationsNumbers(const ID & dof_id,
   //                          Array<UInt> & equation_numbers) override;
 
 protected:
   /// Get local part of an array corresponding to a given dofdata
   template <typename T>
   void getArrayPerDOFs(const ID & dof_id, const Array<T> & global_array,
                        Array<T> & local_array) const;
 
   /// Get the part of the solution corresponding to the dof_id
   void getSolutionPerDOFs(const ID & dof_id,
                           Array<Real> & solution_array) override;
 
   /// fill a Vector with the equation numbers corresponding to the given
   /// connectivity
   inline void extractElementEquationNumber(
       const Array<UInt> & equation_numbers, const Vector<UInt> & connectivity,
       UInt nb_degree_of_freedom, Vector<UInt> & local_equation_number);
 
 public:
   /// extract a lumped matrix part corresponding to a given dof
   void getLumpedMatrixPerDOFs(const ID & dof_id, const ID & lumped_mtx,
                               Array<Real> & lumped) override;
 
 private:
   /// Add a symmetric matrices to a symmetric sparse matrix
   void addSymmetricElementalMatrixToSymmetric(
       SparseMatrixAIJ & matrix, const Matrix<Real> & element_mat,
       const Vector<UInt> & equation_numbers, UInt max_size);
 
   /// Add a unsymmetric matrices to a symmetric sparse matrix (i.e. cohesive
   /// elements)
   void addUnsymmetricElementalMatrixToSymmetric(
       SparseMatrixAIJ & matrix, const Matrix<Real> & element_mat,
       const Vector<UInt> & equation_numbers, UInt max_size);
 
   /// Add a matrices to a unsymmetric sparse matrix
   void addElementalMatrixToUnsymmetric(SparseMatrixAIJ & matrix,
                                        const Matrix<Real> & element_mat,
                                        const Vector<UInt> & equation_numbers,
                                        UInt max_size);
 
   void addToProfile(const ID & matrix_id, const ID & dof_id,
                     const ElementType & type, const GhostType & ghost_type);
 
   /* ------------------------------------------------------------------------ */
   /* MeshEventHandler interface                                               */
   /* ------------------------------------------------------------------------ */
 protected:
   std::pair<UInt, UInt>
   updateNodalDOFs(const ID & dof_id, const Array<UInt> & nodes_list) override;
 
 private:
   void updateDOFsData(DOFDataDefault & dof_data, UInt nb_new_local_dofs,
                       UInt nb_new_pure_local,
                       const std::function<UInt(UInt)> & getNode);
 
 public:
   /// function to implement to react on  akantu::NewNodesEvent
   void onNodesAdded(const Array<UInt> & nodes_list,
                     const NewNodesEvent & event) override;
 
   /* ------------------------------------------------------------------------ */
   /* Accessors                                                                */
   /* ------------------------------------------------------------------------ */
 public:
   /// Get an instance of a new SparseMatrix
   SparseMatrix & getNewMatrix(const ID & matrix_id,
                               const MatrixType & matrix_type) override;
 
   /// Get an instance of a new SparseMatrix as a copy of the SparseMatrix
   /// matrix_to_copy_id
   SparseMatrix & getNewMatrix(const ID & matrix_id,
                               const ID & matrix_to_copy_id) override;
 
   /// Get the reference of an existing matrix
   SparseMatrixAIJ & getMatrix(const ID & matrix_id);
 
   /* ------------------------------------------------------------------------ */
   /* Non Linear Solver                                                        */
   /* ------------------------------------------------------------------------ */
   /// Get instance of a non linear solver
   NonLinearSolver & getNewNonLinearSolver(
       const ID & nls_solver_id,
       const NonLinearSolverType & _non_linear_solver_type) override;
 
   /* ------------------------------------------------------------------------ */
   /* Time-Step Solver                                                         */
   /* ------------------------------------------------------------------------ */
   /// Get instance of a time step solver
   TimeStepSolver &
   getNewTimeStepSolver(const ID & id, const TimeStepSolverType & type,
                        NonLinearSolver & non_linear_solver) override;
 
   /* ------------------------------------------------------------------------ */
   /// Get the solution array
   AKANTU_GET_MACRO_NOT_CONST(GlobalSolution, global_solution, Array<Real> &);
   /// Set the global solution array
   void setGlobalSolution(const Array<Real> & solution);
 
   /// Get the global residual array across processors (SMP call)
   const Array<Real> & getGlobalResidual();
 
   /// Get the residual array
   const Array<Real> & getResidual() const;
 
   /// Get the blocked dofs array
   AKANTU_GET_MACRO(GlobalBlockedDOFs, global_blocked_dofs, const Array<bool> &);
   /// Get the blocked dofs array
   AKANTU_GET_MACRO(PreviousGlobalBlockedDOFs, previous_global_blocked_dofs,
                    const Array<bool> &);
   /// Get the location type of a given dof
   inline bool isLocalOrMasterDOF(UInt local_dof_num);
 
   /// Answer to the question is a dof a slave dof ?
   inline bool isSlaveDOF(UInt local_dof_num);
 
   /// get the equation numbers (in local numbering) corresponding to a dof ID
   inline const Array<UInt> & getLocalEquationNumbers(const ID & dof_id) const;
 
   /// tells if the dof manager knows about a global dof
   bool hasGlobalEquationNumber(UInt global) const;
 
   /// return the local index of the global equation number
   inline UInt globalToLocalEquationNumber(UInt global) const;
 
   /// converts local equation numbers to global equation numbers;
   inline UInt localToGlobalEquationNumber(UInt local) const;
 
   /// get the array of dof types (use only if you know what you do...)
   inline Int getDOFType(UInt local_id) const;
 
   /// get the array of dof types (use only if you know what you do...)
   inline const Array<UInt> & getDOFsAssociatedNodes(const ID & dof_id) const;
 
   /// access the internal dof_synchronizer
   AKANTU_GET_MACRO_NOT_CONST(Synchronizer, *synchronizer, DOFSynchronizer &);
 
   /// access the internal dof_synchronizer
   bool hasSynchronizer() const { return synchronizer != nullptr; }
 
 protected:
   DOFData & getNewDOFData(const ID & dof_id) override;
 
   /* ------------------------------------------------------------------------ */
   /* Class Members                                                            */
   /* ------------------------------------------------------------------------ */
 protected:
   // using AIJMatrixMap = std::map<ID, std::unique_ptr<SparseMatrixAIJ>>;
   // using DefaultNonLinearSolversMap =
   //     std::map<ID, std::unique_ptr<NonLinearSolverDefault>>;
   // using DefaultTimeStepSolversMap =
   //     std::map<ID, std::unique_ptr<TimeStepSolverDefault>>;
 
   using DOFToMatrixProfile =
       std::map<std::pair<ID, ID>,
                std::vector<std::pair<ElementType, GhostType>>>;
 
   /// contains the the dofs that where added to the profile of a given matrix.
   DOFToMatrixProfile matrix_profiled_dofs;
 
   /// rhs to the system of equation corresponding to the residual linked to the
   /// different dofs
   Array<Real> residual;
 
   /// rhs used only on root proc in case of parallel computing, this is the full
   /// gathered rhs array
   std::unique_ptr<Array<Real>> global_residual;
 
   /// solution of the system of equation corresponding to the different dofs
   Array<Real> global_solution;
 
   /// blocked degree of freedom in the system equation corresponding to the
   /// different dofs
   Array<bool> global_blocked_dofs;
 
   /// blocked degree of freedom in the system equation corresponding to the
   /// different dofs
   Array<bool> previous_global_blocked_dofs;
 
   /// define the dofs type, local, shared, ghost
   Array<Int> dofs_type;
 
   /// Map of the different matrices stored in the dof manager
   // AIJMatrixMap aij_matrices;
 
   /// Map of the different time step solvers stored with there real type
   // DefaultTimeStepSolversMap default_time_step_solver_map;
 
   /// Memory cache, this is an array to keep the temporary memory needed for
   /// some operations, it is meant to be resized or cleared when needed
   Array<Real> data_cache;
 
   /// Release at last apply boundary on jacobian
   UInt jacobian_release{0};
 
   /// equation number in global numbering
   Array<UInt> global_equation_number;
 
   using equation_numbers_map = std::unordered_map<UInt, UInt>;
 
   /// dual information of global_equation_number
   equation_numbers_map global_to_local_mapping;
 
   /// accumulator to know what would be the next global id to use
   UInt first_global_dof_id{0};
 
   /// synchronizer to maintain coherency in dof fields
   std::unique_ptr<DOFSynchronizer> synchronizer;
 };
 
 } // namespace akantu
 
 #include "dof_manager_default_inline_impl.cc"
 
 #endif /* __AKANTU_DOF_MANAGER_DEFAULT_HH__ */
diff --git a/src/model/dof_manager_default_inline_impl.cc b/src/model/dof_manager_default_inline_impl.cc
index 1dc37020f..26b764a7c 100644
--- a/src/model/dof_manager_default_inline_impl.cc
+++ b/src/model/dof_manager_default_inline_impl.cc
@@ -1,104 +1,105 @@
 /**
  * @file   dof_manager_default_inline_impl.cc
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
- * @date   Wed Aug 12 10:57:47 2015
+ * @date creation: Tue Aug 18 2015
+ * @date last modification: Wed Jan 31 2018
  *
  * @brief  Implementation of the DOFManagerDefault inline functions
  *
  * @section LICENSE
  *
- * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * Copyright (©) 2015-2018 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
- * terms  of the  GNU Lesser  General Public  License as  published by  the Free
+ * 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
+ * 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 "dof_manager_default.hh"
 /* -------------------------------------------------------------------------- */
 
 #ifndef __AKANTU_DOF_MANAGER_DEFAULT_INLINE_IMPL_CC__
 #define __AKANTU_DOF_MANAGER_DEFAULT_INLINE_IMPL_CC__
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 inline bool DOFManagerDefault::isLocalOrMasterDOF(UInt dof_num) {
   Int dof_type = this->dofs_type(dof_num);
   return (dof_type == Int(_nt_normal)) || (dof_type == Int(_nt_master));
 }
 
 /* -------------------------------------------------------------------------- */
 inline bool DOFManagerDefault::isSlaveDOF(UInt dof_num) {
   Int dof_type = this->dofs_type(dof_num);
   return (dof_type >= 0);
 }
 
 /* -------------------------------------------------------------------------- */
 inline const Array<UInt> &
 DOFManagerDefault::getLocalEquationNumbers(const ID & dof_id) const {
   return this->getDOFData(dof_id).local_equation_number;
 }
 
 inline const Array<UInt> &
 DOFManagerDefault::getDOFsAssociatedNodes(const ID & dof_id) const {
   const auto & dof_data = this->getDOFDataTyped<DOFDataDefault>(dof_id);
   return dof_data.associated_nodes;
 }
 /* -------------------------------------------------------------------------- */
 inline void DOFManagerDefault::extractElementEquationNumber(
     const Array<UInt> & equation_numbers, const Vector<UInt> & connectivity,
     UInt nb_degree_of_freedom, Vector<UInt> & element_equation_number) {
   for (UInt i = 0, ld = 0; i < connectivity.size(); ++i) {
     UInt n = connectivity(i);
     for (UInt d = 0; d < nb_degree_of_freedom; ++d, ++ld) {
       element_equation_number(ld) =
           equation_numbers(n * nb_degree_of_freedom + d);
     }
   }
 }
 
 /* -------------------------------------------------------------------------- */
 inline UInt DOFManagerDefault::localToGlobalEquationNumber(UInt local) const {
   return this->global_equation_number(local);
 }
 
 /* -------------------------------------------------------------------------- */
 inline bool DOFManagerDefault::hasGlobalEquationNumber(UInt global) const {
   auto it = this->global_to_local_mapping.find(global);
   return (it != this->global_to_local_mapping.end());
 }
 
 /* -------------------------------------------------------------------------- */
 inline UInt DOFManagerDefault::globalToLocalEquationNumber(UInt global) const {
   auto it = this->global_to_local_mapping.find(global);
   AKANTU_DEBUG_ASSERT(it != this->global_to_local_mapping.end(),
                       "This global equation number "
                           << global << " does not exists in " << this->id);
 
   return it->second;
 }
 
 /* -------------------------------------------------------------------------- */
 inline Int DOFManagerDefault::getDOFType(UInt local_id) const {
   return this->dofs_type(local_id);
 }
 /* -------------------------------------------------------------------------- */
 
 } // akantu
 
 #endif /* __AKANTU_DOF_MANAGER_DEFAULT_INLINE_IMPL_CC_ */
diff --git a/src/model/dof_manager_inline_impl.cc b/src/model/dof_manager_inline_impl.cc
index 0be0ecd85..71ebf49fd 100644
--- a/src/model/dof_manager_inline_impl.cc
+++ b/src/model/dof_manager_inline_impl.cc
@@ -1,153 +1,154 @@
 /**
  * @file   dof_manager_inline_impl.cc
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
- * @date   Wed Aug 12 11:07:01 2015
+ * @date creation: Thu Feb 21 2013
+ * @date last modification: Wed Jan 31 2018
  *
- * @brief
+ * @brief  inline functions of the dof manager
  *
  * @section LICENSE
  *
- * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * 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
+ * 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
+ * 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 "dof_manager.hh"
 /* -------------------------------------------------------------------------- */
 
 #ifndef __AKANTU_DOF_MANAGER_INLINE_IMPL_CC__
 #define __AKANTU_DOF_MANAGER_INLINE_IMPL_CC__
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 inline bool DOFManager::hasDOFs(const ID & dof_id) const {
   auto it = this->dofs.find(dof_id);
   return it != this->dofs.end();
 }
 
 /* -------------------------------------------------------------------------- */
 inline DOFManager::DOFData & DOFManager::getDOFData(const ID & dof_id) {
   auto it = this->dofs.find(dof_id);
   if (it == this->dofs.end()) {
     AKANTU_EXCEPTION("The dof " << dof_id << " does not exists in "
                                 << this->id);
   }
   return *it->second;
 }
 
 /* -------------------------------------------------------------------------- */
 const DOFManager::DOFData & DOFManager::getDOFData(const ID & dof_id) const {
   auto it = this->dofs.find(dof_id);
   if (it == this->dofs.end()) {
     AKANTU_EXCEPTION("The dof " << dof_id << " does not exists in "
                                 << this->id);
   }
   return *it->second;
 }
 
 /* -------------------------------------------------------------------------- */
 const Array<UInt> & DOFManager::getEquationsNumbers(const ID & dof_id) const {
   return getDOFData(dof_id).local_equation_number;
 }
 
 /* -------------------------------------------------------------------------- */
 template <class _DOFData>
 inline _DOFData & DOFManager::getDOFDataTyped(const ID & dof_id) {
   return dynamic_cast<_DOFData &>(this->getDOFData(dof_id));
 }
 
 /* -------------------------------------------------------------------------- */
 template <class _DOFData>
 inline const _DOFData & DOFManager::getDOFDataTyped(const ID & dof_id) const {
   return dynamic_cast<const _DOFData &>(this->getDOFData(dof_id));
 }
 
 /* -------------------------------------------------------------------------- */
 inline Array<Real> & DOFManager::getDOFs(const ID & dofs_id) {
   return *(this->getDOFData(dofs_id).dof);
 }
 
 /* -------------------------------------------------------------------------- */
 inline DOFSupportType DOFManager::getSupportType(const ID & dofs_id) const {
   return this->getDOFData(dofs_id).support_type;
 }
 
 /* -------------------------------------------------------------------------- */
 inline Array<Real> & DOFManager::getPreviousDOFs(const ID & dofs_id) {
   return *(this->getDOFData(dofs_id).previous);
 }
 
 /* -------------------------------------------------------------------------- */
 inline bool DOFManager::hasPreviousDOFs(const ID & dofs_id) const {
   return (this->getDOFData(dofs_id).previous != nullptr);
 }
 
 /* -------------------------------------------------------------------------- */
 inline Array<Real> & DOFManager::getDOFsIncrement(const ID & dofs_id) {
   return *(this->getDOFData(dofs_id).increment);
 }
 
 /* -------------------------------------------------------------------------- */
 inline bool DOFManager::hasDOFsIncrement(const ID & dofs_id) const {
   return (this->getDOFData(dofs_id).increment != nullptr);
 }
 
 /* -------------------------------------------------------------------------- */
 inline Array<Real> & DOFManager::getDOFsDerivatives(const ID & dofs_id,
                                                     UInt order) {
   std::vector<Array<Real> *> & derivatives =
       this->getDOFData(dofs_id).dof_derivatives;
   if ((order > derivatives.size()) || (derivatives[order - 1] == nullptr))
     AKANTU_EXCEPTION("No derivatives of order " << order << " present in "
                                                 << this->id << " for dof "
                                                 << dofs_id);
 
   return *derivatives[order - 1];
 }
 
 /* -------------------------------------------------------------------------- */
 inline bool DOFManager::hasDOFsDerivatives(const ID & dofs_id,
                                            UInt order) const {
   const std::vector<Array<Real> *> & derivatives =
       this->getDOFData(dofs_id).dof_derivatives;
   return ((order < derivatives.size()) && (derivatives[order - 1] != nullptr));
 }
 
 /* -------------------------------------------------------------------------- */
 inline const Array<Real> & DOFManager::getSolution(const ID & dofs_id) const {
   return this->getDOFData(dofs_id).solution;
 }
 
 /* -------------------------------------------------------------------------- */
 inline const Array<bool> &
 DOFManager::getBlockedDOFs(const ID & dofs_id) const {
   return *(this->getDOFData(dofs_id).blocked_dofs);
 }
 
 /* -------------------------------------------------------------------------- */
 inline bool DOFManager::hasBlockedDOFs(const ID & dofs_id) const {
   return (this->getDOFData(dofs_id).blocked_dofs != nullptr);
 }
 
 /* -------------------------------------------------------------------------- */
 
 } // akantu
 
 #endif /* __AKANTU_DOF_MANAGER_INLINE_IMPL_CC__ */
diff --git a/src/model/dof_manager_petsc.cc b/src/model/dof_manager_petsc.cc
index 0c168640d..2f8f332d4 100644
--- a/src/model/dof_manager_petsc.cc
+++ b/src/model/dof_manager_petsc.cc
@@ -1,395 +1,396 @@
 /**
  * @file   dof_manager_petsc.cc
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
- * @date   Mon Oct  5 21:19:58 2015
+ * @date creation: Wed Oct 07 2015
+ * @date last modification: Tue Feb 20 2018
  *
  * @brief  DOFManaterPETSc is the PETSc implementation of the DOFManager
  *
  * @section LICENSE
  *
- * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * Copyright (©) 2015-2018 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
- * terms  of the  GNU Lesser  General Public  License as  published by  the Free
+ * 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
+ * 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 "dof_manager_petsc.hh"
 
 #include "cppargparse.hh"
 
 #if defined(AKANTU_USE_MPI)
 #include "mpi_type_wrapper.hh"
 #include "static_communicator.hh"
 #endif
 /* -------------------------------------------------------------------------- */
 #include <petscsys.h>
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 
 #if not defined(PETSC_CLANGUAGE_CXX)
 /// small hack to use the c binding of petsc when the cxx binding does notation
 /// exists
 int aka_PETScError(int ierr) {
   CHKERRQ(ierr);
   return 0;
 }
 #endif
 
 UInt DOFManagerPETSc::petsc_dof_manager_instances = 0;
 
 /// Error handler to make PETSc errors caught by Akantu
 #if PETSC_VERSION_MAJOR >= 3 && PETSC_VERSION_MINOR >= 5
 static PetscErrorCode PETScErrorHandler(MPI_Comm, int line, const char * dir,
                                         const char * file,
                                         PetscErrorCode number,
                                         PetscErrorType type,
                                         const char * message, void *) {
   AKANTU_ERROR("An error occured in PETSc in file \""
                << file << ":" << line << "\" - PetscErrorCode " << number
                << " - \"" << message << "\"");
 }
 #else
 static PetscErrorCode PETScErrorHandler(MPI_Comm, int line, const char * func,
                                         const char * dir, const char * file,
                                         PetscErrorCode number,
                                         PetscErrorType type,
                                         const char * message, void *) {
   AKANTU_ERROR("An error occured in PETSc in file \""
                << file << ":" << line << "\" - PetscErrorCode " << number
                << " - \"" << message << "\"");
 }
 #endif
 
 /* -------------------------------------------------------------------------- */
 DOFManagerPETSc::DOFManagerPETSc(const ID & id, const MemoryID & memory_id)
     : DOFManager(id, memory_id) {
 
 // check if the akantu types and PETSc one are consistant
 #if __cplusplus > 199711L
   static_assert(sizeof(Int) == sizeof(PetscInt),
                 "The integer type of Akantu does not match the one from PETSc");
   static_assert(sizeof(Real) == sizeof(PetscReal),
                 "The integer type of Akantu does not match the one from PETSc");
 #else
   AKANTU_DEBUG_ASSERT(
       sizeof(Int) == sizeof(PetscInt),
       "The integer type of Akantu does not match the one from PETSc");
   AKANTU_DEBUG_ASSERT(
       sizeof(Real) == sizeof(PetscReal),
       "The integer type of Akantu does not match the one from PETSc");
 #endif
 
   if (this->petsc_dof_manager_instances == 0) {
 #if defined(AKANTU_USE_MPI)
     StaticCommunicator & comm = StaticCommunicator::getStaticCommunicator();
     const StaticCommunicatorMPI & mpi_st_comm =
         dynamic_cast<const StaticCommunicatorMPI &>(
             comm.getRealStaticCommunicator());
 
     this->mpi_communicator =
         mpi_st_comm.getMPITypeWrapper().getMPICommunicator();
 #else
     this->mpi_communicator = PETSC_COMM_SELF;
 #endif
 
     cppargparse::ArgumentParser & argparser = getStaticArgumentParser();
     int & argc = argparser.getArgC();
     char **& argv = argparser.getArgV();
 
     PetscErrorCode petsc_error = PetscInitialize(&argc, &argv, NULL, NULL);
 
     if (petsc_error != 0) {
       AKANTU_ERROR("An error occured while initializing Petsc (PetscErrorCode "
                    << petsc_error << ")");
     }
 
     PetscPushErrorHandler(PETScErrorHandler, NULL);
     this->petsc_dof_manager_instances++;
   }
 
   VecCreate(PETSC_COMM_WORLD, &this->residual);
   VecCreate(PETSC_COMM_WORLD, &this->solution);
 }
 
 /* -------------------------------------------------------------------------- */
 DOFManagerPETSc::~DOFManagerPETSc() {
   PetscErrorCode ierr;
   ierr = VecDestroy(&(this->residual));
   CHKERRXX(ierr);
 
   ierr = VecDestroy(&(this->solution));
   CHKERRXX(ierr);
 
   this->petsc_dof_manager_instances--;
   if (this->petsc_dof_manager_instances == 0) {
     PetscFinalize();
   }
 }
 
 /* -------------------------------------------------------------------------- */
 void DOFManagerPETSc::registerDOFs(const ID & dof_id, Array<Real> & dofs_array,
                                    DOFSupportType & support_type) {
   DOFManager::registerDOFs(dof_id, dofs_array, support_type);
 
   PetscErrorCode ierr;
 
   PetscInt current_size;
   ierr = VecGetSize(this->residual, &current_size);
   CHKERRXX(ierr);
 
   if (current_size == 0) { // first time vector is set
     PetscInt local_size = this->pure_local_system_size;
     ierr = VecSetSizes(this->residual, local_size, PETSC_DECIDE);
     CHKERRXX(ierr);
 
     ierr = VecSetFromOptions(this->residual);
     CHKERRXX(ierr);
 
 #ifndef AKANTU_NDEBUG
     PetscInt global_size;
     ierr = VecGetSize(this->residual, &global_size);
     CHKERRXX(ierr);
     AKANTU_DEBUG_ASSERT(this->system_size == UInt(global_size),
                         "The local value of the system size does not match the "
                         "one determined by PETSc");
 #endif
     PetscInt start_dof, end_dof;
     VecGetOwnershipRange(this->residual, &start_dof, &end_dof);
 
     PetscInt * global_indices = new PetscInt[local_size];
     global_indices[0] = start_dof;
 
     for (PetscInt d = 0; d < local_size; d++)
       global_indices[d + 1] = global_indices[d] + 1;
 
 // To be change if we switch to a block definition
 #if PETSC_VERSION_MAJOR >= 3 && PETSC_VERSION_MINOR >= 5
     ISLocalToGlobalMappingCreate(this->communicator, 1, local_size,
                                  global_indices, PETSC_COPY_VALUES,
                                  &this->is_ltog);
 
 #else
     ISLocalToGlobalMappingCreate(this->communicator, local_size, global_indices,
                                  PETSC_COPY_VALUES, &this->is_ltog);
 #endif
 
     VecSetLocalToGlobalMapping(this->residual, this->is_ltog);
     delete[] global_indices;
 
     ierr = VecDuplicate(this->residual, &this->solution);
     CHKERRXX(ierr);
 
   } else { // this is an update of the object already created
     AKANTU_TO_IMPLEMENT();
   }
 
   /// set the solution to zero
   // ierr = VecZeroEntries(this->solution);
   // CHKERRXX(ierr);
 }
 
 /* -------------------------------------------------------------------------- */
 /**
  * This function creates the non-zero pattern of the PETSc matrix. In
  * PETSc the parallel matrix is partitioned across processors such
  * that the first m0 rows belong to process 0, the next m1 rows belong
  * to process 1, the next m2 rows belong to process 2 etc.. where
  * m0,m1,m2,.. are the input parameter 'm'. i.e each processor stores
  * values corresponding to [m x N] submatrix
  * (http://www.mcs.anl.gov/petsc/).
  * @param mesh mesh discretizing the domain we want to analyze
  * @param dof_synchronizer dof synchronizer that maps the local
  * dofs to the global dofs and the equation numbers, i.e., the
  * position at which the dof is assembled in the matrix
  */
 
 // void SparseMatrixPETSc::buildProfile(const Mesh & mesh,
 //                                      const DOFSynchronizer &
 //                                      dof_synchronizer,
 //                                      UInt nb_degree_of_freedom) {
 //   AKANTU_DEBUG_IN();
 
 //   // clearProfile();
 //   this->dof_synchronizer = &const_cast<DOFSynchronizer &>(dof_synchronizer);
 //   this->setSize();
 //   PetscErrorCode ierr;
 
 //   /// resize arrays to store the number of nonzeros in each row
 //   this->d_nnz.resize(this->local_size);
 //   this->o_nnz.resize(this->local_size);
 
 //   /// set arrays to zero everywhere
 //   this->d_nnz.set(0);
 //   this->o_nnz.set(0);
 
 //   // if(irn_jcn_to_k) delete irn_jcn_to_k;
 //   // irn_jcn_to_k = new std::map<std::pair<UInt, UInt>, UInt>;
 
 //   coordinate_list_map::iterator irn_jcn_k_it;
 
 //   Int * eq_nb_val = dof_synchronizer.getGlobalDOFEquationNumbers().storage();
 //   UInt nb_global_dofs = dof_synchronizer.getNbGlobalDOFs();
 //   Array<Int> index_pair(2);
 
 //   /// Loop over all the ghost types
 //   for (ghost_type_t::iterator gt = ghost_type_t::begin();
 //        gt != ghost_type_t::end(); ++gt) {
 //     const GhostType & ghost_type = *gt;
 //     Mesh::type_iterator it =
 //         mesh.firstType(mesh.getSpatialDimension(), ghost_type,
 //         _ek_not_defined);
 //     Mesh::type_iterator end =
 //         mesh.lastType(mesh.getSpatialDimension(), ghost_type,
 //         _ek_not_defined);
 //     for (; it != end; ++it) {
 //       UInt nb_element = mesh.getNbElement(*it, ghost_type);
 //       UInt nb_nodes_per_element = Mesh::getNbNodesPerElement(*it);
 //       UInt size_mat = nb_nodes_per_element * nb_degree_of_freedom;
 
 //       UInt * conn_val = mesh.getConnectivity(*it, ghost_type).storage();
 //       Int * local_eq_nb_val =
 //           new Int[nb_degree_of_freedom * nb_nodes_per_element];
 
 //       for (UInt e = 0; e < nb_element; ++e) {
 //         Int * tmp_local_eq_nb_val = local_eq_nb_val;
 //         for (UInt i = 0; i < nb_nodes_per_element; ++i) {
 //           UInt n = conn_val[i];
 //           for (UInt d = 0; d < nb_degree_of_freedom; ++d) {
 //             /**
 //              * !!!!!!Careful!!!!!! This is a ugly fix. @todo this is a
 //              * very ugly fix, because the offset for the global
 //              * equation number, where the dof will be assembled, is
 //              * hardcoded. In the future a class dof manager has to be
 //              * added to Akantu to handle the mapping between the dofs
 //              * and the equation numbers
 //              *
 //              */
 
 //             *tmp_local_eq_nb_val++ =
 //                 eq_nb_val[n * nb_degree_of_freedom + d] -
 //                 (dof_synchronizer.isPureGhostDOF(n * nb_degree_of_freedom +
 //                 d)
 //                      ? nb_global_dofs
 //                      : 0);
 //           }
 //         }
 
 //         for (UInt i = 0; i < size_mat; ++i) {
 //           Int c_irn = local_eq_nb_val[i];
 //           UInt j_start = 0;
 //           for (UInt j = j_start; j < size_mat; ++j) {
 //             Int c_jcn = local_eq_nb_val[j];
 //             index_pair(0) = c_irn;
 //             index_pair(1) = c_jcn;
 //             AOApplicationToPetsc(this->petsc_matrix_wrapper->ao, 2,
 //                                  index_pair.storage());
 //             if (index_pair(0) >= first_global_index &&
 //                 index_pair(0) < first_global_index + this->local_size) {
 //               KeyCOO irn_jcn = keyPETSc(c_irn, c_jcn);
 //               irn_jcn_k_it = irn_jcn_k.find(irn_jcn);
 
 //               if (irn_jcn_k_it == irn_jcn_k.end()) {
 //                 irn_jcn_k[irn_jcn] = nb_non_zero;
 
 //                 // check if node is slave node
 //                 if (index_pair(1) >= first_global_index &&
 //                     index_pair(1) < first_global_index + this->local_size)
 //                   this->d_nnz(index_pair(0) - first_global_index) += 1;
 //                 else
 //                   this->o_nnz(index_pair(0) - first_global_index) += 1;
 //                 nb_non_zero++;
 //               }
 //             }
 //           }
 //         }
 //         conn_val += nb_nodes_per_element;
 //       }
 
 //       delete[] local_eq_nb_val;
 //     }
 //   }
 
 //   // /// for pbc @todo correct it for parallel
 //   // if(StaticCommunicator::getStaticCommunicator().getNbProc() == 1) {
 //   //   for (UInt i = 0; i < size; ++i) {
 //   //    KeyCOO irn_jcn = key(i, i);
 //   //    irn_jcn_k_it = irn_jcn_k.find(irn_jcn);
 //   //    if(irn_jcn_k_it == irn_jcn_k.end()) {
 //   //      irn_jcn_k[irn_jcn] = nb_non_zero;
 //   //      irn.push_back(i + 1);
 //   //      jcn.push_back(i + 1);
 //   //      nb_non_zero++;
 //   //    }
 //   //   }
 //   // }
 
 //   // std::string mat_type;
 //   // mat_type.resize(20, 'a');
 //   // std::cout << "MatType: " << mat_type << std::endl;
 //   // const char * mat_type_ptr = mat_type.c_str();
 //   MatType type;
 //   MatGetType(this->petsc_matrix_wrapper->mat, &type);
 //   /// std::cout << "the matrix type is: " << type << std::endl;
 //   /**
 //    * PETSc will use only one of the following preallocation commands
 //    * depending on the matrix type and ignore the rest. Note that for
 //    * the block matrix format a block size of 1 is used. This might
 //    * result in bad performance. @todo For better results implement
 //    * buildProfile() with larger block size.
 //    *
 //    */
 //   /// build profile:
 //   if (strcmp(type, MATSEQAIJ) == 0) {
 //     ierr = MatSeqAIJSetPreallocation(this->petsc_matrix_wrapper->mat, 0,
 //                                      d_nnz.storage());
 //     CHKERRXX(ierr);
 //   } else if ((strcmp(type, MATMPIAIJ) == 0)) {
 //     ierr = MatMPIAIJSetPreallocation(this->petsc_matrix_wrapper->mat, 0,
 //                                      d_nnz.storage(), 0, o_nnz.storage());
 //     CHKERRXX(ierr);
 //   } else {
 //     AKANTU_ERROR("The type " << type
 //                                    << " of PETSc matrix is not handled by"
 //                                    << " akantu in the preallocation step");
 //   }
 
 //   // ierr =  MatSeqSBAIJSetPreallocation(this->petsc_matrix_wrapper->mat, 1,
 //   //                                  0, d_nnz.storage()); CHKERRXX(ierr);
 
 //   if (this->sparse_matrix_type == _symmetric) {
 //     /// set flag for symmetry to enable ICC/Cholesky preconditioner
 //     ierr = MatSetOption(this->petsc_matrix_wrapper->mat, MAT_SYMMETRIC,
 //                         PETSC_TRUE);
 //     CHKERRXX(ierr);
 //     /// set flag for symmetric positive definite
 //     ierr = MatSetOption(this->petsc_matrix_wrapper->mat, MAT_SPD,
 //     PETSC_TRUE);
 //     CHKERRXX(ierr);
 //   }
 //   /// once the profile has been build ignore any new nonzero locations
 //   ierr = MatSetOption(this->petsc_matrix_wrapper->mat,
 //                       MAT_NEW_NONZERO_LOCATIONS, PETSC_TRUE);
 //   CHKERRXX(ierr);
 
 //   AKANTU_DEBUG_OUT();
 // }
 
 /* -------------------------------------------------------------------------- */
 
 } // akantu
diff --git a/src/model/dof_manager_petsc.hh b/src/model/dof_manager_petsc.hh
index e994d5c73..8e199a964 100644
--- a/src/model/dof_manager_petsc.hh
+++ b/src/model/dof_manager_petsc.hh
@@ -1,173 +1,174 @@
 /**
  * @file   dof_manager_petsc.hh
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
- * @date   Tue Aug 11 14:06:18 2015
+ * @date creation: Tue Aug 18 2015
+ * @date last modification: Wed Jan 31 2018
  *
  * @brief  PETSc implementation of the dof manager
  *
  * @section LICENSE
  *
- * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * Copyright (©) 2015-2018 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
- * terms  of the  GNU Lesser  General Public  License as  published by  the Free
+ * 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
+ * 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 "dof_manager.hh"
 /* -------------------------------------------------------------------------- */
 #include <petscis.h>
 #include <petscvec.h>
 /* -------------------------------------------------------------------------- */
 
 #if not defined(PETSC_CLANGUAGE_CXX)
 extern int aka_PETScError(int ierr);
 
 #define CHKERRXX(x)                                                            \
   do {                                                                         \
     int error = aka_PETScError(x);                                             \
     if (error != 0) {                                                          \
       AKANTU_EXCEPTION("Error in PETSC");                                      \
     }                                                                          \
   } while (0)
 #endif
 
 #ifndef __AKANTU_DOF_MANAGER_PETSC_HH__
 #define __AKANTU_DOF_MANAGER_PETSC_HH__
 
 namespace akantu {
 
 class SparseMatrixPETSc;
 
 class DOFManagerPETSc : public DOFManager {
   /* ------------------------------------------------------------------------ */
   /* Constructors/Destructors                                                 */
   /* ------------------------------------------------------------------------ */
 public:
   DOFManagerPETSc(const ID & id = "dof_manager_petsc",
                   const MemoryID & memory_id = 0);
   DOFManagerPETSc(Mesh & mesh, const ID & id = "dof_manager_petsc",
                   const MemoryID & memory_id = 0);
 
   virtual ~DOFManagerPETSc();
 
   /* ------------------------------------------------------------------------ */
   /* Methods                                                                  */
   /* ------------------------------------------------------------------------ */
 public:
   /// register an array of degree of freedom
   void registerDOFs(const ID & dof_id, Array<Real> & dofs_array,
                     DOFSupportType & support_type);
 
   /// Assemble an array to the global residual array
   virtual void assembleToResidual(const ID & dof_id,
                                   const Array<Real> & array_to_assemble,
                                   Real scale_factor = 1.);
 
   /**
    * Assemble elementary values to the global residual array. The dof number is
    * implicitly considered as conn(el, n) * nb_nodes_per_element + d.
    * With 0 < n < nb_nodes_per_element and 0 < d < nb_dof_per_node
    **/
   virtual void assembleElementalArrayResidual(
       const ID & dof_id, const Array<Real> & array_to_assemble,
       const ElementType & type, const GhostType & ghost_type,
       Real scale_factor = 1.);
   /**
    * Assemble elementary values to the global residual array. The dof number is
    * implicitly considered as conn(el, n) * nb_nodes_per_element + d.
    * With 0 < n < nb_nodes_per_element and 0 < d < nb_dof_per_node
    **/
   virtual void assembleElementalMatricesToMatrix(
       const ID & matrix_id, const ID & dof_id,
       const Array<Real> & elementary_mat, const ElementType & type,
       const GhostType & ghost_type, const MatrixType & elemental_matrix_type,
       const Array<UInt> & filter_elements);
 
 protected:
   /// Get the part of the solution corresponding to the dof_id
   virtual void getSolutionPerDOFs(const ID & dof_id,
                                   Array<Real> & solution_array);
 
 private:
   /// Add a symmetric matrices to a symmetric sparse matrix
   inline void addSymmetricElementalMatrixToSymmetric(
       SparseMatrixAIJ & matrix, const Matrix<Real> & element_mat,
       const Vector<UInt> & equation_numbers, UInt max_size);
 
   /// Add a unsymmetric matrices to a symmetric sparse matrix (i.e. cohesive
   /// elements)
   inline void addUnsymmetricElementalMatrixToSymmetric(
       SparseMatrixAIJ & matrix, const Matrix<Real> & element_mat,
       const Vector<UInt> & equation_numbers, UInt max_size);
 
   /// Add a matrices to a unsymmetric sparse matrix
   inline void addElementalMatrixToUnsymmetric(
       SparseMatrixAIJ & matrix, const Matrix<Real> & element_mat,
       const Vector<UInt> & equation_numbers, UInt max_size);
 
   /* ------------------------------------------------------------------------ */
   /* Accessors                                                                */
   /* ------------------------------------------------------------------------ */
 public:
   /// Get an instance of a new SparseMatrix
   virtual SparseMatrix & getNewMatrix(const ID & matrix_id,
                                       const MatrixType & matrix_type);
 
   /// Get an instance of a new SparseMatrix as a copy of the SparseMatrix
   /// matrix_to_copy_id
   virtual SparseMatrix & getNewMatrix(const ID & matrix_id,
                                       const ID & matrix_to_copy_id);
 
   /// Get the reference of an existing matrix
   SparseMatrixPETSc & getMatrix(const ID & matrix_id);
 
   /// Get the solution array
   AKANTU_GET_MACRO_NOT_CONST(GlobalSolution, this->solution, Vec &);
   /// Get the residual array
   AKANTU_GET_MACRO_NOT_CONST(Residual, this->residual, Vec &);
   /// Get the blocked dofs array
   //  AKANTU_GET_MACRO(BlockedDOFs, blocked_dofs, const Array<bool> &);
 
   /* ------------------------------------------------------------------------ */
   /* Class Members                                                            */
   /* ------------------------------------------------------------------------ */
 private:
   typedef std::map<ID, SparseMatrixPETSc *> PETScMatrixMap;
 
   /// list of matrices registered to the dof manager
   PETScMatrixMap petsc_matrices;
 
   /// PETSc version of the solution
   Vec solution;
 
   /// PETSc version of the residual
   Vec residual;
 
   /// PETSc local to global mapping of dofs
   ISLocalToGlobalMapping is_ltog;
 
   /// Communicator associated to PETSc
   MPI_Comm mpi_communicator;
 
   /// Static handler for petsc to know if it was initialized or not
   static UInt petsc_dof_manager_instances;
 };
 
 } // akantu
 
 #endif /* __AKANTU_DOF_MANAGER_PETSC_HH__ */
diff --git a/src/model/heat_transfer/heat_transfer_model.cc b/src/model/heat_transfer/heat_transfer_model.cc
index 031214f49..4cd6ef3ad 100644
--- a/src/model/heat_transfer/heat_transfer_model.cc
+++ b/src/model/heat_transfer/heat_transfer_model.cc
@@ -1,958 +1,958 @@
 /**
  * @file   heat_transfer_model.cc
  *
  * @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
  * @author Lucas Frerot <lucas.frerot@epfl.ch>
+ * @author Emil Gallyamov <emil.gallyamov@epfl.ch>
  * @author David Simon Kammer <david.kammer@epfl.ch>
  * @author Srinivasa Babu Ramisetti <srinivasa.ramisetti@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  * @author Rui Wang <rui.wang@epfl.ch>
  *
  * @date creation: Sun May 01 2011
- * @date last modification: Mon Nov 30 2015
+ * @date last modification: Tue Feb 20 2018
  *
  * @brief  Implementation of HeatTransferModel class
  *
  * @section LICENSE
  *
- * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
- * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
- * Solides)
+ * 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
+ * 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
+ * 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 "heat_transfer_model.hh"
 #include "dumpable_inline_impl.hh"
 #include "element_synchronizer.hh"
 #include "fe_engine_template.hh"
 #include "generalized_trapezoidal.hh"
 #include "group_manager_inline_impl.cc"
 #include "integrator_gauss.hh"
 #include "mesh.hh"
 #include "parser.hh"
 #include "shape_lagrange.hh"
 
 #ifdef AKANTU_USE_IOHELPER
 #include "dumper_element_partition.hh"
 #include "dumper_elemental_field.hh"
 #include "dumper_internal_material_field.hh"
 #include "dumper_iohelper_paraview.hh"
 #endif
 
 /* -------------------------------------------------------------------------- */
 namespace akantu {
 
 namespace heat_transfer {
   namespace details {
     class ComputeRhoFunctor {
     public:
       ComputeRhoFunctor(const HeatTransferModel & model) : model(model){};
 
       void operator()(Matrix<Real> & rho, const Element &) const {
         rho.set(model.getCapacity());
       }
 
     private:
       const HeatTransferModel & model;
     };
   }
 }
 
 /* -------------------------------------------------------------------------- */
 HeatTransferModel::HeatTransferModel(Mesh & mesh, UInt dim, const ID & id,
                                      const MemoryID & memory_id)
     : Model(mesh, ModelType::_heat_transfer_model, dim, id, memory_id),
       temperature_gradient("temperature_gradient", id),
       temperature_on_qpoints("temperature_on_qpoints", id),
       conductivity_on_qpoints("conductivity_on_qpoints", id),
       k_gradt_on_qpoints("k_gradt_on_qpoints", id) {
   AKANTU_DEBUG_IN();
 
   conductivity = Matrix<Real>(this->spatial_dimension, this->spatial_dimension);
 
   this->initDOFManager();
 
   this->registerDataAccessor(*this);
 
   if (this->mesh.isDistributed()) {
     auto & synchronizer = this->mesh.getElementSynchronizer();
     this->registerSynchronizer(synchronizer, _gst_htm_capacity);
     this->registerSynchronizer(synchronizer, _gst_htm_temperature);
     this->registerSynchronizer(synchronizer, _gst_htm_gradient_temperature);
   }
 
   registerFEEngineObject<FEEngineType>(id + ":fem", mesh, spatial_dimension);
 
 #ifdef AKANTU_USE_IOHELPER
   this->mesh.registerDumper<DumperParaview>("heat_transfer", id, true);
   this->mesh.addDumpMesh(mesh, spatial_dimension, _not_ghost, _ek_regular);
 #endif
 
   this->registerParam("conductivity", conductivity, _pat_parsmod);
   this->registerParam("conductivity_variation", conductivity_variation, 0.,
                       _pat_parsmod);
   this->registerParam("temperature_reference", T_ref, 0., _pat_parsmod);
   this->registerParam("capacity", capacity, _pat_parsmod);
   this->registerParam("density", density, _pat_parsmod);
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void HeatTransferModel::initModel() {
   auto & fem = this->getFEEngine();
   fem.initShapeFunctions(_not_ghost);
   fem.initShapeFunctions(_ghost);
 
   temperature_on_qpoints.initialize(fem, _nb_component = 1);
   temperature_gradient.initialize(fem, _nb_component = spatial_dimension);
   conductivity_on_qpoints.initialize(
       fem, _nb_component = spatial_dimension * spatial_dimension);
   k_gradt_on_qpoints.initialize(fem, _nb_component = spatial_dimension);
 }
 
 /* -------------------------------------------------------------------------- */
 FEEngine & HeatTransferModel::getFEEngineBoundary(const ID & name) {
   return dynamic_cast<FEEngine &>(getFEEngineClassBoundary<FEEngineType>(name));
 }
 
 /* -------------------------------------------------------------------------- */
 template <typename T>
 void HeatTransferModel::allocNodalField(Array<T> *& array, const ID & name) {
   if (array == nullptr) {
     UInt nb_nodes = mesh.getNbNodes();
     std::stringstream sstr_disp;
     sstr_disp << id << ":" << name;
 
     array = &(alloc<T>(sstr_disp.str(), nb_nodes, 1, T()));
   }
 }
 
 /* -------------------------------------------------------------------------- */
 HeatTransferModel::~HeatTransferModel() = default;
 
 /* -------------------------------------------------------------------------- */
 void HeatTransferModel::assembleCapacityLumped(const GhostType & ghost_type) {
   AKANTU_DEBUG_IN();
 
   auto & fem = getFEEngineClass<FEEngineType>();
   heat_transfer::details::ComputeRhoFunctor compute_rho(*this);
 
   for (auto & type : mesh.elementTypes(spatial_dimension, ghost_type)) {
     fem.assembleFieldLumped(compute_rho, "M", "temperature",
                             this->getDOFManager(), type, ghost_type);
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 MatrixType HeatTransferModel::getMatrixType(const ID & matrix_id) {
   if (matrix_id == "K" or matrix_id == "M") {
     return _symmetric;
   }
 
   return _mt_not_defined;
 }
 
 /* -------------------------------------------------------------------------- */
 void HeatTransferModel::assembleMatrix(const ID & matrix_id) {
   if (matrix_id == "K") {
     this->assembleConductivityMatrix();
   } else if (matrix_id == "M") {
     this->assembleCapacity();
   } else {
     AKANTU_TO_IMPLEMENT();
   }
 }
 
 /* -------------------------------------------------------------------------- */
 void HeatTransferModel::assembleLumpedMatrix(const ID & matrix_id) {
   if (matrix_id == "M") {
     this->assembleCapacityLumped();
   } else {
     AKANTU_TO_IMPLEMENT();
   }
 }
 
 /* -------------------------------------------------------------------------- */
 void HeatTransferModel::assembleResidual() {
   AKANTU_DEBUG_IN();
 
   this->assembleInternalHeatRate();
 
   this->getDOFManager().assembleToResidual("temperature",
                                            *this->external_heat_rate, 1);
   this->getDOFManager().assembleToResidual("temperature",
                                            *this->internal_heat_rate, 1);
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void HeatTransferModel::predictor() { ++temperature_release; }
 
 /* -------------------------------------------------------------------------- */
 void HeatTransferModel::assembleCapacityLumped() {
   AKANTU_DEBUG_IN();
 
   if (!this->getDOFManager().hasLumpedMatrix("M")) {
     this->getDOFManager().getNewLumpedMatrix("M");
   }
 
   this->getDOFManager().clearLumpedMatrix("M");
 
   assembleCapacityLumped(_not_ghost);
   assembleCapacityLumped(_ghost);
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void HeatTransferModel::initSolver(TimeStepSolverType time_step_solver_type,
                                    NonLinearSolverType) {
   DOFManager & dof_manager = this->getDOFManager();
 
   this->allocNodalField(this->temperature, "temperature");
   this->allocNodalField(this->external_heat_rate, "external_heat_rate");
   this->allocNodalField(this->internal_heat_rate, "internal_heat_rate");
   this->allocNodalField(this->blocked_dofs, "blocked_dofs");
 
   if (!dof_manager.hasDOFs("temperature")) {
     dof_manager.registerDOFs("temperature", *this->temperature, _dst_nodal);
     dof_manager.registerBlockedDOFs("temperature", *this->blocked_dofs);
   }
 
   if (time_step_solver_type == _tsst_dynamic ||
       time_step_solver_type == _tsst_dynamic_lumped) {
     this->allocNodalField(this->temperature_rate, "temperature_rate");
 
     if (!dof_manager.hasDOFsDerivatives("temperature", 1)) {
       dof_manager.registerDOFsDerivative("temperature", 1,
                                          *this->temperature_rate);
     }
   }
 }
 
 /* -------------------------------------------------------------------------- */
 std::tuple<ID, TimeStepSolverType>
 HeatTransferModel::getDefaultSolverID(const AnalysisMethod & method) {
   switch (method) {
   case _explicit_lumped_mass: {
     return std::make_tuple("explicit_lumped", _tsst_dynamic_lumped);
   }
   case _static: {
     return std::make_tuple("static", _tsst_static);
   }
   case _implicit_dynamic: {
     return std::make_tuple("implicit", _tsst_dynamic);
   }
   default:
     return std::make_tuple("unknown", _tsst_not_defined);
   }
 }
 
 /* -------------------------------------------------------------------------- */
 ModelSolverOptions HeatTransferModel::getDefaultSolverOptions(
     const TimeStepSolverType & type) const {
   ModelSolverOptions options;
 
   switch (type) {
   case _tsst_dynamic_lumped: {
     options.non_linear_solver_type = _nls_lumped;
     options.integration_scheme_type["temperature"] = _ist_forward_euler;
     options.solution_type["temperature"] = IntegrationScheme::_temperature_rate;
     break;
   }
   case _tsst_static: {
     options.non_linear_solver_type = _nls_newton_raphson;
     options.integration_scheme_type["temperature"] = _ist_pseudo_time;
     options.solution_type["temperature"] = IntegrationScheme::_not_defined;
     break;
   }
   case _tsst_dynamic: {
     if (this->method == _explicit_consistent_mass) {
       options.non_linear_solver_type = _nls_newton_raphson;
       options.integration_scheme_type["temperature"] = _ist_forward_euler;
       options.solution_type["temperature"] =
           IntegrationScheme::_temperature_rate;
     } else {
       options.non_linear_solver_type = _nls_newton_raphson;
       options.integration_scheme_type["temperature"] = _ist_trapezoidal_rule_1;
       options.solution_type["temperature"] = IntegrationScheme::_temperature;
     }
     break;
   }
   default:
     AKANTU_EXCEPTION(type << " is not a valid time step solver type");
   }
 
   return options;
 }
 
 /* -------------------------------------------------------------------------- */
 void HeatTransferModel::assembleConductivityMatrix() {
   AKANTU_DEBUG_IN();
 
   this->computeConductivityOnQuadPoints(_not_ghost);
   if (conductivity_release[_not_ghost] == conductivity_matrix_release)
     return;
 
   if (!this->getDOFManager().hasMatrix("K")) {
     this->getDOFManager().getNewMatrix("K", getMatrixType("K"));
   }
   this->getDOFManager().clearMatrix("K");
 
   switch (mesh.getSpatialDimension()) {
   case 1:
     this->assembleConductivityMatrix<1>(_not_ghost);
     break;
   case 2:
     this->assembleConductivityMatrix<2>(_not_ghost);
     break;
   case 3:
     this->assembleConductivityMatrix<3>(_not_ghost);
     break;
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <UInt dim>
 void HeatTransferModel::assembleConductivityMatrix(
     const GhostType & ghost_type) {
   AKANTU_DEBUG_IN();
 
   auto & fem = this->getFEEngine();
 
   for (auto && type : mesh.elementTypes(spatial_dimension, ghost_type)) {
     auto nb_element = mesh.getNbElement(type, ghost_type);
     auto nb_nodes_per_element = Mesh::getNbNodesPerElement(type);
     auto nb_quadrature_points = fem.getNbIntegrationPoints(type, ghost_type);
 
     auto bt_d_b = std::make_unique<Array<Real>>(
         nb_element * nb_quadrature_points,
         nb_nodes_per_element * nb_nodes_per_element, "B^t*D*B");
 
     fem.computeBtDB(conductivity_on_qpoints(type, ghost_type), *bt_d_b, 2, type,
                     ghost_type);
 
     /// compute @f$ k_e = \int_e \mathbf{B}^t * \mathbf{D} * \mathbf{B}@f$
     auto K_e = std::make_unique<Array<Real>>(
         nb_element, nb_nodes_per_element * nb_nodes_per_element, "K_e");
 
     fem.integrate(*bt_d_b, *K_e, nb_nodes_per_element * nb_nodes_per_element,
                   type, ghost_type);
 
     this->getDOFManager().assembleElementalMatricesToMatrix(
         "K", "temperature", *K_e, type, ghost_type, _symmetric);
   }
 
   conductivity_matrix_release = conductivity_release[ghost_type];
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void HeatTransferModel::computeConductivityOnQuadPoints(
     const GhostType & ghost_type) {
   // if already computed once check if need to compute
   if (not initial_conductivity[ghost_type]) {
     // if temperature did not change, condictivity will not vary
     if (temperature_release == conductivity_release[ghost_type])
       return;
 
     // if conductivity_variation is 0 no need to recompute
     if (conductivity_variation == 0.)
       return;
   }
 
   for (auto & type : mesh.elementTypes(spatial_dimension, ghost_type)) {
     auto & temperature_interpolated = temperature_on_qpoints(type, ghost_type);
 
     // compute the temperature on quadrature points
     this->getFEEngine().interpolateOnIntegrationPoints(
         *temperature, temperature_interpolated, 1, type, ghost_type);
 
     auto & cond = conductivity_on_qpoints(type, ghost_type);
     for (auto && tuple :
          zip(make_view(cond, spatial_dimension, spatial_dimension),
              temperature_interpolated)) {
       auto & C = std::get<0>(tuple);
       auto & T = std::get<1>(tuple);
       C = conductivity;
 
       Matrix<Real> variation(spatial_dimension, spatial_dimension,
                              conductivity_variation * (T - T_ref));
       // @TODO: Guillaume are you sure ? why due you compute variation then ?
       C += conductivity_variation;
     }
   }
 
   conductivity_release[ghost_type] = temperature_release;
   initial_conductivity[ghost_type] = false;
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void HeatTransferModel::computeKgradT(const GhostType & ghost_type) {
   computeConductivityOnQuadPoints(ghost_type);
 
   for (auto & type : mesh.elementTypes(spatial_dimension, ghost_type)) {
     auto & gradient = temperature_gradient(type, ghost_type);
     this->getFEEngine().gradientOnIntegrationPoints(*temperature, gradient, 1,
                                                     type, ghost_type);
 
     for (auto && values :
          zip(make_view(conductivity_on_qpoints(type, ghost_type),
                        spatial_dimension, spatial_dimension),
              make_view(gradient, spatial_dimension),
              make_view(k_gradt_on_qpoints(type, ghost_type),
                        spatial_dimension))) {
       const auto & C = std::get<0>(values);
       const auto & BT = std::get<1>(values);
       auto & k_BT = std::get<2>(values);
 
       k_BT.mul<false>(C, BT);
     }
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void HeatTransferModel::assembleInternalHeatRate() {
   AKANTU_DEBUG_IN();
 
   this->internal_heat_rate->clear();
 
   this->synchronize(_gst_htm_temperature);
   auto & fem = this->getFEEngine();
 
   for (auto ghost_type : ghost_types) {
     // compute k \grad T
     computeKgradT(ghost_type);
 
     for (auto type : mesh.elementTypes(spatial_dimension, ghost_type)) {
       UInt nb_nodes_per_element = Mesh::getNbNodesPerElement(type);
 
       auto & k_gradt_on_qpoints_vect = k_gradt_on_qpoints(type, ghost_type);
 
       UInt nb_quad_points = k_gradt_on_qpoints_vect.size();
       Array<Real> bt_k_gT(nb_quad_points, nb_nodes_per_element);
       fem.computeBtD(k_gradt_on_qpoints_vect, bt_k_gT, type, ghost_type);
 
       UInt nb_elements = mesh.getNbElement(type, ghost_type);
       Array<Real> int_bt_k_gT(nb_elements, nb_nodes_per_element);
 
       fem.integrate(bt_k_gT, int_bt_k_gT, nb_nodes_per_element, type,
                     ghost_type);
 
       this->getDOFManager().assembleElementalArrayLocalArray(
           int_bt_k_gT, *this->internal_heat_rate, type, ghost_type, -1);
     }
   }
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 Real HeatTransferModel::getStableTimeStep() {
   AKANTU_DEBUG_IN();
 
   Real el_size;
   Real min_el_size = std::numeric_limits<Real>::max();
   Real conductivitymax = conductivity(0, 0);
 
   // get the biggest parameter from k11 until k33//
   for (UInt i = 0; i < spatial_dimension; i++)
     for (UInt j = 0; j < spatial_dimension; j++)
       conductivitymax = std::max(conductivity(i, j), conductivitymax);
 
   for (auto & type : mesh.elementTypes(spatial_dimension, _not_ghost)) {
 
     UInt nb_nodes_per_element = mesh.getNbNodesPerElement(type);
 
     Array<Real> coord(0, nb_nodes_per_element * spatial_dimension);
     FEEngine::extractNodalToElementField(mesh, mesh.getNodes(), coord, type,
                                          _not_ghost);
 
     auto el_coord = coord.begin(spatial_dimension, nb_nodes_per_element);
     UInt nb_element = mesh.getNbElement(type);
 
     for (UInt el = 0; el < nb_element; ++el, ++el_coord) {
       el_size = getFEEngine().getElementInradius(*el_coord, type);
       min_el_size = std::min(min_el_size, el_size);
     }
 
     AKANTU_DEBUG_INFO("The minimum element size : "
                       << min_el_size
                       << " and the max conductivity is : " << conductivitymax);
   }
 
   Real min_dt =
       2 * min_el_size * min_el_size * density * capacity / conductivitymax;
 
   mesh.getCommunicator().allReduce(min_dt, SynchronizerOperation::_min);
 
   AKANTU_DEBUG_OUT();
 
   return min_dt;
 }
 
 /* -------------------------------------------------------------------------- */
 void HeatTransferModel::readMaterials() {
   auto sect = this->getParserSection();
 
   if (not std::get<1>(sect)) {
     const auto & section = std::get<0>(sect);
     this->parseSection(section);
   }
 
   conductivity_on_qpoints.set(conductivity);
 }
 
 /* -------------------------------------------------------------------------- */
 void HeatTransferModel::initFullImpl(const ModelOptions & options) {
   Model::initFullImpl(options);
 
   readMaterials();
 }
 
 /* -------------------------------------------------------------------------- */
 void HeatTransferModel::assembleCapacity() {
   AKANTU_DEBUG_IN();
   auto ghost_type = _not_ghost;
 
   auto & fem = getFEEngineClass<FEEngineType>();
 
   heat_transfer::details::ComputeRhoFunctor rho_functor(*this);
 
   for (auto && type : mesh.elementTypes(spatial_dimension, ghost_type)) {
     fem.assembleFieldMatrix(rho_functor, "M", "temperature",
                             this->getDOFManager(), type, ghost_type);
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void HeatTransferModel::computeRho(Array<Real> & rho, ElementType type,
                                    GhostType ghost_type) {
   AKANTU_DEBUG_IN();
 
   FEEngine & fem = this->getFEEngine();
   UInt nb_element = mesh.getNbElement(type, ghost_type);
   UInt nb_quadrature_points = fem.getNbIntegrationPoints(type, ghost_type);
 
   rho.resize(nb_element * nb_quadrature_points);
   rho.set(this->capacity);
 
   // Real * rho_1_val = rho.storage();
   // /// compute @f$ rho @f$ for each nodes of each element
   // for (UInt el = 0; el < nb_element; ++el) {
   //   for (UInt n = 0; n < nb_quadrature_points; ++n) {
   //     *rho_1_val++ = this->capacity;
   //   }
   // }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 Real HeatTransferModel::computeThermalEnergyByNode() {
   AKANTU_DEBUG_IN();
 
   Real ethermal = 0.;
 
   for (auto && pair : enumerate(make_view(
            *internal_heat_rate, internal_heat_rate->getNbComponent()))) {
     auto n = std::get<0>(pair);
     auto & heat_rate = std::get<1>(pair);
 
     Real heat = 0.;
     bool is_local_node = mesh.isLocalOrMasterNode(n);
     bool is_not_pbc_slave_node = !isPBCSlaveNode(n);
     bool count_node = is_local_node && is_not_pbc_slave_node;
 
     for (UInt i = 0; i < heat_rate.size(); ++i) {
       if (count_node)
         heat += heat_rate[i] * time_step;
     }
     ethermal += heat;
   }
 
   mesh.getCommunicator().allReduce(ethermal, SynchronizerOperation::_sum);
 
   AKANTU_DEBUG_OUT();
   return ethermal;
 }
 
 /* -------------------------------------------------------------------------- */
 template <class iterator>
 void HeatTransferModel::getThermalEnergy(
     iterator Eth, Array<Real>::const_iterator<Real> T_it,
     Array<Real>::const_iterator<Real> T_end) const {
   for (; T_it != T_end; ++T_it, ++Eth) {
     *Eth = capacity * density * *T_it;
   }
 }
 
 /* -------------------------------------------------------------------------- */
 Real HeatTransferModel::getThermalEnergy(const ElementType & type, UInt index) {
   AKANTU_DEBUG_IN();
 
   UInt nb_quadrature_points = getFEEngine().getNbIntegrationPoints(type);
   Vector<Real> Eth_on_quarature_points(nb_quadrature_points);
 
   auto T_it = this->temperature_on_qpoints(type).begin();
   T_it += index * nb_quadrature_points;
 
   auto T_end = T_it + nb_quadrature_points;
 
   getThermalEnergy(Eth_on_quarature_points.storage(), T_it, T_end);
 
   return getFEEngine().integrate(Eth_on_quarature_points, type, index);
 }
 
 /* -------------------------------------------------------------------------- */
 Real HeatTransferModel::getThermalEnergy() {
   Real Eth = 0;
 
   auto & fem = getFEEngine();
 
   for (auto && type : mesh.elementTypes(spatial_dimension)) {
     auto nb_element = mesh.getNbElement(type, _not_ghost);
     auto nb_quadrature_points = fem.getNbIntegrationPoints(type, _not_ghost);
     Array<Real> Eth_per_quad(nb_element * nb_quadrature_points, 1);
 
     auto & temperature_interpolated = temperature_on_qpoints(type);
 
     // compute the temperature on quadrature points
     this->getFEEngine().interpolateOnIntegrationPoints(
         *temperature, temperature_interpolated, 1, type);
 
     auto T_it = temperature_interpolated.begin();
     auto T_end = temperature_interpolated.end();
     getThermalEnergy(Eth_per_quad.begin(), T_it, T_end);
 
     Eth += fem.integrate(Eth_per_quad, type);
   }
 
   return Eth;
 }
 
 /* -------------------------------------------------------------------------- */
 Real HeatTransferModel::getEnergy(const std::string & id) {
   AKANTU_DEBUG_IN();
   Real energy = 0;
 
   if (id == "thermal")
     energy = getThermalEnergy();
 
   // reduction sum over all processors
   mesh.getCommunicator().allReduce(energy, SynchronizerOperation::_sum);
 
   AKANTU_DEBUG_OUT();
   return energy;
 }
 
 /* -------------------------------------------------------------------------- */
 Real HeatTransferModel::getEnergy(const std::string & id,
                                   const ElementType & type, UInt index) {
   AKANTU_DEBUG_IN();
 
   Real energy = 0.;
 
   if (id == "thermal")
     energy = getThermalEnergy(type, index);
 
   AKANTU_DEBUG_OUT();
   return energy;
 }
 
 /* -------------------------------------------------------------------------- */
 /* -------------------------------------------------------------------------- */
 #ifdef AKANTU_USE_IOHELPER
 
 dumper::Field * HeatTransferModel::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;
 
   dumper::Field * field = nullptr;
   field = mesh.createNodalField(uint_nodal_fields[field_name], group_name);
   return field;
 }
 
 /* -------------------------------------------------------------------------- */
 dumper::Field * HeatTransferModel::createNodalFieldReal(
     const std::string & field_name, const std::string & group_name,
     __attribute__((unused)) bool padding_flag) {
 
   std::map<std::string, Array<Real> *> real_nodal_fields;
   real_nodal_fields["temperature"] = temperature;
   real_nodal_fields["temperature_rate"] = temperature_rate;
   real_nodal_fields["external_heat_rate"] = external_heat_rate;
   real_nodal_fields["internal_heat_rate"] = internal_heat_rate;
   real_nodal_fields["capacity_lumped"] = capacity_lumped;
   real_nodal_fields["increment"] = increment;
 
   dumper::Field * field =
       mesh.createNodalField(real_nodal_fields[field_name], group_name);
 
   return field;
 }
 
 /* -------------------------------------------------------------------------- */
 dumper::Field * HeatTransferModel::createElementalField(
     const std::string & field_name, const std::string & group_name,
     __attribute__((unused)) bool padding_flag,
     __attribute__((unused)) const UInt & spatial_dimension,
     const ElementKind & element_kind) {
 
   dumper::Field * field = nullptr;
 
   if (field_name == "partitions")
     field = mesh.createElementalField<UInt, dumper::ElementPartitionField>(
         mesh.getConnectivities(), group_name, this->spatial_dimension,
         element_kind);
   else if (field_name == "temperature_gradient") {
     ElementTypeMap<UInt> nb_data_per_elem =
         this->mesh.getNbDataPerElem(temperature_gradient, element_kind);
 
     field = mesh.createElementalField<Real, dumper::InternalMaterialField>(
         temperature_gradient, group_name, this->spatial_dimension, element_kind,
         nb_data_per_elem);
   } else if (field_name == "conductivity") {
     ElementTypeMap<UInt> nb_data_per_elem =
         this->mesh.getNbDataPerElem(conductivity_on_qpoints, element_kind);
 
     field = mesh.createElementalField<Real, dumper::InternalMaterialField>(
         conductivity_on_qpoints, group_name, this->spatial_dimension,
         element_kind, nb_data_per_elem);
   }
 
   return field;
 }
 
 /* -------------------------------------------------------------------------- */
 #else
 /* -------------------------------------------------------------------------- */
 dumper::Field * HeatTransferModel::createElementalField(
     __attribute__((unused)) const std::string & field_name,
     __attribute__((unused)) const std::string & group_name,
     __attribute__((unused)) bool padding_flag,
     __attribute__((unused)) const ElementKind & element_kind) {
   return nullptr;
 }
 
 /* -------------------------------------------------------------------------- */
 dumper::Field * HeatTransferModel::createNodalFieldBool(
     __attribute__((unused)) const std::string & field_name,
     __attribute__((unused)) const std::string & group_name,
     __attribute__((unused)) bool padding_flag) {
   return nullptr;
 }
 
 /* -------------------------------------------------------------------------- */
 dumper::Field * HeatTransferModel::createNodalFieldReal(
     __attribute__((unused)) const std::string & field_name,
     __attribute__((unused)) const std::string & group_name,
     __attribute__((unused)) bool padding_flag) {
   return nullptr;
 }
 #endif
 
 /* -------------------------------------------------------------------------- */
 void HeatTransferModel::dump(const std::string & dumper_name) {
   mesh.dump(dumper_name);
 }
 
 /* -------------------------------------------------------------------------- */
 void HeatTransferModel::dump(const std::string & dumper_name, UInt step) {
   mesh.dump(dumper_name, step);
 }
 
 /* ------------------------------------------------------------------------- */
 void HeatTransferModel::dump(const std::string & dumper_name, Real time,
                              UInt step) {
   mesh.dump(dumper_name, time, step);
 }
 
 /* -------------------------------------------------------------------------- */
 void HeatTransferModel::dump() { mesh.dump(); }
 
 /* -------------------------------------------------------------------------- */
 void HeatTransferModel::dump(UInt step) { mesh.dump(step); }
 
 /* -------------------------------------------------------------------------- */
 void HeatTransferModel::dump(Real time, UInt step) { mesh.dump(time, step); }
 
 /* -------------------------------------------------------------------------- */
 inline UInt HeatTransferModel::getNbData(const Array<UInt> & indexes,
                                          const SynchronizationTag & tag) const {
   AKANTU_DEBUG_IN();
 
   UInt size = 0;
   UInt nb_nodes = indexes.size();
 
   switch (tag) {
   case _gst_htm_capacity:
   case _gst_htm_temperature: {
     size += nb_nodes * sizeof(Real);
     break;
   }
   default: { AKANTU_ERROR("Unknown ghost synchronization tag : " << tag); }
   }
 
   AKANTU_DEBUG_OUT();
   return size;
 }
 
 /* -------------------------------------------------------------------------- */
 inline void HeatTransferModel::packData(CommunicationBuffer & buffer,
                                         const Array<UInt> & indexes,
                                         const SynchronizationTag & tag) const {
   AKANTU_DEBUG_IN();
 
   for (auto index : indexes) {
     switch (tag) {
     case _gst_htm_capacity:
       buffer << (*capacity_lumped)(index);
       break;
     case _gst_htm_temperature: {
       buffer << (*temperature)(index);
       break;
     }
     default: { AKANTU_ERROR("Unknown ghost synchronization tag : " << tag); }
     }
   }
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 inline void HeatTransferModel::unpackData(CommunicationBuffer & buffer,
                                           const Array<UInt> & indexes,
                                           const SynchronizationTag & tag) {
   AKANTU_DEBUG_IN();
 
   for (auto index : indexes) {
     switch (tag) {
     case _gst_htm_capacity: {
       buffer >> (*capacity_lumped)(index);
       break;
     }
     case _gst_htm_temperature: {
       buffer >> (*temperature)(index);
       break;
     }
     default: { AKANTU_ERROR("Unknown ghost synchronization tag : " << tag); }
     }
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 inline UInt HeatTransferModel::getNbData(const Array<Element> & elements,
                                          const SynchronizationTag & tag) const {
   AKANTU_DEBUG_IN();
 
   UInt size = 0;
   UInt nb_nodes_per_element = 0;
   Array<Element>::const_iterator<Element> it = elements.begin();
   Array<Element>::const_iterator<Element> end = elements.end();
   for (; it != end; ++it) {
     const Element & el = *it;
     nb_nodes_per_element += Mesh::getNbNodesPerElement(el.type);
   }
 
   switch (tag) {
   case _gst_htm_capacity: {
     size += nb_nodes_per_element * sizeof(Real); // capacity vector
     break;
   }
   case _gst_htm_temperature: {
     size += nb_nodes_per_element * sizeof(Real); // temperature
     break;
   }
   case _gst_htm_gradient_temperature: {
     // temperature gradient
     size += getNbIntegrationPoints(elements) * spatial_dimension * sizeof(Real);
     size += nb_nodes_per_element * sizeof(Real); // nodal temperatures
     break;
   }
   default: { AKANTU_ERROR("Unknown ghost synchronization tag : " << tag); }
   }
 
   AKANTU_DEBUG_OUT();
   return size;
 }
 
 /* -------------------------------------------------------------------------- */
 inline void HeatTransferModel::packData(CommunicationBuffer & buffer,
                                         const Array<Element> & elements,
                                         const SynchronizationTag & tag) const {
   switch (tag) {
   case _gst_htm_capacity: {
     packNodalDataHelper(*capacity_lumped, buffer, elements, mesh);
     break;
   }
   case _gst_htm_temperature: {
     packNodalDataHelper(*temperature, buffer, elements, mesh);
     break;
   }
   case _gst_htm_gradient_temperature: {
     packElementalDataHelper(temperature_gradient, buffer, elements, true,
                             getFEEngine());
     packNodalDataHelper(*temperature, buffer, elements, mesh);
     break;
   }
   default: { AKANTU_ERROR("Unknown ghost synchronization tag : " << tag); }
   }
 }
 
 /* -------------------------------------------------------------------------- */
 inline void HeatTransferModel::unpackData(CommunicationBuffer & buffer,
                                           const Array<Element> & elements,
                                           const SynchronizationTag & tag) {
   switch (tag) {
   case _gst_htm_capacity: {
     unpackNodalDataHelper(*capacity_lumped, buffer, elements, mesh);
     break;
   }
   case _gst_htm_temperature: {
     unpackNodalDataHelper(*temperature, buffer, elements, mesh);
     break;
   }
   case _gst_htm_gradient_temperature: {
     unpackElementalDataHelper(temperature_gradient, buffer, elements, true,
                               getFEEngine());
     unpackNodalDataHelper(*temperature, buffer, elements, mesh);
 
     break;
   }
   default: { AKANTU_ERROR("Unknown ghost synchronization tag : " << tag); }
   }
 }
 
 /* -------------------------------------------------------------------------- */
 } // akantu
diff --git a/src/model/heat_transfer/heat_transfer_model.hh b/src/model/heat_transfer/heat_transfer_model.hh
index 723f6bf2b..1e50f36df 100644
--- a/src/model/heat_transfer/heat_transfer_model.hh
+++ b/src/model/heat_transfer/heat_transfer_model.hh
@@ -1,337 +1,337 @@
 /**
  * @file   heat_transfer_model.hh
  *
  * @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
  * @author Lucas Frerot <lucas.frerot@epfl.ch>
  * @author Srinivasa Babu Ramisetti <srinivasa.ramisetti@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  * @author Rui Wang <rui.wang@epfl.ch>
  *
  * @date creation: Sun May 01 2011
- * @date last modification: Tue Dec 08 2015
+ * @date last modification: Mon Feb 05 2018
  *
  * @brief  Model of Heat Transfer
  *
  * @section LICENSE
  *
- * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
- * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
- * Solides)
+ * 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
+ * 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
+ * A PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
+
 /* -------------------------------------------------------------------------- */
 #include "data_accessor.hh"
 #include "fe_engine.hh"
 #include "model.hh"
 /* -------------------------------------------------------------------------- */
 #include <array>
 /* -------------------------------------------------------------------------- */
 
 #ifndef __AKANTU_HEAT_TRANSFER_MODEL_HH__
 #define __AKANTU_HEAT_TRANSFER_MODEL_HH__
 
 namespace akantu {
 template <ElementKind kind, class IntegrationOrderFunctor>
 class IntegratorGauss;
 template <ElementKind kind> class ShapeLagrange;
 }
 
 namespace akantu {
 
 class HeatTransferModel : public Model,
                           public DataAccessor<Element>,
                           public DataAccessor<UInt> {
   /* ------------------------------------------------------------------------ */
   /* Constructors/Destructors                                                 */
   /* ------------------------------------------------------------------------ */
 public:
   using FEEngineType = FEEngineTemplate<IntegratorGauss, ShapeLagrange>;
 
   HeatTransferModel(Mesh & mesh, UInt spatial_dimension = _all_dimensions,
                     const ID & id = "heat_transfer_model",
                     const MemoryID & memory_id = 0);
 
   virtual ~HeatTransferModel();
 
   /* ------------------------------------------------------------------------ */
   /* Methods                                                                  */
   /* ------------------------------------------------------------------------ */
 protected:
   /// generic function to initialize everything ready for explicit dynamics
   void initFullImpl(const ModelOptions & options) override;
 
   /// read one material file to instantiate all the materials
   void readMaterials();
 
   /// allocate all vectors
   void initSolver(TimeStepSolverType, NonLinearSolverType) override;
 
   /// initialize the model
   void initModel() override;
 
   void predictor() override;
 
   /// compute the heat flux
   void assembleResidual() override;
 
   /// get the type of matrix needed
   MatrixType getMatrixType(const ID &) override;
 
   /// callback to assemble a Matrix
   void assembleMatrix(const ID &) override;
 
   /// callback to assemble a lumped Matrix
   void assembleLumpedMatrix(const ID &) override;
 
   std::tuple<ID, TimeStepSolverType>
   getDefaultSolverID(const AnalysisMethod & method) override;
 
   ModelSolverOptions
   getDefaultSolverOptions(const TimeStepSolverType & type) const;
   /* ------------------------------------------------------------------------ */
   /* Methods for explicit                                                     */
   /* ------------------------------------------------------------------------ */
 public:
   /// compute and get the stable time step
   Real getStableTimeStep();
 
   /// compute the internal heat flux
   void assembleInternalHeatRate();
 
   /// calculate the lumped capacity vector for heat transfer problem
   void assembleCapacityLumped();
 
   /* ------------------------------------------------------------------------ */
   /* Methods for static                                                       */
   /* ------------------------------------------------------------------------ */
 public:
   /// assemble the conductivity matrix
   void assembleConductivityMatrix();
 
   /// assemble the conductivity matrix
   void assembleCapacity();
 
   /// compute the capacity on quadrature points
   void computeRho(Array<Real> & rho, ElementType type, GhostType ghost_type);
 
 private:
   /// calculate the lumped capacity vector for heat transfer problem (w
   /// ghost type)
   void assembleCapacityLumped(const GhostType & ghost_type);
 
   /// assemble the conductivity matrix (w/ ghost type)
   template <UInt dim>
   void assembleConductivityMatrix(const GhostType & ghost_type);
 
   /// compute the conductivity tensor for each quadrature point in an array
   void computeConductivityOnQuadPoints(const GhostType & ghost_type);
 
   /// compute vector k \grad T for each quadrature point
   void computeKgradT(const GhostType & ghost_type);
 
   /// compute the thermal energy
   Real computeThermalEnergyByNode();
 
   /* ------------------------------------------------------------------------ */
   /* Data Accessor inherited members                                          */
   /* ------------------------------------------------------------------------ */
 public:
   inline UInt getNbData(const Array<Element> & elements,
                         const SynchronizationTag & tag) const override;
   inline void packData(CommunicationBuffer & buffer,
                        const Array<Element> & elements,
                        const SynchronizationTag & tag) const override;
   inline void unpackData(CommunicationBuffer & buffer,
                          const Array<Element> & elements,
                          const SynchronizationTag & tag) override;
 
   inline UInt getNbData(const Array<UInt> & indexes,
                         const SynchronizationTag & tag) const override;
   inline void packData(CommunicationBuffer & buffer,
                        const Array<UInt> & indexes,
                        const SynchronizationTag & tag) const override;
   inline void unpackData(CommunicationBuffer & buffer,
                          const Array<UInt> & indexes,
                          const SynchronizationTag & tag) override;
 
   /* ------------------------------------------------------------------------ */
   /* Dumpable interface                                                       */
   /* ------------------------------------------------------------------------ */
 public:
   dumper::Field * createNodalFieldReal(const std::string & field_name,
                                        const std::string & group_name,
                                        bool padding_flag) override;
 
   dumper::Field * createNodalFieldBool(const std::string & field_name,
                                        const std::string & group_name,
                                        bool padding_flag) override;
 
   dumper::Field * createElementalField(const std::string & field_name,
                                        const std::string & group_name,
                                        bool padding_flag,
                                        const UInt & spatial_dimension,
                                        const ElementKind & kind) override;
 
   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);
 
   void dump() override;
 
   virtual void dump(UInt step);
 
   virtual void dump(Real time, UInt step);
 
   /* ------------------------------------------------------------------------ */
   /* Accessors                                                                */
   /* ------------------------------------------------------------------------ */
 public:
   AKANTU_GET_MACRO(Density, density, Real);
   AKANTU_GET_MACRO(Capacity, capacity, Real);
   /// get the dimension of the system space
   AKANTU_GET_MACRO(SpatialDimension, spatial_dimension, UInt);
   /// get the current value of the time step
   AKANTU_GET_MACRO(TimeStep, time_step, Real);
   /// get the assembled heat flux
   AKANTU_GET_MACRO(InternalHeatRate, *internal_heat_rate, Array<Real> &);
   /// get the lumped capacity
   AKANTU_GET_MACRO(CapacityLumped, *capacity_lumped, Array<Real> &);
   /// get the boundary vector
   AKANTU_GET_MACRO(BlockedDOFs, *blocked_dofs, Array<bool> &);
   /// get the external heat rate vector
   AKANTU_GET_MACRO(ExternalHeatRate, *external_heat_rate, Array<Real> &);
   /// get the temperature gradient
   AKANTU_GET_MACRO_BY_ELEMENT_TYPE_CONST(TemperatureGradient,
                                          temperature_gradient, Real);
   /// get the conductivity on q points
   AKANTU_GET_MACRO_BY_ELEMENT_TYPE_CONST(ConductivityOnQpoints,
                                          conductivity_on_qpoints, Real);
   /// get the conductivity on q points
   AKANTU_GET_MACRO_BY_ELEMENT_TYPE_CONST(TemperatureOnQpoints,
                                          temperature_on_qpoints, Real);
   /// internal variables
   AKANTU_GET_MACRO_BY_ELEMENT_TYPE_CONST(KgradT, k_gradt_on_qpoints, Real);
   /// get the temperature
   AKANTU_GET_MACRO(Temperature, *temperature, Array<Real> &);
   /// get the temperature derivative
   AKANTU_GET_MACRO(TemperatureRate, *temperature_rate, Array<Real> &);
 
   /// get the energy denominated by thermal
   Real getEnergy(const std::string & energy_id, const ElementType & type,
                  UInt index);
   /// get the energy denominated by thermal
   Real getEnergy(const std::string & energy_id);
 
   /// get the thermal energy for a given element
   Real getThermalEnergy(const ElementType & type, UInt index);
   /// get the thermal energy for a given element
   Real getThermalEnergy();
 
 protected:
   /* ------------------------------------------------------------------------ */
   FEEngine & getFEEngineBoundary(const ID & name = "") override;
 
   /* ----------------------------------------------------------------------- */
   template <class iterator>
   void getThermalEnergy(iterator Eth, Array<Real>::const_iterator<Real> T_it,
                         Array<Real>::const_iterator<Real> T_end) const;
 
   template <typename T>
   void allocNodalField(Array<T> *& array, const ID & name);
 
   /* ------------------------------------------------------------------------ */
   /* Class Members                                                            */
   /* ------------------------------------------------------------------------ */
 private:
   /// number of iterations
   UInt n_iter;
 
   /// time step
   Real time_step;
 
   /// temperatures array
   Array<Real> * temperature{nullptr};
 
   /// temperatures derivatives array
   Array<Real> * temperature_rate{nullptr};
 
   /// increment array (@f$\delta \dot T@f$ or @f$\delta T@f$)
   Array<Real> * increment{nullptr};
 
   /// the density
   Real density;
 
   /// the speed of the changing temperature
   ElementTypeMapArray<Real> temperature_gradient;
 
   /// temperature field on quadrature points
   ElementTypeMapArray<Real> temperature_on_qpoints;
 
   /// conductivity tensor on quadrature points
   ElementTypeMapArray<Real> conductivity_on_qpoints;
 
   /// vector k \grad T on quad points
   ElementTypeMapArray<Real> k_gradt_on_qpoints;
 
   /// external flux vector
   Array<Real> * external_heat_rate{nullptr};
 
   /// residuals array
   Array<Real> * internal_heat_rate{nullptr};
 
   // lumped vector
   Array<Real> * capacity_lumped{nullptr};
 
   /// boundary vector
   Array<bool> * blocked_dofs{nullptr};
 
   // realtime
   Real time;
 
   /// capacity
   Real capacity;
 
   // conductivity matrix
   Matrix<Real> conductivity;
 
   // linear variation of the conductivity (for temperature dependent
   // conductivity)
   Real conductivity_variation;
 
   // reference temperature for the interpretation of temperature variation
   Real T_ref;
 
   // the biggest parameter of conductivity matrix
   Real conductivitymax;
 
   UInt temperature_release{0};
   UInt conductivity_matrix_release{0};
   std::unordered_map<GhostType, bool> initial_conductivity{{_not_ghost, true},
                                                            {_ghost, true}};
   std::unordered_map<GhostType, UInt> conductivity_release{{_not_ghost, 0},
                                                            {_ghost, 0}};
 };
 
 } // akantu
 
 /* -------------------------------------------------------------------------- */
 /* inline functions                                                           */
 /* -------------------------------------------------------------------------- */
 #include "heat_transfer_model_inline_impl.cc"
 
 #endif /* __AKANTU_HEAT_TRANSFER_MODEL_HH__ */
diff --git a/src/model/heat_transfer/heat_transfer_model_inline_impl.cc b/src/model/heat_transfer/heat_transfer_model_inline_impl.cc
index 9eca9dd79..1f10eb039 100644
--- a/src/model/heat_transfer/heat_transfer_model_inline_impl.cc
+++ b/src/model/heat_transfer/heat_transfer_model_inline_impl.cc
@@ -1,42 +1,42 @@
 /**
  * @file   heat_transfer_model_inline_impl.cc
  *
  * @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
  * @author Srinivasa Babu Ramisetti <srinivasa.ramisetti@epfl.ch>
+ * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Fri Aug 20 2010
- * @date last modification: Tue Dec 08 2015
+ * @date last modification: Wed Jan 31 2018
  *
  * @brief  Implementation of the inline functions of the HeatTransferModel class
  *
  * @section LICENSE
  *
- * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
- * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
- * Solides)
+ * 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
+ * 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
+ * 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_HEAT_TRANSFER_MODEL_INLINE_IMPL_CC__
 #define __AKANTU_HEAT_TRANSFER_MODEL_INLINE_IMPL_CC__
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 
 } // namespace akantu
 
 #endif /* __AKANTU_HEAT_TRANSFER_MODEL_INLINE_IMPL_CC__ */
diff --git a/src/model/integration_scheme/generalized_trapezoidal.cc b/src/model/integration_scheme/generalized_trapezoidal.cc
index 9dc57650c..91d937d32 100644
--- a/src/model/integration_scheme/generalized_trapezoidal.cc
+++ b/src/model/integration_scheme/generalized_trapezoidal.cc
@@ -1,193 +1,193 @@
 /**
  * @file   generalized_trapezoidal.cc
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
- * @date creation: Mon Jul 04 2011
- * @date last modification: Thu Jun 05 2014
+ * @date creation: Fri Oct 23 2015
+ * @date last modification: Wed Jan 31 2018
  *
  * @brief  implementation of inline functions
  *
  * @section LICENSE
  *
- * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * Copyright (©) 2015-2018 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
- * terms  of the  GNU Lesser  General Public  License as  published by  the Free
+ * 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
+ * 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 "generalized_trapezoidal.hh"
 #include "aka_array.hh"
 #include "dof_manager.hh"
 #include "mesh.hh"
 #include "sparse_matrix.hh"
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 GeneralizedTrapezoidal::GeneralizedTrapezoidal(DOFManager & dof_manager,
                                                const ID & dof_id, Real alpha)
     : IntegrationScheme1stOrder(dof_manager, dof_id), alpha(alpha) {
 
   this->registerParam("alpha", this->alpha, alpha, _pat_parsmod,
                       "The alpha parameter");
 }
 
 /* -------------------------------------------------------------------------- */
 void GeneralizedTrapezoidal::predictor(Real delta_t, Array<Real> & u,
                                        Array<Real> & u_dot,
                                        const Array<bool> & blocked_dofs) const {
   AKANTU_DEBUG_IN();
 
   UInt nb_nodes = u.size();
   UInt nb_degree_of_freedom = u.getNbComponent() * nb_nodes;
 
   Real * u_val = u.storage();
   Real * u_dot_val = u_dot.storage();
   bool * blocked_dofs_val = blocked_dofs.storage();
 
   for (UInt d = 0; d < nb_degree_of_freedom; d++) {
     if (!(*blocked_dofs_val)) {
       *u_val += (1. - alpha) * delta_t * *u_dot_val;
     }
     u_val++;
     u_dot_val++;
     blocked_dofs_val++;
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void GeneralizedTrapezoidal::corrector(const SolutionType & type, Real delta_t,
                                        Array<Real> & u, Array<Real> & u_dot,
                                        const Array<bool> & blocked_dofs,
                                        const Array<Real> & delta) const {
   AKANTU_DEBUG_IN();
 
   switch (type) {
   case _temperature:
     this->allCorrector<_temperature>(delta_t, u, u_dot, blocked_dofs, delta);
     break;
   case _temperature_rate:
     this->allCorrector<_temperature_rate>(delta_t, u, u_dot, blocked_dofs,
                                           delta);
     break;
   default:
     AKANTU_EXCEPTION("The corrector type : "
                      << type
                      << " is not supported by this type of integration scheme");
   }
 
   AKANTU_DEBUG_OUT();
 }
 /* -------------------------------------------------------------------------- */
 Real GeneralizedTrapezoidal::getTemperatureCoefficient(
     const SolutionType & type, Real delta_t) const {
   switch (type) {
   case _temperature:
     return 1.;
   case _temperature_rate:
     return alpha * delta_t;
   default:
     AKANTU_EXCEPTION("The corrector type : "
                      << type
                      << " is not supported by this type of integration scheme");
   }
 }
 
 /* -------------------------------------------------------------------------- */
 Real GeneralizedTrapezoidal::getTemperatureRateCoefficient(
     const SolutionType & type, Real delta_t) const {
   switch (type) {
   case _temperature:
     return 1. / (alpha * delta_t);
   case _temperature_rate:
     return 1.;
   default:
     AKANTU_EXCEPTION("The corrector type : "
                      << type
                      << " is not supported by this type of integration scheme");
   }
 }
 
 /* -------------------------------------------------------------------------- */
 template <IntegrationScheme::SolutionType type>
 void GeneralizedTrapezoidal::allCorrector(Real delta_t, Array<Real> & u,
                                           Array<Real> & u_dot,
                                           const Array<bool> & blocked_dofs,
                                           const Array<Real> & delta) const {
   AKANTU_DEBUG_IN();
 
   UInt nb_nodes = u.size();
   UInt nb_degree_of_freedom = u.getNbComponent() * nb_nodes;
 
   Real e = getTemperatureCoefficient(type, delta_t);
   Real d = getTemperatureRateCoefficient(type, delta_t);
 
   Real * u_val = u.storage();
   Real * u_dot_val = u_dot.storage();
   Real * delta_val = delta.storage();
   bool * blocked_dofs_val = blocked_dofs.storage();
 
   for (UInt dof = 0; dof < nb_degree_of_freedom; dof++) {
     if (!(*blocked_dofs_val)) {
       *u_val += e * *delta_val;
       *u_dot_val += d * *delta_val;
     }
     u_val++;
     u_dot_val++;
     delta_val++;
     blocked_dofs_val++;
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void GeneralizedTrapezoidal::assembleJacobian(const SolutionType & type,
                                               Real delta_t) {
   AKANTU_DEBUG_IN();
 
   SparseMatrix & J = this->dof_manager.getMatrix("J");
 
   const SparseMatrix & M = this->dof_manager.getMatrix("M");
   const SparseMatrix & K = this->dof_manager.getMatrix("K");
 
   bool does_j_need_update = false;
   does_j_need_update |= M.getRelease() != m_release;
   does_j_need_update |= K.getRelease() != k_release;
   if (!does_j_need_update) {
     AKANTU_DEBUG_OUT();
     return;
   }
 
   J.clear();
 
   Real c = this->getTemperatureRateCoefficient(type, delta_t);
   Real e = this->getTemperatureCoefficient(type, delta_t);
 
   J.add(M, e);
   J.add(K, c);
 
   m_release = M.getRelease();
   k_release = K.getRelease();
 
   AKANTU_DEBUG_OUT();
 }
 
 } // akantu
diff --git a/src/model/integration_scheme/generalized_trapezoidal.hh b/src/model/integration_scheme/generalized_trapezoidal.hh
index b984d5590..5ad22cdaf 100644
--- a/src/model/integration_scheme/generalized_trapezoidal.hh
+++ b/src/model/integration_scheme/generalized_trapezoidal.hh
@@ -1,166 +1,165 @@
 /**
  * @file   generalized_trapezoidal.hh
  *
  * @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Mon Jul 04 2011
- * @date last modification: Fri Oct 23 2015
+ * @date last modification: Wed Jan 31 2018
  *
  * @brief  Generalized Trapezoidal  Method.  This implementation  is taken  from
  * Méthodes  numériques en mécanique  des solides  by Alain  Curnier \note{ISBN:
  * 2-88074-247-1}
  *
  * @section LICENSE
  *
- * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
- * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
- * Solides)
+ * 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
+ * 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
+ * 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_GENERALIZED_TRAPEZOIDAL_HH__
 #define __AKANTU_GENERALIZED_TRAPEZOIDAL_HH__
 
 #include "integration_scheme_1st_order.hh"
 
 namespace akantu {
 
 /**
  * The two differentiate equation (thermal and kinematic) are :
  * @f{eqnarray*}{
  *  C\dot{u}_{n+1} + Ku_{n+1} = q_{n+1}\\
  *  u_{n+1} = u_{n} + (1-\alpha) \Delta t \dot{u}_{n} + \alpha \Delta t
  *\dot{u}_{n+1}
  * @f}
  *
  * To solve it :
  * Predictor :
  * @f{eqnarray*}{
  * u^0_{n+1} &=& u_{n} + (1-\alpha) \Delta t v_{n} \\
  * \dot{u}^0_{n+1} &=& \dot{u}_{n}
  * @f}
  *
  * Solve :
  * @f[ (a C + b K^i_{n+1}) w = q_{n+1} - f^i_{n+1} - C \dot{u}^i_{n+1} @f]
  *
  * Corrector :
  * @f{eqnarray*}{
  * \dot{u}^{i+1}_{n+1} &=& \dot{u}^{i}_{n+1} + a w \\
  * u^{i+1}_{n+1} &=& u^{i}_{n+1} + b w
  * @f}
  *
  * a and b depends on the resolution method : temperature (u) or temperature
  *rate (@f$\dot{u}@f$)
  *
  * For temperature : @f$ w = \delta u, a = 1 / (\alpha \Delta t) , b = 1 @f$ @n
  * For temperature rate : @f$ w = \delta \dot{u}, a = 1, b = \alpha \Delta t @f$
  */
 class GeneralizedTrapezoidal : public IntegrationScheme1stOrder {
   /* ------------------------------------------------------------------------ */
   /* Constructors/Destructors                                                 */
   /* ------------------------------------------------------------------------ */
 public:
   GeneralizedTrapezoidal(DOFManager & dof_manager, const ID & dof_id,
                          Real alpha = 0);
 
   /* ------------------------------------------------------------------------ */
   /* Methods                                                                  */
   /* ------------------------------------------------------------------------ */
 public:
   void predictor(Real delta_t, Array<Real> & u, Array<Real> & u_dot,
                  const Array<bool> & blocked_dofs) const override;
 
   void corrector(const SolutionType & type, Real delta_t, Array<Real> & u,
                  Array<Real> & u_dot, const Array<bool> & blocked_dofs,
                  const Array<Real> & delta) const override;
 
   void assembleJacobian(const SolutionType & type, Real time_step) override;
 
 public:
   /// the coeffichent @f{b@f} in the description
   Real getTemperatureCoefficient(const SolutionType & type,
                                  Real delta_t) const override;
 
   /// the coeffichent @f{a@f} in the description
   Real getTemperatureRateCoefficient(const SolutionType & type,
                                      Real delta_t) const override;
 
 private:
   template <SolutionType type>
   void allCorrector(Real delta_t, Array<Real> & u, Array<Real> & u_dot,
                     const Array<bool> & blocked_dofs,
                     const Array<Real> & delta) const;
 
   /* ------------------------------------------------------------------------ */
   /* Accessors                                                                */
   /* ------------------------------------------------------------------------ */
 public:
   AKANTU_GET_MACRO(Alpha, alpha, Real);
 
   /* ------------------------------------------------------------------------ */
   /* Class Members                                                            */
   /* ------------------------------------------------------------------------ */
 private:
   /// the @f$\alpha@f$ parameter
   Real alpha;
 
   /// last release of M matrix
   UInt m_release;
 
   /// last release of K matrix
   UInt k_release;
 };
 
 /* -------------------------------------------------------------------------- */
 /* -------------------------------------------------------------------------- */
 
 /**
  * Forward Euler (explicit) -> condition on delta_t
  */
 class ForwardEuler : public GeneralizedTrapezoidal {
 public:
   ForwardEuler(DOFManager & dof_manager, const ID & dof_id)
       : GeneralizedTrapezoidal(dof_manager, dof_id, 0.){};
 
   std::vector<std::string> getNeededMatrixList() override { return {"M"}; }
 };
 
 /**
  * Trapezoidal rule (implicit), midpoint rule or Crank-Nicolson
  */
 class TrapezoidalRule1 : public GeneralizedTrapezoidal {
 public:
   TrapezoidalRule1(DOFManager & dof_manager, const ID & dof_id)
       : GeneralizedTrapezoidal(dof_manager, dof_id, .5){};
 };
 
 /**
  * Backward Euler (implicit)
  */
 class BackwardEuler : public GeneralizedTrapezoidal {
 public:
   BackwardEuler(DOFManager & dof_manager, const ID & dof_id)
       : GeneralizedTrapezoidal(dof_manager, dof_id, 1.){};
 };
 
 /* -------------------------------------------------------------------------- */
 
 } // namespace akantu
 
 #endif /* __AKANTU_GENERALIZED_TRAPEZOIDAL_HH__ */
diff --git a/src/model/integration_scheme/integration_scheme.cc b/src/model/integration_scheme/integration_scheme.cc
index dc28ebb5e..68073a71d 100644
--- a/src/model/integration_scheme/integration_scheme.cc
+++ b/src/model/integration_scheme/integration_scheme.cc
@@ -1,66 +1,67 @@
 /**
  * @file   integration_scheme.cc
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
- * @date   Fri Oct 23 15:33:36 2015
+ * @date creation: Tue Aug 18 2015
+ * @date last modification: Wed Jan 31 2018
  *
  * @brief  Common interface to all interface schemes
  *
  * @section LICENSE
  *
- * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * Copyright (©) 2015-2018 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
- * terms  of the  GNU Lesser  General Public  License as  published by  the Free
+ * 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
+ * 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 "integration_scheme.hh"
 #include "dof_manager.hh"
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 IntegrationScheme::IntegrationScheme(DOFManager & dof_manager,
                                      const ID & dof_id, UInt order)
     : Parsable(ParserType::_integration_scheme, dof_id),
       dof_manager(dof_manager), dof_id(dof_id), order(order) {}
 
 /* -------------------------------------------------------------------------- */
 /// standard input stream operator for SolutionType
 std::istream & operator>>(std::istream & stream,
                           IntegrationScheme::SolutionType & type) {
   std::string str;
   stream >> str;
   if (str == "displacement")
     type = IntegrationScheme::_displacement;
   else if (str == "temperature")
     type = IntegrationScheme::_temperature;
   else if (str == "velocity")
     type = IntegrationScheme::_velocity;
   else if (str == "temperature_rate")
     type = IntegrationScheme::_temperature_rate;
   else if (str == "acceleration")
     type = IntegrationScheme::_acceleration;
   else {
     stream.setstate(std::ios::failbit);
   }
 
   return stream;
 }
 
 } // akantu
diff --git a/src/model/integration_scheme/integration_scheme.hh b/src/model/integration_scheme/integration_scheme.hh
index 024313073..ccf850bf8 100644
--- a/src/model/integration_scheme/integration_scheme.hh
+++ b/src/model/integration_scheme/integration_scheme.hh
@@ -1,111 +1,111 @@
-
 /**
  * @file   integration_scheme.hh
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
- * @date   Mon Sep 28 10:43:18 2015
+ * @date creation: Fri Jun 18 2010
+ * @date last modification: Wed Jan 31 2018
  *
  * @brief  This class is just a base class for the integration schemes
  *
  * @section LICENSE
  *
- * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * 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
+ * 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
+ * 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 "parsable.hh"
 /* -------------------------------------------------------------------------- */
 
 #ifndef __AKANTU_INTEGRATION_SCHEME_HH__
 #define __AKANTU_INTEGRATION_SCHEME_HH__
 
 namespace akantu {
 class DOFManager;
 }
 
 namespace akantu {
 
 class IntegrationScheme : public Parsable {
   /* ------------------------------------------------------------------------ */
   /* Constructors/Destructors                                                 */
   /* ------------------------------------------------------------------------ */
 public:
   enum SolutionType {
     _not_defined = -1,
     _displacement = 0,
     _temperature = 0,
     _velocity = 1,
     _temperature_rate = 1,
     _acceleration = 2,
   };
 
   IntegrationScheme(DOFManager & dof_manager, const ID & dof_id, UInt order);
   ~IntegrationScheme() override = default;
 
   /* ------------------------------------------------------------------------ */
   /* Methods                                                                  */
   /* ------------------------------------------------------------------------ */
 public:
   /// generic interface of a predictor
   virtual void predictor(Real delta_t) = 0;
 
   /// generic interface of a corrector
   virtual void corrector(const SolutionType & type, Real delta_t) = 0;
 
   /// assemble the jacobian matrix
   virtual void assembleJacobian(const SolutionType & type, Real delta_t) = 0;
 
   /// assemble the residual
   virtual void assembleResidual(bool is_lumped) = 0;
 
   /// returns a list of needed matrices
   virtual std::vector<std::string> getNeededMatrixList() = 0;
 
   /* ------------------------------------------------------------------------ */
   /* Accessors                                                                */
   /* ------------------------------------------------------------------------ */
 public:
   /// return the order of the integration scheme
   UInt getOrder() const;
 
   /* ------------------------------------------------------------------------ */
   /* Class Members                                                            */
   /* ------------------------------------------------------------------------ */
 protected:
   /// The underlying DOFManager
   DOFManager & dof_manager;
 
   /// The id of the dof treated by this integration scheme.
   ID dof_id;
 
   /// The order of the integrator
   UInt order;
 };
 
 /* -------------------------------------------------------------------------- */
 // std::ostream & operator<<(std::ostream & stream,
 //                           const IntegrationScheme::SolutionType & type);
 std::istream & operator>>(std::istream & stream,
                           IntegrationScheme::SolutionType & type);
 /* -------------------------------------------------------------------------- */
 
 } // namespace akantu
 
 #endif /* __AKANTU_INTEGRATION_SCHEME_HH__ */
diff --git a/src/model/integration_scheme/integration_scheme_1st_order.cc b/src/model/integration_scheme/integration_scheme_1st_order.cc
index e9701c486..af6e9d8e0 100644
--- a/src/model/integration_scheme/integration_scheme_1st_order.cc
+++ b/src/model/integration_scheme/integration_scheme_1st_order.cc
@@ -1,95 +1,96 @@
 /**
  * @file   integration_scheme_1st_order.cc
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
- * @date   Fri Oct 23 12:31:32 2015
+ * @date creation: Mon Dec 13 2010
+ * @date last modification: Wed Jan 31 2018
  *
  * @brief  Implementation of the common functions for 1st order time
- *integrations
+ * integrations
  *
  * @section LICENSE
  *
- * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * 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
+ * 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
+ * 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 "integration_scheme_1st_order.hh"
 #include "dof_manager.hh"
 #include "sparse_matrix.hh"
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 std::vector<std::string> IntegrationScheme1stOrder::getNeededMatrixList() {
   return {"K", "M"};
 }
 
 /* -------------------------------------------------------------------------- */
 void IntegrationScheme1stOrder::predictor(Real delta_t) {
   AKANTU_DEBUG_IN();
 
   Array<Real> & u = this->dof_manager.getDOFs(this->dof_id);
   Array<Real> & u_dot = this->dof_manager.getDOFsDerivatives(this->dof_id, 1);
   const Array<bool> & blocked_dofs =
       this->dof_manager.getBlockedDOFs(this->dof_id);
 
   this->predictor(delta_t, u, u_dot, blocked_dofs);
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void IntegrationScheme1stOrder::corrector(const SolutionType & type,
                                           Real delta_t) {
   AKANTU_DEBUG_IN();
 
   Array<Real> & u = this->dof_manager.getDOFs(this->dof_id);
   Array<Real> & u_dot = this->dof_manager.getDOFsDerivatives(this->dof_id, 1);
 
   const Array<Real> & solution = this->dof_manager.getSolution(this->dof_id);
   const Array<bool> & blocked_dofs =
       this->dof_manager.getBlockedDOFs(this->dof_id);
 
   this->corrector(type, delta_t, u, u_dot, blocked_dofs, solution);
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void IntegrationScheme1stOrder::assembleResidual(bool is_lumped) {
   AKANTU_DEBUG_IN();
 
   const Array<Real> & first_derivative =
       dof_manager.getDOFsDerivatives(this->dof_id, 1);
   if (not is_lumped) {
     if (this->dof_manager.hasMatrix("M"))
       this->dof_manager.assembleMatMulVectToResidual(this->dof_id, "M",
                                                      first_derivative, -1);
   } else {
     if (this->dof_manager.hasLumpedMatrix("M"))
       this->dof_manager.assembleLumpedMatMulVectToResidual(
           this->dof_id, "M", first_derivative, -1);
   }
 
   AKANTU_DEBUG_OUT();
 }
 /* -------------------------------------------------------------------------- */
 
 } // akantu
diff --git a/src/model/integration_scheme/integration_scheme_1st_order.hh b/src/model/integration_scheme/integration_scheme_1st_order.hh
index d15ec19df..1f77217b6 100644
--- a/src/model/integration_scheme/integration_scheme_1st_order.hh
+++ b/src/model/integration_scheme/integration_scheme_1st_order.hh
@@ -1,95 +1,94 @@
 /**
  * @file   integration_scheme_1st_order.hh
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Fri Jun 18 2010
- * @date last modification: Fri Oct 23 2015
+ * @date last modification: Wed Jan 31 2018
  *
  * @brief  Interface of the time integrator of first order
  *
  * @section LICENSE
  *
- * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
- * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
- * Solides)
+ * 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
+ * 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
+ * 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 "integration_scheme.hh"
 /* -------------------------------------------------------------------------- */
 
 #ifndef __AKANTU_INTEGRATION_SCHEME_1ST_ORDER_HH__
 #define __AKANTU_INTEGRATION_SCHEME_1ST_ORDER_HH__
 
 namespace akantu {
 
 class IntegrationScheme1stOrder : public IntegrationScheme {
   /* ------------------------------------------------------------------------ */
   /* Constructors/Destructors                                                 */
   /* ------------------------------------------------------------------------ */
 public:
   IntegrationScheme1stOrder(DOFManager & dof_manager, const ID & dof_id)
       : IntegrationScheme(dof_manager, dof_id, 1){};
 
   /* ------------------------------------------------------------------------ */
   /* Methods                                                                  */
   /* ------------------------------------------------------------------------ */
 public:
   /// get list of needed matrices
   std::vector<std::string> getNeededMatrixList() override;
 
   /// generic interface of a predictor
   void predictor(Real delta_t) override;
   /// generic interface of a corrector
   void corrector(const SolutionType & type, Real delta_t) override;
 
   /// assemble the residual
   void assembleResidual(bool is_lumped) override;
 
 protected:
   /// generic interface of a predictor of 1st order
   virtual void predictor(Real delta_t, Array<Real> & u, Array<Real> & u_dot,
                          const Array<bool> & boundary) const = 0;
 
   /// generic interface of a corrector of 1st order
   virtual void corrector(const SolutionType & type, Real delta_t,
                          Array<Real> & u, Array<Real> & u_dot,
                          const Array<bool> & boundary,
                          const Array<Real> & delta) const = 0;
 
   /* ------------------------------------------------------------------------ */
   /* Accessors                                                                */
   /* ------------------------------------------------------------------------ */
 protected:
   virtual Real getTemperatureCoefficient(const SolutionType & type,
                                          Real delta_t) const = 0;
   virtual Real getTemperatureRateCoefficient(const SolutionType & type,
                                              Real delta_t) const = 0;
 
   /* ------------------------------------------------------------------------ */
   /* Class Members                                                            */
   /* ------------------------------------------------------------------------ */
 private:
 };
 
 } // akantu
 
 #include "generalized_trapezoidal.hh"
 
 #endif /* __AKANTU_INTEGRATION_SCHEME_1ST_ORDER_HH__ */
diff --git a/src/model/integration_scheme/integration_scheme_2nd_order.cc b/src/model/integration_scheme/integration_scheme_2nd_order.cc
index e308331dc..ee1dd2a39 100644
--- a/src/model/integration_scheme/integration_scheme_2nd_order.cc
+++ b/src/model/integration_scheme/integration_scheme_2nd_order.cc
@@ -1,105 +1,106 @@
 /**
  * @file   integration_scheme_2nd_order.cc
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
- * @date   Tue Oct 20 10:41:12 2015
+ * @date creation: Fri Oct 23 2015
+ * @date last modification: Wed Jan 31 2018
  *
  * @brief  Implementation of the common part of 2nd order integration schemes
  *
  * @section LICENSE
  *
- * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * Copyright (©) 2015-2018 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
- * terms  of the  GNU Lesser  General Public  License as  published by  the Free
+ * 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
+ * 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 "integration_scheme_2nd_order.hh"
 #include "dof_manager.hh"
 #include "sparse_matrix.hh"
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 std::vector<std::string> IntegrationScheme2ndOrder::getNeededMatrixList() {
   return {"K", "M", "C"};
 }
 
 /* -------------------------------------------------------------------------- */
 void IntegrationScheme2ndOrder::predictor(Real delta_t) {
   AKANTU_DEBUG_IN();
 
   Array<Real> & u = this->dof_manager.getDOFs(this->dof_id);
   Array<Real> & u_dot = this->dof_manager.getDOFsDerivatives(this->dof_id, 1);
   Array<Real> & u_dot_dot =
       this->dof_manager.getDOFsDerivatives(this->dof_id, 2);
   const Array<bool> & blocked_dofs =
       this->dof_manager.getBlockedDOFs(this->dof_id);
 
   this->predictor(delta_t, u, u_dot, u_dot_dot, blocked_dofs);
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void IntegrationScheme2ndOrder::corrector(const SolutionType & type,
                                           Real delta_t) {
   AKANTU_DEBUG_IN();
 
   Array<Real> & u = this->dof_manager.getDOFs(this->dof_id);
   Array<Real> & u_dot = this->dof_manager.getDOFsDerivatives(this->dof_id, 1);
   Array<Real> & u_dot_dot =
       this->dof_manager.getDOFsDerivatives(this->dof_id, 2);
 
   const Array<Real> & solution = this->dof_manager.getSolution(this->dof_id);
   const Array<bool> & blocked_dofs =
       this->dof_manager.getBlockedDOFs(this->dof_id);
 
   this->corrector(type, delta_t, u, u_dot, u_dot_dot, blocked_dofs, solution);
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void IntegrationScheme2ndOrder::assembleResidual(bool is_lumped) {
   AKANTU_DEBUG_IN();
 
   if (this->dof_manager.hasMatrix("C")) {
     const Array<Real> & first_derivative =
         this->dof_manager.getDOFsDerivatives(this->dof_id, 1);
 
     this->dof_manager.assembleMatMulVectToResidual(this->dof_id, "C",
                                                    first_derivative, -1);
   }
 
   const Array<Real> & second_derivative =
       this->dof_manager.getDOFsDerivatives(this->dof_id, 2);
 
   if (not is_lumped) {
     this->dof_manager.assembleMatMulVectToResidual(this->dof_id, "M",
                                                    second_derivative, -1);
   } else {
     this->dof_manager.assembleLumpedMatMulVectToResidual(this->dof_id, "M",
                                                          second_derivative, -1);
   }
 
   AKANTU_DEBUG_OUT();
 }
 /* -------------------------------------------------------------------------- */
 
 } // namespace akantu
diff --git a/src/model/integration_scheme/integration_scheme_2nd_order.hh b/src/model/integration_scheme/integration_scheme_2nd_order.hh
index d60ee5777..d171a2e8b 100644
--- a/src/model/integration_scheme/integration_scheme_2nd_order.hh
+++ b/src/model/integration_scheme/integration_scheme_2nd_order.hh
@@ -1,108 +1,107 @@
 /**
  * @file   integration_scheme_2nd_order.hh
  *
  * @author David Simon Kammer <david.kammer@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Fri Jun 18 2010
- * @date last modification: Fri Oct 23 2015
+ * @date last modification: Wed Jan 31 2018
  *
  * @brief  Interface of the integrator of second order
  *
  * @section LICENSE
  *
- * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
- * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
- * Solides)
+ * 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
+ * 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
+ * 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_array.hh"
 #include "integration_scheme.hh"
 /* -------------------------------------------------------------------------- */
 
 #ifndef __AKANTU_INTEGRATION_SCHEME_2ND_ORDER_HH__
 #define __AKANTU_INTEGRATION_SCHEME_2ND_ORDER_HH__
 
 namespace akantu {
 class SparseMatrix;
 }
 
 namespace akantu {
 
 class IntegrationScheme2ndOrder : public IntegrationScheme {
   /* ------------------------------------------------------------------------ */
   /* Constructors/Destructors                                                 */
   /* ------------------------------------------------------------------------ */
 public:
   IntegrationScheme2ndOrder(DOFManager & dof_manager, const ID & dof_id)
       : IntegrationScheme(dof_manager, dof_id, 2){};
 
   ~IntegrationScheme2ndOrder() override = default;
 
   /* ------------------------------------------------------------------------ */
   /* Methods                                                                  */
   /* ------------------------------------------------------------------------ */
 public:
   /// get list of needed matrices
   std::vector<std::string> getNeededMatrixList() override;
 
   /// generic interface of a predictor
   void predictor(Real delta_t) override;
 
   /// generic interface of a corrector
   void corrector(const SolutionType & type, Real delta_t) override;
 
   void assembleResidual(bool is_lumped) override;
 
 protected:
   /// generic interface of a predictor of 2nd order
   virtual void predictor(Real delta_t, Array<Real> & u, Array<Real> & u_dot,
                          Array<Real> & u_dot_dot,
                          const Array<bool> & blocked_dofs) const = 0;
 
   /// generic interface of a corrector of 2nd order
   virtual void corrector(const SolutionType & type, Real delta_t,
                          Array<Real> & u, Array<Real> & u_dot,
                          Array<Real> & u_dot_dot,
                          const Array<bool> & blocked_dofs,
                          const Array<Real> & delta) const = 0;
 
   /* ------------------------------------------------------------------------ */
   /* Accessors                                                                */
   /* ------------------------------------------------------------------------ */
 protected:
   virtual Real getAccelerationCoefficient(const SolutionType & type,
                                           Real delta_t) const = 0;
 
   virtual Real getVelocityCoefficient(const SolutionType & type,
                                       Real delta_t) const = 0;
 
   virtual Real getDisplacementCoefficient(const SolutionType & type,
                                           Real delta_t) const = 0;
 
   /* ------------------------------------------------------------------------ */
   /* Class Members                                                            */
   /* ------------------------------------------------------------------------ */
 private:
 };
 
 } // akantu
 
 #include "newmark-beta.hh"
 
 #endif /* __AKANTU_INTEGRATION_SCHEME_2ND_ORDER_HH__ */
diff --git a/src/model/integration_scheme/newmark-beta.cc b/src/model/integration_scheme/newmark-beta.cc
index be0d3cdeb..0831da765 100644
--- a/src/model/integration_scheme/newmark-beta.cc
+++ b/src/model/integration_scheme/newmark-beta.cc
@@ -1,260 +1,260 @@
 /**
  * @file   newmark-beta.cc
  *
  * @author David Simon Kammer <david.kammer@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
- * @date creation: Tue Oct 05 2010
- * @date last modification: Thu Jun 05 2014
+ * @date creation: Fri Oct 23 2015
+ * @date last modification: Wed Jan 31 2018
  *
  * @brief  implementation of the  newmark-@f$\beta@f$ integration  scheme.  This
  * implementation is taken from Méthodes  numériques en mécanique des solides by
  * Alain Curnier \note{ISBN: 2-88074-247-1}
  *
  * @section LICENSE
  *
- * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * Copyright (©) 2015-2018 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
- * terms  of the  GNU Lesser  General Public  License as  published by  the Free
+ * 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
+ * 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 "newmark-beta.hh"
 #include "dof_manager.hh"
 #include "sparse_matrix.hh"
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 NewmarkBeta::NewmarkBeta(DOFManager & dof_manager, const ID & dof_id,
                          Real alpha, Real beta)
     : IntegrationScheme2ndOrder(dof_manager, dof_id), beta(beta), alpha(alpha),
       k(0.), h(0.), m_release(0), k_release(0), c_release(0) {
 
   this->registerParam("alpha", this->alpha, alpha, _pat_parsmod,
                       "The alpha parameter");
   this->registerParam("beta", this->beta, beta, _pat_parsmod,
                       "The beta parameter");
 }
 
 /* -------------------------------------------------------------------------- */
 /*
  * @f$ \tilde{u_{n+1}} = u_{n} +  \Delta t \dot{u}_n + \frac{\Delta t^2}{2}
  * \ddot{u}_n @f$
  * @f$ \tilde{\dot{u}_{n+1}} = \dot{u}_{n} +  \Delta t \ddot{u}_{n} @f$
  * @f$ \tilde{\ddot{u}_{n}} = \ddot{u}_{n} @f$
  */
 void NewmarkBeta::predictor(Real delta_t, Array<Real> & u, Array<Real> & u_dot,
                             Array<Real> & u_dot_dot,
                             const Array<bool> & blocked_dofs) const {
   AKANTU_DEBUG_IN();
 
   UInt nb_nodes = u.size();
   UInt nb_degree_of_freedom = u.getNbComponent() * nb_nodes;
 
   Real * u_val = u.storage();
   Real * u_dot_val = u_dot.storage();
   Real * u_dot_dot_val = u_dot_dot.storage();
   bool * blocked_dofs_val = blocked_dofs.storage();
 
   for (UInt d = 0; d < nb_degree_of_freedom; d++) {
     if (!(*blocked_dofs_val)) {
       Real dt_a_n = delta_t * *u_dot_dot_val;
 
       *u_val += (1 - k * alpha) * delta_t * *u_dot_val +
                 (.5 - h * alpha * beta) * delta_t * dt_a_n;
       *u_dot_val = (1 - k) * *u_dot_val + (1 - h * beta) * dt_a_n;
       *u_dot_dot_val = (1 - h) * *u_dot_dot_val;
     }
     u_val++;
     u_dot_val++;
     u_dot_dot_val++;
     blocked_dofs_val++;
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void NewmarkBeta::corrector(const SolutionType & type, Real delta_t,
                             Array<Real> & u, Array<Real> & u_dot,
                             Array<Real> & u_dot_dot,
                             const Array<bool> & blocked_dofs,
                             const Array<Real> & delta) const {
   AKANTU_DEBUG_IN();
 
   switch (type) {
   case _acceleration: {
     this->allCorrector<_acceleration>(delta_t, u, u_dot, u_dot_dot,
                                       blocked_dofs, delta);
     break;
   }
   case _velocity: {
     this->allCorrector<_velocity>(delta_t, u, u_dot, u_dot_dot, blocked_dofs,
                                   delta);
     break;
   }
   case _displacement: {
     this->allCorrector<_displacement>(delta_t, u, u_dot, u_dot_dot,
                                       blocked_dofs, delta);
     break;
   }
   default:
     AKANTU_EXCEPTION("The corrector type : "
                      << type
                      << " is not supported by this type of integration scheme");
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 Real NewmarkBeta::getAccelerationCoefficient(const SolutionType & type,
                                              Real delta_t) const {
   switch (type) {
   case _acceleration:
     return 1.;
   case _velocity:
     return 1. / (beta * delta_t);
   case _displacement:
     return 1. / (alpha * beta * delta_t * delta_t);
   default:
     AKANTU_EXCEPTION("The corrector type : "
                      << type
                      << " is not supported by this type of integration scheme");
   }
 }
 
 /* -------------------------------------------------------------------------- */
 Real NewmarkBeta::getVelocityCoefficient(const SolutionType & type,
                                          Real delta_t) const {
   switch (type) {
   case _acceleration:
     return beta * delta_t;
   case _velocity:
     return 1.;
   case _displacement:
     return 1. / (alpha * delta_t);
   default:
     AKANTU_EXCEPTION("The corrector type : "
                      << type
                      << " is not supported by this type of integration scheme");
   }
 }
 
 /* -------------------------------------------------------------------------- */
 Real NewmarkBeta::getDisplacementCoefficient(const SolutionType & type,
                                              Real delta_t) const {
   switch (type) {
   case _acceleration:
     return alpha * beta * delta_t * delta_t;
   case _velocity:
     return alpha * delta_t;
   case _displacement:
     return 1.;
   default:
     AKANTU_EXCEPTION("The corrector type : "
                      << type
                      << " is not supported by this type of integration scheme");
   }
 }
 
 /* -------------------------------------------------------------------------- */
 template <IntegrationScheme::SolutionType type>
 void NewmarkBeta::allCorrector(Real delta_t, Array<Real> & u,
                                Array<Real> & u_dot, Array<Real> & u_dot_dot,
                                const Array<bool> & blocked_dofs,
                                const Array<Real> & delta) const {
   AKANTU_DEBUG_IN();
 
   UInt nb_nodes = u.size();
   UInt nb_degree_of_freedom = u.getNbComponent() * nb_nodes;
 
   Real c = getAccelerationCoefficient(type, delta_t);
   Real d = getVelocityCoefficient(type, delta_t);
   Real e = getDisplacementCoefficient(type, delta_t);
 
   Real * u_val = u.storage();
   Real * u_dot_val = u_dot.storage();
   Real * u_dot_dot_val = u_dot_dot.storage();
   Real * delta_val = delta.storage();
   bool * blocked_dofs_val = blocked_dofs.storage();
 
   for (UInt dof = 0; dof < nb_degree_of_freedom; dof++) {
     if (!(*blocked_dofs_val)) {
       *u_val += e * *delta_val;
       *u_dot_val += d * *delta_val;
       *u_dot_dot_val += c * *delta_val;
     }
     u_val++;
     u_dot_val++;
     u_dot_dot_val++;
     delta_val++;
     blocked_dofs_val++;
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void NewmarkBeta::assembleJacobian(const SolutionType & type, Real delta_t) {
   AKANTU_DEBUG_IN();
 
   SparseMatrix & J = this->dof_manager.getMatrix("J");
 
   const SparseMatrix & M = this->dof_manager.getMatrix("M");
   const SparseMatrix & K = this->dof_manager.getMatrix("K");
 
   bool does_j_need_update = false;
   does_j_need_update |= M.getRelease() != m_release;
   does_j_need_update |= K.getRelease() != k_release;
   if (this->dof_manager.hasMatrix("C")) {
     const SparseMatrix & C = this->dof_manager.getMatrix("C");
     does_j_need_update |= C.getRelease() != c_release;
   }
 
   if (!does_j_need_update) {
     AKANTU_DEBUG_OUT();
     return;
   }
 
   J.clear();
 
   Real c = this->getAccelerationCoefficient(type, delta_t);
   Real e = this->getDisplacementCoefficient(type, delta_t);
 
   if (!(e == 0.)) { // in explicit this coefficient is exactly 0.
     J.add(K, e);
   }
 
   J.add(M, c);
 
   m_release = M.getRelease();
   k_release = K.getRelease();
 
   if (this->dof_manager.hasMatrix("C")) {
     Real d = this->getVelocityCoefficient(type, delta_t);
     const SparseMatrix & C = this->dof_manager.getMatrix("C");
     J.add(C, d);
     c_release = C.getRelease();
   }
 
   AKANTU_DEBUG_OUT();
 }
 /* -------------------------------------------------------------------------- */
 
 } // akantu
diff --git a/src/model/integration_scheme/newmark-beta.hh b/src/model/integration_scheme/newmark-beta.hh
index 7373c56a9..d3742a76d 100644
--- a/src/model/integration_scheme/newmark-beta.hh
+++ b/src/model/integration_scheme/newmark-beta.hh
@@ -1,196 +1,195 @@
 /**
  * @file   newmark-beta.hh
  *
  * @author David Simon Kammer <david.kammer@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Tue Oct 05 2010
- * @date last modification: Fri Oct 23 2015
+ * @date last modification: Wed Jan 31 2018
  *
  * @brief  implementation of the  newmark-@f$\beta@f$ integration  scheme.  This
  * implementation is taken from Méthodes  numériques en mécanique des solides by
  * Alain Curnier \note{ISBN: 2-88074-247-1}
  *
  * @section LICENSE
  *
- * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
- * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
- * Solides)
+ * 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
+ * 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
+ * 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_NEWMARK_BETA_HH__
 #define __AKANTU_NEWMARK_BETA_HH__
 
 /* -------------------------------------------------------------------------- */
 #include "integration_scheme_2nd_order.hh"
 
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 
 /**
  * The three differentiate equations (dynamic and cinematic) are :
  *  @f{eqnarray*}{
  *   M \ddot{u}_{n+1} + C \dot{u}_{n+1} + K u_{n+1} &=& q_{n+1} \\
  *   u_{n+1} &=& u_{n} + (1 - \alpha) \Delta t \dot{u}_{n} + \alpha \Delta t
  *\dot{u}_{n+1} + (1/2 - \alpha) \Delta t^2 \ddot{u}_n \\
  *   \dot{u}_{n+1} &=& \dot{u}_{n} + (1 - \beta) \Delta t \ddot{u}_{n} + \beta
  *\Delta t \ddot{u}_{n+1}
  *  @f}
  *
  * Predictor:
  *  @f{eqnarray*}{
  *  u^{0}_{n+1}        &=& u_{n} +  \Delta t \dot{u}_n + \frac{\Delta t^2}{2}
  *\ddot{u}_n \\
  *  \dot{u}^{0}_{n+1}  &=& \dot{u}_{n} +  \Delta t \ddot{u}_{n} \\
  *  \ddot{u}^{0}_{n+1} &=& \ddot{u}_{n}
  *  @f}
  *
  * Solve :
  *  @f[ (c M + d C + e K^i_{n+1}) w = = q_{n+1} - f^i_{n+1} - C \dot{u}^i_{n+1}
  *- M \ddot{u}^i_{n+1} @f]
  *
  * Corrector :
  *  @f{eqnarray*}{
  *  \ddot{u}^{i+1}_{n+1} &=& \ddot{u}^{i}_{n+1} + c w \\
  *  \dot{u}^{i+1}_{n+1} &=& \dot{u}^{i}_{n+1} + d w \\
  *  u^{i+1}_{n+1} &=& u^{i}_{n+1} + e w
  *  @f}
  *
  * c, d and e are parameters depending on the method used to solve the equations
  *@n
  * For acceleration : @f$ w = \delta \ddot{u}, e = \alpha \beta \Delta t^2, d =
  *\beta \Delta t,    c = 1 @f$ @n
  * For velocity :     @f$ w = \delta \dot{u},  e = 1/\beta \Delta t,        d =
  *1,                 c = \alpha \Delta t @f$ @n
  * For displacement : @f$ w = \delta u,        e = 1,                       d =
  *1/\alpha \Delta t, c = 1/\alpha \beta \Delta t^2 @f$
  */
 
 class NewmarkBeta : public IntegrationScheme2ndOrder {
   /* ------------------------------------------------------------------------ */
   /* Constructors/Destructors                                                 */
   /* ------------------------------------------------------------------------ */
 public:
   NewmarkBeta(DOFManager & dof_manager, const ID & dof_id, Real alpha = 0.,
               Real beta = 0.);
 
   /* ------------------------------------------------------------------------ */
   /* Methods                                                                  */
   /* ------------------------------------------------------------------------ */
 public:
   void predictor(Real delta_t, Array<Real> & u, Array<Real> & u_dot,
                  Array<Real> & u_dot_dot,
                  const Array<bool> & blocked_dofs) const override;
 
   void corrector(const SolutionType & type, Real delta_t, Array<Real> & u,
                  Array<Real> & u_dot, Array<Real> & u_dot_dot,
                  const Array<bool> & blocked_dofs,
                  const Array<Real> & delta) const override;
 
   void assembleJacobian(const SolutionType & type, Real delta_t) override;
 
 public:
   Real getAccelerationCoefficient(const SolutionType & type,
                                   Real delta_t) const override;
 
   Real getVelocityCoefficient(const SolutionType & type,
                               Real delta_t) const override;
 
   Real getDisplacementCoefficient(const SolutionType & type,
                                   Real delta_t) const override;
 
 private:
   template <SolutionType type>
   void allCorrector(Real delta_t, Array<Real> & u, Array<Real> & u_dot,
                     Array<Real> & u_dot_dot, const Array<bool> & blocked_dofs,
                     const Array<Real> & delta) const;
 
   /* ------------------------------------------------------------------------ */
   /* Accessors                                                                */
   /* ------------------------------------------------------------------------ */
 public:
   AKANTU_GET_MACRO(Beta, beta, Real);
   AKANTU_GET_MACRO(Alpha, alpha, Real);
 
   /* ------------------------------------------------------------------------ */
   /* Class Members                                                            */
   /* ------------------------------------------------------------------------ */
 protected:
   /// the @f$\beta@f$ parameter
   Real beta;
 
   /// the @f$\alpha@f$ parameter
   Real alpha;
 
   Real k;
   Real h;
 
   /// last release of M matrix
   UInt m_release;
 
   /// last release of K matrix
   UInt k_release;
 
   /// last release of C matrix
   UInt c_release;
 };
 
 /**
  * central difference method (explicit)
  * undamped stability condition :
  * @f$ \Delta t = \alpha \Delta t_{crit} = \frac{2}{\omega_{max}} \leq \min_{e}
  *\frac{l_e}{c_e}
  *
  */
 class CentralDifference : public NewmarkBeta {
 public:
   CentralDifference(DOFManager & dof_manager, const ID & dof_id)
       : NewmarkBeta(dof_manager, dof_id, 0., 1. / 2.){};
 
   std::vector<std::string> getNeededMatrixList() override { return {"M", "C"}; }
 };
 //#include "integration_scheme/central_difference.hh"
 
 /// undamped trapezoidal rule (implicit)
 class TrapezoidalRule2 : public NewmarkBeta {
 public:
   TrapezoidalRule2(DOFManager & dof_manager, const ID & dof_id)
       : NewmarkBeta(dof_manager, dof_id, 1. / 2., 1. / 2.){};
 };
 
 /// Fox-Goodwin rule (implicit)
 class FoxGoodwin : public NewmarkBeta {
 public:
   FoxGoodwin(DOFManager & dof_manager, const ID & dof_id)
       : NewmarkBeta(dof_manager, dof_id, 1. / 6., 1. / 2.){};
 };
 
 /// Linear acceleration (implicit)
 class LinearAceleration : public NewmarkBeta {
 public:
   LinearAceleration(DOFManager & dof_manager, const ID & dof_id)
       : NewmarkBeta(dof_manager, dof_id, 1. / 3., 1. / 2.){};
 };
 
 /* -------------------------------------------------------------------------- */
 
 } // namespace akantu
 
 #endif /* __AKANTU_NEWMARK_BETA_HH__ */
diff --git a/src/model/integration_scheme/pseudo_time.cc b/src/model/integration_scheme/pseudo_time.cc
index 6b350562d..1ca15129b 100644
--- a/src/model/integration_scheme/pseudo_time.cc
+++ b/src/model/integration_scheme/pseudo_time.cc
@@ -1,81 +1,82 @@
 /**
  * @file   pseudo_time.cc
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
- * @date   Wed Feb 17 09:49:10 2016
+ * @date creation: Fri Feb 19 2016
+ * @date last modification: Wed Jan 31 2018
  *
  * @brief  Implementation of a really simple integration scheme
  *
  * @section LICENSE
  *
- * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * 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
+ * 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
+ * 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 "pseudo_time.hh"
 #include "dof_manager.hh"
 #include "sparse_matrix.hh"
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 PseudoTime::PseudoTime(DOFManager & dof_manager, const ID & dof_id)
     : IntegrationScheme(dof_manager, dof_id, 0), k_release(0) {}
 
 /* -------------------------------------------------------------------------- */
 std::vector<std::string> PseudoTime::getNeededMatrixList() { return {"K"}; }
 
 /* -------------------------------------------------------------------------- */
 void PseudoTime::predictor(Real) {}
 
 /* -------------------------------------------------------------------------- */
 void PseudoTime::corrector(const SolutionType &, Real) {
   auto & us = this->dof_manager.getDOFs(this->dof_id);
   const auto & deltas = this->dof_manager.getSolution(this->dof_id);
   const auto & blocked_dofs = this->dof_manager.getBlockedDOFs(this->dof_id);
 
   for (auto && tuple : zip(make_view(us), deltas, make_view(blocked_dofs))) {
     auto & u = std::get<0>(tuple);
     const auto & delta = std::get<1>(tuple);
     const auto & bld = std::get<2>(tuple);
     if (not bld)
       u += delta;
   }
 }
 
 /* -------------------------------------------------------------------------- */
 void PseudoTime::assembleJacobian(const SolutionType &, Real) {
   SparseMatrix & J = this->dof_manager.getMatrix("J");
   const SparseMatrix & K = this->dof_manager.getMatrix("K");
 
   if (K.getRelease() == k_release)
     return;
 
   J.clear();
   J.add(K);
 
   k_release = K.getRelease();
 }
 
 /* -------------------------------------------------------------------------- */
 void PseudoTime::assembleResidual(bool) {}
 /* -------------------------------------------------------------------------- */
 
 } // akantu
diff --git a/src/model/integration_scheme/pseudo_time.hh b/src/model/integration_scheme/pseudo_time.hh
index 8950f86b1..a93e66986 100644
--- a/src/model/integration_scheme/pseudo_time.hh
+++ b/src/model/integration_scheme/pseudo_time.hh
@@ -1,72 +1,73 @@
 /**
  * @file   pseudo_time.hh
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
- * @date   Wed Feb 17 09:46:05 2016
+ * @date creation: Fri Jun 18 2010
+ * @date last modification: Wed Jan 31 2018
  *
  * @brief  Pseudo time integration scheme
  *
  * @section LICENSE
  *
- * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * 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
+ * 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
+ * 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 "integration_scheme.hh"
 /* -------------------------------------------------------------------------- */
 
 #ifndef __AKANTU_PSEUDO_TIME_HH__
 #define __AKANTU_PSEUDO_TIME_HH__
 
 namespace akantu {
 
 class PseudoTime : public IntegrationScheme {
   /* ------------------------------------------------------------------------ */
   /* Constructors/Destructors                                                 */
   /* ------------------------------------------------------------------------ */
 public:
   PseudoTime(DOFManager & dof_manager, const ID & dof_id);
 
   /* ------------------------------------------------------------------------ */
   /* Methods                                                                  */
   /* ------------------------------------------------------------------------ */
 public:
   /// get list of needed matrices
   std::vector<std::string> getNeededMatrixList() override;
 
   /// generic interface of a predictor
   void predictor(Real delta_t) override;
 
   /// generic interface of a corrector
   void corrector(const SolutionType & type, Real delta_t) override;
 
   /// assemble the jacobian matrix
   void assembleJacobian(const SolutionType & type, Real delta_t) override;
 
   /// assemble the residual
   void assembleResidual(bool is_lumped) override;
 
 protected:
   /// last release of K matrix
   UInt k_release;
 };
 
 } // namespace akantu
 
 #endif /* __AKANTU_PSEUDO_TIME_HH__ */
diff --git a/src/model/model.cc b/src/model/model.cc
index 959a2fba5..9a4a9577a 100644
--- a/src/model/model.cc
+++ b/src/model/model.cc
@@ -1,369 +1,369 @@
 /**
  * @file   model.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: Mon Oct 03 2011
- * @date last modification: Thu Nov 19 2015
+ * @date last modification: Tue Feb 20 2018
  *
  * @brief  implementation of model common parts
  *
  * @section LICENSE
  *
- * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
- * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
- * Solides)
+ * 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
+ * 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
+ * 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 "model.hh"
 #include "communicator.hh"
 #include "data_accessor.hh"
 #include "element_group.hh"
 #include "element_synchronizer.hh"
 #include "synchronizer_registry.hh"
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 Model::Model(Mesh & mesh, const ModelType & type, UInt dim, const ID & id,
              const MemoryID & memory_id)
     : Memory(id, memory_id), ModelSolver(mesh, type, id, memory_id), mesh(mesh),
       spatial_dimension(dim == _all_dimensions ? mesh.getSpatialDimension()
                                                : dim),
       is_pbc_slave_node(0, 1, "is_pbc_slave_node"), parser(getStaticParser()) {
   AKANTU_DEBUG_IN();
 
   this->mesh.registerEventHandler(*this, _ehp_model);
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 Model::~Model() = default;
 
 /* -------------------------------------------------------------------------- */
 // void Model::setParser(Parser & parser) { this->parser = &parser; }
 
 /* -------------------------------------------------------------------------- */
 void Model::initFullImpl(const ModelOptions & options) {
   AKANTU_DEBUG_IN();
 
   method = options.analysis_method;
   if (!this->hasDefaultSolver()) {
     this->initNewSolver(this->method);
   }
   initModel();
 
   initFEEngineBoundary();
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void Model::initNewSolver(const AnalysisMethod & method) {
   ID solver_name;
   TimeStepSolverType tss_type;
   std::tie(solver_name, tss_type) = this->getDefaultSolverID(method);
 
   if (not this->hasSolver(solver_name)) {
     ModelSolverOptions options = this->getDefaultSolverOptions(tss_type);
     this->getNewSolver(solver_name, tss_type, options.non_linear_solver_type);
 
     for (auto && is_type : options.integration_scheme_type) {
       if (!this->hasIntegrationScheme(solver_name, is_type.first)) {
         this->setIntegrationScheme(solver_name, is_type.first, is_type.second,
                                    options.solution_type[is_type.first]);
       }
     }
   }
 
   this->method = method;
   this->setDefaultSolver(solver_name);
 }
 
 /* -------------------------------------------------------------------------- */
 void Model::initPBC() {
   auto it = pbc_pair.begin();
   auto end = pbc_pair.end();
 
   is_pbc_slave_node.resize(mesh.getNbNodes());
 #ifndef AKANTU_NDEBUG
   auto coord_it = mesh.getNodes().begin(this->spatial_dimension);
 #endif
 
   while (it != end) {
     UInt i1 = (*it).first;
 
     is_pbc_slave_node(i1) = true;
 
 #ifndef AKANTU_NDEBUG
     UInt i2 = (*it).second;
     UInt slave = mesh.isDistributed() ? mesh.getGlobalNodesIds()(i1) : i1;
     UInt master = mesh.isDistributed() ? mesh.getGlobalNodesIds()(i2) : i2;
 
     AKANTU_DEBUG_INFO("pairing " << slave << " (" << Vector<Real>(coord_it[i1])
                                  << ") with " << master << " ("
                                  << Vector<Real>(coord_it[i2]) << ")");
 #endif
     ++it;
   }
 }
 
 /* -------------------------------------------------------------------------- */
 void Model::initFEEngineBoundary() {
   FEEngine & fem_boundary = getFEEngineBoundary();
   fem_boundary.initShapeFunctions(_not_ghost);
   fem_boundary.initShapeFunctions(_ghost);
 
   fem_boundary.computeNormalsOnIntegrationPoints(_not_ghost);
   fem_boundary.computeNormalsOnIntegrationPoints(_ghost);
 }
 
 /* -------------------------------------------------------------------------- */
 void Model::dumpGroup(const std::string & group_name) {
   ElementGroup & group = mesh.getElementGroup(group_name);
   group.dump();
 }
 
 /* -------------------------------------------------------------------------- */
 void Model::dumpGroup(const std::string & group_name,
                       const std::string & dumper_name) {
   ElementGroup & group = mesh.getElementGroup(group_name);
   group.dump(dumper_name);
 }
 
 /* -------------------------------------------------------------------------- */
 void Model::dumpGroup() {
   auto bit = mesh.element_group_begin();
   auto bend = mesh.element_group_end();
   for (; bit != bend; ++bit) {
     bit->second->dump();
   }
 }
 
 /* -------------------------------------------------------------------------- */
 void Model::setGroupDirectory(const std::string & directory) {
   auto bit = mesh.element_group_begin();
   auto bend = mesh.element_group_end();
   for (; bit != bend; ++bit) {
     bit->second->setDirectory(directory);
   }
 }
 
 /* -------------------------------------------------------------------------- */
 void Model::setGroupDirectory(const std::string & directory,
                               const std::string & group_name) {
   ElementGroup & group = mesh.getElementGroup(group_name);
   group.setDirectory(directory);
 }
 
 /* -------------------------------------------------------------------------- */
 void Model::setGroupBaseName(const std::string & basename,
                              const std::string & group_name) {
   ElementGroup & group = mesh.getElementGroup(group_name);
   group.setBaseName(basename);
 }
 
 /* -------------------------------------------------------------------------- */
 DumperIOHelper & Model::getGroupDumper(const std::string & group_name) {
   ElementGroup & group = mesh.getElementGroup(group_name);
   return group.getDumper();
 }
 
 /* -------------------------------------------------------------------------- */
 // DUMPER stuff
 /* -------------------------------------------------------------------------- */
 void Model::addDumpGroupFieldToDumper(const std::string & field_id,
                                       dumper::Field * field,
                                       DumperIOHelper & dumper) {
 #ifdef AKANTU_USE_IOHELPER
   dumper.registerField(field_id, field);
 #endif
 }
 
 /* -------------------------------------------------------------------------- */
 void Model::addDumpField(const std::string & field_id) {
 
   this->addDumpFieldToDumper(mesh.getDefaultDumperName(), field_id);
 }
 /* -------------------------------------------------------------------------- */
 
 void Model::addDumpFieldVector(const std::string & field_id) {
 
   this->addDumpFieldVectorToDumper(mesh.getDefaultDumperName(), field_id);
 }
 
 /* -------------------------------------------------------------------------- */
 void Model::addDumpFieldTensor(const std::string & field_id) {
 
   this->addDumpFieldTensorToDumper(mesh.getDefaultDumperName(), field_id);
 }
 
 /* -------------------------------------------------------------------------- */
 
 void Model::setBaseName(const std::string & field_id) {
 
   mesh.setBaseName(field_id);
 }
 /* -------------------------------------------------------------------------- */
 
 void Model::setBaseNameToDumper(const std::string & dumper_name,
                                 const std::string & basename) {
   mesh.setBaseNameToDumper(dumper_name, basename);
 }
 /* -------------------------------------------------------------------------- */
 
 void Model::addDumpFieldToDumper(const std::string & dumper_name,
                                  const std::string & field_id) {
 
   this->addDumpGroupFieldToDumper(dumper_name, field_id, "all", _ek_regular,
                                   false);
 }
 
 /* -------------------------------------------------------------------------- */
 void Model::addDumpGroupField(const std::string & field_id,
                               const std::string & group_name) {
 
   ElementGroup & group = mesh.getElementGroup(group_name);
   this->addDumpGroupFieldToDumper(group.getDefaultDumperName(), field_id,
                                   group_name, _ek_regular, false);
 }
 
 /* -------------------------------------------------------------------------- */
 void Model::removeDumpGroupField(const std::string & field_id,
                                  const std::string & group_name) {
   ElementGroup & group = mesh.getElementGroup(group_name);
   this->removeDumpGroupFieldFromDumper(group.getDefaultDumperName(), field_id,
                                        group_name);
 }
 
 /* -------------------------------------------------------------------------- */
 void Model::removeDumpGroupFieldFromDumper(const std::string & dumper_name,
                                            const std::string & field_id,
                                            const std::string & group_name) {
   ElementGroup & group = mesh.getElementGroup(group_name);
   group.removeDumpFieldFromDumper(dumper_name, field_id);
 }
 
 /* -------------------------------------------------------------------------- */
 void Model::addDumpFieldVectorToDumper(const std::string & dumper_name,
                                        const std::string & field_id) {
   this->addDumpGroupFieldToDumper(dumper_name, field_id, "all", _ek_regular,
                                   true);
 }
 
 /* -------------------------------------------------------------------------- */
 void Model::addDumpGroupFieldVector(const std::string & field_id,
                                     const std::string & group_name) {
   ElementGroup & group = mesh.getElementGroup(group_name);
   this->addDumpGroupFieldVectorToDumper(group.getDefaultDumperName(), field_id,
                                         group_name);
 }
 
 /* -------------------------------------------------------------------------- */
 void Model::addDumpGroupFieldVectorToDumper(const std::string & dumper_name,
                                             const std::string & field_id,
                                             const std::string & group_name) {
   this->addDumpGroupFieldToDumper(dumper_name, field_id, group_name,
                                   _ek_regular, true);
 }
 /* -------------------------------------------------------------------------- */
 
 void Model::addDumpFieldTensorToDumper(const std::string & dumper_name,
                                        const std::string & field_id) {
   this->addDumpGroupFieldToDumper(dumper_name, field_id, "all", _ek_regular,
                                   true);
 }
 
 /* -------------------------------------------------------------------------- */
 void Model::addDumpGroupFieldToDumper(const std::string & dumper_name,
                                       const std::string & field_id,
                                       const std::string & group_name,
                                       const ElementKind & element_kind,
                                       bool padding_flag) {
   this->addDumpGroupFieldToDumper(dumper_name, field_id, group_name,
                                   this->spatial_dimension, element_kind,
                                   padding_flag);
 }
 
 /* -------------------------------------------------------------------------- */
 void Model::addDumpGroupFieldToDumper(const std::string & dumper_name,
                                       const std::string & field_id,
                                       const std::string & group_name,
                                       UInt spatial_dimension,
                                       const ElementKind & element_kind,
                                       bool padding_flag) {
 
 #ifdef AKANTU_USE_IOHELPER
   dumper::Field * field = nullptr;
 
   if (!field)
     field = this->createNodalFieldReal(field_id, group_name, padding_flag);
   if (!field)
     field = this->createNodalFieldUInt(field_id, group_name, padding_flag);
   if (!field)
     field = this->createNodalFieldBool(field_id, group_name, padding_flag);
   if (!field)
     field = this->createElementalField(field_id, group_name, padding_flag,
                                        spatial_dimension, element_kind);
   if (!field)
     field = this->mesh.createFieldFromAttachedData<UInt>(field_id, group_name,
                                                          element_kind);
   if (!field)
     field = this->mesh.createFieldFromAttachedData<Real>(field_id, group_name,
                                                          element_kind);
 
 #ifndef AKANTU_NDEBUG
   if (!field) {
     AKANTU_DEBUG_WARNING("No field could be found based on name: " << field_id);
   }
 #endif
   if (field) {
     DumperIOHelper & dumper = mesh.getGroupDumper(dumper_name, group_name);
     this->addDumpGroupFieldToDumper(field_id, field, dumper);
   }
 
 #endif
 }
 
 /* -------------------------------------------------------------------------- */
 
 void Model::dump() { mesh.dump(); }
 
 /* -------------------------------------------------------------------------- */
 
 void Model::setDirectory(const std::string & directory) {
   mesh.setDirectory(directory);
 }
 
 /* -------------------------------------------------------------------------- */
 
 void Model::setDirectoryToDumper(const std::string & dumper_name,
                                  const std::string & directory) {
   mesh.setDirectoryToDumper(dumper_name, directory);
 }
 
 /* -------------------------------------------------------------------------- */
 
 void Model::setTextModeToDumper() { mesh.setTextModeToDumper(); }
 
 /* -------------------------------------------------------------------------- */
 
 } // namespace akantu
diff --git a/src/model/model.hh b/src/model/model.hh
index af1032fae..b162476fd 100644
--- a/src/model/model.hh
+++ b/src/model/model.hh
@@ -1,376 +1,376 @@
 /**
  * @file   model.hh
  *
  * @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
  * @author David Simon Kammer <david.kammer@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Fri Jun 18 2010
- * @date last modification: Fri Oct 16 2015
+ * @date last modification: Tue Feb 20 2018
  *
  * @brief  Interface of a model
  *
  * @section LICENSE
  *
- * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
- * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
- * Solides)
+ * 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
+ * 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
+ * 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 "aka_memory.hh"
 #include "aka_named_argument.hh"
 #include "fe_engine.hh"
 #include "mesh.hh"
 #include "model_options.hh"
 #include "model_solver.hh"
 /* -------------------------------------------------------------------------- */
 #include <typeindex>
 /* -------------------------------------------------------------------------- */
 
 #ifndef __AKANTU_MODEL_HH__
 #define __AKANTU_MODEL_HH__
 
 namespace akantu {
 class SynchronizerRegistry;
 class Parser;
 class DumperIOHelper;
 } // namespace akantu
 
 /* -------------------------------------------------------------------------- */
 namespace akantu {
 
 class Model : public Memory, public ModelSolver, public MeshEventHandler {
   /* ------------------------------------------------------------------------ */
   /* Constructors/Destructors                                                 */
   /* ------------------------------------------------------------------------ */
 public:
   Model(Mesh & mesh, const ModelType & type,
         UInt spatial_dimension = _all_dimensions, const ID & id = "model",
         const MemoryID & memory_id = 0);
 
   ~Model() override;
 
   using FEEngineMap = std::map<std::string, std::unique_ptr<FEEngine>>;
 
   /* ------------------------------------------------------------------------ */
   /* Methods                                                                  */
   /* ------------------------------------------------------------------------ */
 protected:
   virtual void initFullImpl(const ModelOptions & options);
 
 public:
 #ifndef SWIG
 
   template <typename... pack>
   std::enable_if_t<are_named_argument<pack...>::value>
   initFull(pack &&... _pack) {
     switch (this->model_type) {
 #ifdef AKANTU_SOLID_MECHANICS
     case ModelType::_solid_mechanics_model:
       this->initFullImpl(SolidMechanicsModelOptions{
           use_named_args, std::forward<decltype(_pack)>(_pack)...});
       break;
 #endif
 #ifdef AKANTU_COHESIVE_ELEMENT
     case ModelType::_solid_mechanics_model_cohesive:
       this->initFullImpl(SolidMechanicsModelCohesiveOptions{
           use_named_args, std::forward<decltype(_pack)>(_pack)...});
       break;
 #endif
 #ifdef AKANTU_HEAT_TRANSFER
     case ModelType::_heat_transfer_model:
       this->initFullImpl(HeatTransferModelOptions{
           use_named_args, std::forward<decltype(_pack)>(_pack)...});
       break;
 #endif
 #ifdef AKANTU_EMBEDDED
     case ModelType::_embedded_model:
       this->initFullImpl(EmbeddedInterfaceModelOptions{
           use_named_args, std::forward<decltype(_pack)>(_pack)...});
       break;
 #endif
     default:
       this->initFullImpl(ModelOptions{use_named_args,
                                       std::forward<decltype(_pack)>(_pack)...});
     }
   }
 
   template <typename... pack>
   std::enable_if_t<not are_named_argument<pack...>::value>
   initFull(pack &&... _pack) {
     this->initFullImpl(std::forward<decltype(_pack)>(_pack)...);
   }
 #endif
 
   /// initialize a new solver if needed
   void initNewSolver(const AnalysisMethod & method);
 
 protected:
   /// get some default values for derived classes
   virtual std::tuple<ID, TimeStepSolverType>
   getDefaultSolverID(const AnalysisMethod & method) = 0;
 
   virtual void initModel() = 0;
 
   virtual void initFEEngineBoundary();
 
   // /// change local equation number so that PBC is assembled properly
   // void changeLocalEquationNumberForPBC(std::map<UInt, UInt> & pbc_pair,
   //                                      UInt dimension);
   /// function to print the containt of the class
   void printself(std::ostream &, int = 0) const override{};
 
   // /// initialize the model for PBC
   // void setPBC(UInt x, UInt y, UInt z);
   // void setPBC(SurfacePairList & surface_pairs);
 public:
   virtual void initPBC();
 
   /// set the parser to use
   // void setParser(Parser & parser);
 
   /* ------------------------------------------------------------------------ */
   /* Access to the dumpable interface of the boundaries                       */
   /* ------------------------------------------------------------------------ */
   /// Dump the data for a given group
   void dumpGroup(const std::string & group_name);
   void dumpGroup(const std::string & group_name,
                  const std::string & dumper_name);
   /// Dump the data for all boundaries
   void dumpGroup();
   /// Set the directory for a given group
   void setGroupDirectory(const std::string & directory,
                          const std::string & group_name);
   /// Set the directory for all boundaries
   void setGroupDirectory(const std::string & directory);
   /// Set the base name for a given group
   void setGroupBaseName(const std::string & basename,
                         const std::string & group_name);
   /// Get the internal dumper of a given group
   DumperIOHelper & getGroupDumper(const std::string & group_name);
 
   /* ------------------------------------------------------------------------ */
   /* Function for non local capabilities                                      */
   /* ------------------------------------------------------------------------ */
   virtual void updateDataForNonLocalCriterion(__attribute__((unused))
                                               ElementTypeMapReal & criterion) {
     AKANTU_TO_IMPLEMENT();
   }
 
 protected:
   template <typename T>
   void allocNodalField(Array<T> *& array, UInt nb_component, const ID & name);
 
   /* ------------------------------------------------------------------------ */
   /* Accessors */
   /* ------------------------------------------------------------------------ */
 public:
   /// get id of model
   AKANTU_GET_MACRO(ID, id, const ID)
 
   /// get the number of surfaces
   AKANTU_GET_MACRO(Mesh, mesh, Mesh &)
 
   /// synchronize the boundary in case of parallel run
   virtual void synchronizeBoundaries(){};
 
   /// return the fem object associated with a provided name
   inline FEEngine & getFEEngine(const ID & name = "") const;
 
   /// return the fem boundary object associated with a provided name
   virtual FEEngine & getFEEngineBoundary(const ID & name = "");
 
   /// register a fem object associated with name
   template <typename FEEngineClass>
   inline void registerFEEngineObject(const std::string & name, Mesh & mesh,
                                      UInt spatial_dimension);
   /// unregister a fem object associated with name
   inline void unRegisterFEEngineObject(const std::string & name);
 
   /// return the synchronizer registry
   SynchronizerRegistry & getSynchronizerRegistry();
 
   /// return the fem object associated with a provided name
   template <typename FEEngineClass>
   inline FEEngineClass & getFEEngineClass(std::string name = "") const;
 
   /// return the fem boundary object associated with a provided name
   template <typename FEEngineClass>
   inline FEEngineClass & getFEEngineClassBoundary(std::string name = "");
 
   /// get the pbc pairs
   std::map<UInt, UInt> & getPBCPairs() { return pbc_pair; };
 
   /// returns if node is slave in pbc
   inline bool isPBCSlaveNode(const UInt) const {
     throw;
     return false; /* TODO repair PBC*/
   }
 
   /// returns the array of pbc slave nodes (boolean information)
   AKANTU_GET_MACRO(IsPBCSlaveNode, is_pbc_slave_node, const Array<bool> &)
 
   /// Get the type of analysis method used
   AKANTU_GET_MACRO(AnalysisMethod, method, AnalysisMethod);
 
   /* ------------------------------------------------------------------------ */
   /* Pack and unpack helper functions                                         */
   /* ------------------------------------------------------------------------ */
 public:
   inline UInt getNbIntegrationPoints(const Array<Element> & elements,
                                      const ID & fem_id = ID()) const;
 
   /* ------------------------------------------------------------------------ */
   /* Dumpable interface (kept for convenience) and dumper relative functions  */
   /* ------------------------------------------------------------------------ */
   void setTextModeToDumper();
 
   virtual void addDumpGroupFieldToDumper(const std::string & field_id,
                                          dumper::Field * field,
                                          DumperIOHelper & dumper);
 
   virtual void addDumpField(const std::string & field_id);
 
   virtual void addDumpFieldVector(const std::string & field_id);
 
   virtual void addDumpFieldToDumper(const std::string & dumper_name,
                                     const std::string & field_id);
 
   virtual void addDumpFieldVectorToDumper(const std::string & dumper_name,
                                           const std::string & field_id);
 
   virtual void addDumpFieldTensorToDumper(const std::string & dumper_name,
                                           const std::string & field_id);
 
   virtual void addDumpFieldTensor(const std::string & field_id);
 
   virtual void setBaseName(const std::string & basename);
 
   virtual void setBaseNameToDumper(const std::string & dumper_name,
                                    const std::string & basename);
 
   virtual void addDumpGroupField(const std::string & field_id,
                                  const std::string & group_name);
 
   virtual void addDumpGroupFieldToDumper(const std::string & dumper_name,
                                          const std::string & field_id,
                                          const std::string & group_name,
                                          const ElementKind & element_kind,
                                          bool padding_flag);
 
   virtual void addDumpGroupFieldToDumper(const std::string & dumper_name,
                                          const std::string & field_id,
                                          const std::string & group_name,
                                          UInt spatial_dimension,
                                          const ElementKind & element_kind,
                                          bool padding_flag);
 
   virtual void removeDumpGroupField(const std::string & field_id,
                                     const std::string & group_name);
   virtual void removeDumpGroupFieldFromDumper(const std::string & dumper_name,
                                               const std::string & field_id,
                                               const std::string & group_name);
 
   virtual void addDumpGroupFieldVector(const std::string & field_id,
                                        const std::string & group_name);
 
   virtual void addDumpGroupFieldVectorToDumper(const std::string & dumper_name,
                                                const std::string & field_id,
                                                const std::string & group_name);
 
   virtual dumper::Field *
   createNodalFieldReal(__attribute__((unused)) const std::string & field_name,
                        __attribute__((unused)) const std::string & group_name,
                        __attribute__((unused)) bool padding_flag) {
     return nullptr;
   }
 
   virtual dumper::Field *
   createNodalFieldUInt(__attribute__((unused)) const std::string & field_name,
                        __attribute__((unused)) const std::string & group_name,
                        __attribute__((unused)) bool padding_flag) {
     return nullptr;
   }
 
   virtual dumper::Field *
   createNodalFieldBool(__attribute__((unused)) const std::string & field_name,
                        __attribute__((unused)) const std::string & group_name,
                        __attribute__((unused)) bool padding_flag) {
     return nullptr;
   }
 
   virtual dumper::Field *
   createElementalField(__attribute__((unused)) const std::string & field_name,
                        __attribute__((unused)) const std::string & group_name,
                        __attribute__((unused)) bool padding_flag,
                        __attribute__((unused)) const UInt & spatial_dimension,
                        __attribute__((unused)) const ElementKind & kind) {
     return nullptr;
   }
 
   void setDirectory(const std::string & directory);
   void setDirectoryToDumper(const std::string & dumper_name,
                             const std::string & directory);
 
   virtual void dump();
 
   /* ------------------------------------------------------------------------ */
   /* Class Members                                                            */
   /* ------------------------------------------------------------------------ */
 protected:
   friend std::ostream & operator<<(std::ostream &, const Model &);
 
   /// analysis method check the list in akantu::AnalysisMethod
   AnalysisMethod method;
 
   /// Mesh
   Mesh & mesh;
 
   /// Spatial dimension of the problem
   UInt spatial_dimension;
 
   /// the main fem object present in all  models
   FEEngineMap fems;
 
   /// the fem object present in all  models for boundaries
   FEEngineMap fems_boundary;
 
   /// default fem object
   std::string default_fem;
 
   /// pbc pairs
   std::map<UInt, UInt> pbc_pair;
 
   /// flag per node to know is pbc slave
   Array<bool> is_pbc_slave_node;
 
   /// parser to the pointer to use
   Parser & parser;
 };
 
 /// standard output stream operator
 inline std::ostream & operator<<(std::ostream & stream, const Model & _this) {
   _this.printself(stream);
   return stream;
 }
 
 } // namespace akantu
 
 #include "model_inline_impl.cc"
 
 #endif /* __AKANTU_MODEL_HH__ */
diff --git a/src/model/model_inline_impl.cc b/src/model/model_inline_impl.cc
index c57bbf7ed..c786190ed 100644
--- a/src/model/model_inline_impl.cc
+++ b/src/model/model_inline_impl.cc
@@ -1,217 +1,216 @@
 /**
  * @file   model_inline_impl.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: Wed Aug 25 2010
- * @date last modification: Wed Nov 11 2015
+ * @date last modification: Wed Nov 08 2017
  *
  * @brief  inline implementation of the model class
  *
  * @section LICENSE
  *
- * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
- * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
- * Solides)
+ * 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
+ * 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
+ * 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 "model.hh"
 /* -------------------------------------------------------------------------- */
 
 #ifndef __AKANTU_MODEL_INLINE_IMPL_CC__
 #define __AKANTU_MODEL_INLINE_IMPL_CC__
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 template <typename FEEngineClass>
 inline FEEngineClass & Model::getFEEngineClassBoundary(std::string name) {
   AKANTU_DEBUG_IN();
 
   if (name == "")
     name = default_fem;
 
   FEEngineMap::const_iterator it_boun = fems_boundary.find(name);
 
   if (it_boun == fems_boundary.end()) {
     AKANTU_DEBUG_INFO("Creating FEEngine boundary " << name);
 
     FEEngineMap::const_iterator it = fems.find(name);
     AKANTU_DEBUG_ASSERT(it != fems.end(),
                         "The FEEngine " << name << " is not registered");
 
     UInt spatial_dimension = it->second->getElementDimension();
     std::stringstream sstr;
     sstr << id << ":fem_boundary:" << name;
 
     fems_boundary[name] = std::make_unique<FEEngineClass>(
         it->second->getMesh(), spatial_dimension - 1, sstr.str(), memory_id);
   }
 
   AKANTU_DEBUG_OUT();
   return dynamic_cast<FEEngineClass &>(*fems_boundary[name]);
 }
 
 /* -------------------------------------------------------------------------- */
 template <typename FEEngineClass>
 inline FEEngineClass & Model::getFEEngineClass(std::string name) const {
   AKANTU_DEBUG_IN();
 
   if (name == "")
     name = default_fem;
 
   auto it = fems.find(name);
   AKANTU_DEBUG_ASSERT(it != fems.end(),
                       "The FEEngine " << name << " is not registered");
 
   AKANTU_DEBUG_OUT();
   return dynamic_cast<FEEngineClass &>(*(it->second));
 }
 
 /* -------------------------------------------------------------------------- */
 
 inline void Model::unRegisterFEEngineObject(const std::string & name) {
 
   auto it = fems.find(name);
   AKANTU_DEBUG_ASSERT(it != fems.end(),
                       "FEEngine object with name " << name << " was not found");
 
   fems.erase(it);
   if (!fems.empty())
     default_fem = (*fems.begin()).first;
 }
 
 /* -------------------------------------------------------------------------- */
 
 template <typename FEEngineClass>
 inline void Model::registerFEEngineObject(const std::string & name, Mesh & mesh,
                                           UInt spatial_dimension) {
   if (fems.size() == 0)
     default_fem = name;
 
 #ifndef AKANTU_NDEBUG
   auto it = fems.find(name);
   AKANTU_DEBUG_ASSERT(it == fems.end(),
                       "FEEngine object with name " << name
                                                    << " was already created");
 #endif
 
   std::stringstream sstr;
   sstr << id << ":fem:" << name << memory_id;
   fems[name] = std::make_unique<FEEngineClass>(mesh, spatial_dimension,
                                                sstr.str(), memory_id);
 }
 
 /* -------------------------------------------------------------------------- */
 inline FEEngine & Model::getFEEngine(const ID & name) const {
   AKANTU_DEBUG_IN();
   ID tmp_name = name;
   if (name == "")
     tmp_name = default_fem;
 
   auto it = fems.find(tmp_name);
 
   AKANTU_DEBUG_ASSERT(it != fems.end(),
                       "The FEEngine " << tmp_name << " is not registered");
 
   AKANTU_DEBUG_OUT();
   return *(it->second);
 }
 
 /* -------------------------------------------------------------------------- */
 inline FEEngine & Model::getFEEngineBoundary(const ID & name) {
   AKANTU_DEBUG_IN();
 
   ID tmp_name = name;
   if (name == "")
     tmp_name = default_fem;
 
   FEEngineMap::const_iterator it = fems_boundary.find(tmp_name);
   AKANTU_DEBUG_ASSERT(it != fems_boundary.end(),
                       "The FEEngine boundary  " << tmp_name
                                                 << " is not registered");
   AKANTU_DEBUG_ASSERT(it->second != nullptr,
                       "The FEEngine boundary " << tmp_name
                                                << " was not created");
 
   AKANTU_DEBUG_OUT();
   return *(it->second);
 }
 
 // /* --------------------------------------------------------------------------
 // */
 // /// @todo : should merge with a single function which handles local and
 // global
 // inline void Model::changeLocalEquationNumberForPBC(std::map<UInt,UInt> &
 // pbc_pair,
 // 					    UInt dimension){
 //   for (std::map<UInt,UInt>::iterator it = pbc_pair.begin();
 //        it != pbc_pair.end();++it) {
 //     Int node_master = (*it).second;
 //     Int node_slave = (*it).first;
 //     for (UInt i = 0; i < dimension; ++i) {
 //       (*dof_synchronizer->getLocalDOFEquationNumbersPointer())
 // 	(node_slave*dimension+i) = dimension*node_master+i;
 //       (*dof_synchronizer->getGlobalDOFEquationNumbersPointer())
 // 	(node_slave*dimension+i) = dimension*node_master+i;
 //     }
 //   }
 // }
 // /* --------------------------------------------------------------------------
 // */
 // inline bool Model::isPBCSlaveNode(const UInt node) const {
 //   // if no pbc is defined, is_pbc_slave_node is of size zero
 //   if (is_pbc_slave_node.size() == 0)
 //     return false;
 //   else
 //     return is_pbc_slave_node(node);
 // }
 /* -------------------------------------------------------------------------- */
 template <typename T>
 void Model::allocNodalField(Array<T> *& array, UInt nb_component,
                             const ID & name) {
   if (array == nullptr) {
     UInt nb_nodes = mesh.getNbNodes();
     std::stringstream sstr_disp;
     sstr_disp << id << ":" << name;
 
     array = &(alloc<T>(sstr_disp.str(), nb_nodes, nb_component, T()));
   }
 }
 
 /* -------------------------------------------------------------------------- */
 inline UInt Model::getNbIntegrationPoints(const Array<Element> & elements,
                                           const ID & fem_id) const {
   UInt nb_quad = 0;
   Array<Element>::const_iterator<Element> it = elements.begin();
   Array<Element>::const_iterator<Element> end = elements.end();
   for (; it != end; ++it) {
     const Element & el = *it;
     nb_quad +=
         getFEEngine(fem_id).getNbIntegrationPoints(el.type, el.ghost_type);
   }
   return nb_quad;
 }
 
 /* -------------------------------------------------------------------------- */
 
 } // akantu
 
 #endif /* __AKANTU_MODEL_INLINE_IMPL_CC__ */
diff --git a/src/model/model_options.hh b/src/model/model_options.hh
index c431d6931..7e2e0a15c 100644
--- a/src/model/model_options.hh
+++ b/src/model/model_options.hh
@@ -1,137 +1,139 @@
 /**
  * @file   model_options.hh
  *
- * @author Nicolas Richart
+ * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
- * @date creation  Mon Dec 04 2017
+ * @date creation: Mon Dec 04 2017
+ * @date last modification: Wed Jan 31 2018
  *
- * @brief A Documented file.
+ * @brief  A Documented file.
  *
  * @section LICENSE
  *
- * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * 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
+ * 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
+ * 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 "aka_named_argument.hh"
 /* -------------------------------------------------------------------------- */
 
 #ifndef __AKANTU_MODEL_OPTIONS_HH__
 #define __AKANTU_MODEL_OPTIONS_HH__
 
 namespace akantu {
 
 namespace {
   DECLARE_NAMED_ARGUMENT(analysis_method);
 }
 
 struct ModelOptions {
   explicit ModelOptions(AnalysisMethod analysis_method = _static)
       : analysis_method(analysis_method) {}
 
   template <typename... pack>
   ModelOptions(use_named_args_t, pack &&... _pack)
       : ModelOptions(OPTIONAL_NAMED_ARG(analysis_method, _static)) {}
 
   virtual ~ModelOptions() = default;
 
   AnalysisMethod analysis_method;
 };
 
 #ifdef AKANTU_SOLID_MECHANICS
 /* -------------------------------------------------------------------------- */
 struct SolidMechanicsModelOptions : public ModelOptions {
   explicit SolidMechanicsModelOptions(
       AnalysisMethod analysis_method = _explicit_lumped_mass)
       : ModelOptions(analysis_method) {}
 
   template <typename... pack>
   SolidMechanicsModelOptions(use_named_args_t, pack &&... _pack)
       : SolidMechanicsModelOptions(
             OPTIONAL_NAMED_ARG(analysis_method, _explicit_lumped_mass)) {}
 };
 #endif
 
 /* -------------------------------------------------------------------------- */
 #ifdef AKANTU_COHESIVE_ELEMENT
 namespace {
   DECLARE_NAMED_ARGUMENT(is_extrinsic);
 }
 /* -------------------------------------------------------------------------- */
 struct SolidMechanicsModelCohesiveOptions : public SolidMechanicsModelOptions {
   SolidMechanicsModelCohesiveOptions(
       AnalysisMethod analysis_method = _explicit_lumped_mass,
       bool extrinsic = false)
       : SolidMechanicsModelOptions(analysis_method), extrinsic(extrinsic) {}
 
   template <typename... pack>
   SolidMechanicsModelCohesiveOptions(use_named_args_t, pack &&... _pack)
       : SolidMechanicsModelCohesiveOptions(
             OPTIONAL_NAMED_ARG(analysis_method, _explicit_lumped_mass),
             OPTIONAL_NAMED_ARG(is_extrinsic, false)) {}
 
   bool extrinsic{false};
 };
 #endif
 
 #ifdef AKANTU_HEAT_TRANSFER
 /* -------------------------------------------------------------------------- */
 struct HeatTransferModelOptions : public ModelOptions {
   explicit HeatTransferModelOptions(
       AnalysisMethod analysis_method = _explicit_lumped_mass)
       : ModelOptions(analysis_method) {}
 
   template <typename... pack>
   HeatTransferModelOptions(use_named_args_t, pack &&... _pack)
       : HeatTransferModelOptions(
             OPTIONAL_NAMED_ARG(analysis_method, _explicit_lumped_mass)) {}
 };
 #endif
 
 #ifdef AKANTU_EMBEDDED
 
 namespace {
   DECLARE_NAMED_ARGUMENT(init_intersections);
 }
 /* -------------------------------------------------------------------------- */
 struct EmbeddedInterfaceModelOptions : SolidMechanicsModelOptions {
   /**
    * @brief Constructor for EmbeddedInterfaceModelOptions
    * @param analysis_method see SolidMechanicsModelOptions
    * @param init_intersections compute intersections
    */
   EmbeddedInterfaceModelOptions(
       AnalysisMethod analysis_method = _explicit_lumped_mass,
       bool init_intersections = true)
       : SolidMechanicsModelOptions(analysis_method),
         has_intersections(init_intersections) {}
 
   template <typename... pack>
   EmbeddedInterfaceModelOptions(use_named_args_t, pack &&... _pack)
       : EmbeddedInterfaceModelOptions(
             OPTIONAL_NAMED_ARG(analysis_method, _explicit_lumped_mass),
             OPTIONAL_NAMED_ARG(init_intersections, true)) {}
 
   /// Should consider reinforcements
   bool has_intersections;
 };
 #endif
 
 } // akantu
 
 #endif /* __AKANTU_MODEL_OPTIONS_HH__ */
diff --git a/src/model/model_solver.cc b/src/model/model_solver.cc
index 78e97c629..1891e7fd3 100644
--- a/src/model/model_solver.cc
+++ b/src/model/model_solver.cc
@@ -1,364 +1,365 @@
 /**
  * @file   model_solver.cc
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
- * @date   Wed Aug 12 13:31:56 2015
+ * @date creation: Tue Aug 18 2015
+ * @date last modification: Wed Feb 21 2018
  *
  * @brief  Implementation of ModelSolver
  *
  * @section LICENSE
  *
- * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * Copyright (©) 2015-2018 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
- * terms  of the  GNU Lesser  General Public  License as  published by  the Free
+ * 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
+ * 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 "model_solver.hh"
 #include "dof_manager.hh"
 #include "dof_manager_default.hh"
 #include "mesh.hh"
 #include "non_linear_solver.hh"
 #include "time_step_solver.hh"
 
 #if defined(AKANTU_USE_PETSC)
 #include "dof_manager_petsc.hh"
 #endif
 
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 template <typename T> static T getOptionToType(const std::string & opt_str) {
   std::stringstream sstr(opt_str);
   T opt;
   sstr >> opt;
 
   return opt;
 }
 
 /* -------------------------------------------------------------------------- */
 ModelSolver::ModelSolver(Mesh & mesh, const ModelType & type, const ID & id,
                          UInt memory_id)
     : Parsable(ParserType::_model, id), SolverCallback(), model_type(type),
       parent_id(id), parent_memory_id(memory_id), mesh(mesh),
       dof_manager(nullptr), default_solver_id("") {}
 
 /* -------------------------------------------------------------------------- */
 ModelSolver::~ModelSolver() = default;
 
 /* -------------------------------------------------------------------------- */
 std::tuple<ParserSection, bool> ModelSolver::getParserSection() {
   auto sub_sections = getStaticParser().getSubSections(ParserType::_model);
 
   auto it = std::find_if(
       sub_sections.begin(), sub_sections.end(), [&](auto && section) {
         ModelType type = getOptionToType<ModelType>(section.getName());
         // default id should be the model type if not defined
         std::string name = section.getParameter("name", this->parent_id);
         return type == model_type and name == this->parent_id;
       });
 
   if (it == sub_sections.end())
     return std::make_tuple(ParserSection(), true);
 
   return std::make_tuple(*it, false);
 }
 
 /* -------------------------------------------------------------------------- */
 void ModelSolver::initDOFManager() {
   // default without external solver activated at compilation same as mumps that
   // is the historical solver but with only the lumped solver
   ID solver_type = "default";
 
 #if defined(AKANTU_USE_MUMPS)
   solver_type = "default";
 #elif defined(AKANTU_USE_PETSC)
   solver_type = "petsc";
 #endif
 
   ParserSection section;
   bool is_empty;
   std::tie(section, is_empty) = this->getParserSection();
 
   if (not is_empty) {
     solver_type = section.getOption(solver_type);
     this->initDOFManager(section, solver_type);
   } else {
     this->initDOFManager(solver_type);
   }
 }
 
 /* -------------------------------------------------------------------------- */
 void ModelSolver::initDOFManager(const ID & solver_type) {
   try {
     this->dof_manager = DOFManagerFactory::getInstance().allocate(
         solver_type, mesh, this->parent_id + ":dof_manager" + solver_type,
         this->parent_memory_id);
   } catch (...) {
     AKANTU_EXCEPTION(
         "To use the solver "
         << solver_type
         << " you will have to code it. This is an unknown solver type.");
   }
 
   this->setDOFManager(*this->dof_manager);
 }
 
 /* -------------------------------------------------------------------------- */
 void ModelSolver::initDOFManager(const ParserSection & section,
                                  const ID & solver_type) {
   this->initDOFManager(solver_type);
   auto sub_sections = section.getSubSections(ParserType::_time_step_solver);
 
   // parsing the time step solvers
   for (auto && section : sub_sections) {
     ID type = section.getName();
     ID solver_id = section.getParameter("name", type);
 
     auto tss_type = getOptionToType<TimeStepSolverType>(type);
     auto tss_options = this->getDefaultSolverOptions(tss_type);
 
     auto sub_solvers_sect =
         section.getSubSections(ParserType::_non_linear_solver);
     auto nb_non_linear_solver_section =
         section.getNbSubSections(ParserType::_non_linear_solver);
 
     auto nls_type = tss_options.non_linear_solver_type;
 
     if (nb_non_linear_solver_section == 1) {
       auto && nls_section = *(sub_solvers_sect.first);
       nls_type = getOptionToType<NonLinearSolverType>(nls_section.getName());
     } else if (nb_non_linear_solver_section > 0) {
       AKANTU_EXCEPTION("More than one non linear solver are provided for the "
                        "time step solver "
                        << solver_id);
     }
 
     this->getNewSolver(solver_id, tss_type, nls_type);
     if (nb_non_linear_solver_section == 1) {
       const auto & nls_section = *(sub_solvers_sect.first);
       this->dof_manager->getNonLinearSolver(solver_id).parseSection(
           nls_section);
     }
 
     auto sub_integrator_sections =
         section.getSubSections(ParserType::_integration_scheme);
 
     for (auto && is_section : sub_integrator_sections) {
       const auto & dof_type_str = is_section.getName();
       ID dof_id;
       try {
         ID tmp = is_section.getParameter("name");
         dof_id = tmp;
       } catch (...) {
         AKANTU_EXCEPTION("No degree of freedom name specified for the "
                          "integration scheme of type "
                          << dof_type_str);
       }
 
       auto it_type = getOptionToType<IntegrationSchemeType>(dof_type_str);
 
       IntegrationScheme::SolutionType s_type = is_section.getParameter(
           "solution_type", tss_options.solution_type[dof_id]);
       this->setIntegrationScheme(solver_id, dof_id, it_type, s_type);
     }
 
     for (auto & is_type : tss_options.integration_scheme_type) {
       if (!this->hasIntegrationScheme(solver_id, is_type.first)) {
         this->setIntegrationScheme(solver_id, is_type.first, is_type.second,
                                    tss_options.solution_type[is_type.first]);
       }
     }
   }
 
   if (section.hasParameter("default_solver")) {
     ID default_solver = section.getParameter("default_solver");
     if (this->hasSolver(default_solver)) {
       this->setDefaultSolver(default_solver);
     } else
       AKANTU_EXCEPTION(
           "The solver \""
           << default_solver
           << "\" was not created, it cannot be set as default solver");
   }
 }
 
 /* -------------------------------------------------------------------------- */
 TimeStepSolver & ModelSolver::getSolver(const ID & solver_id) {
   ID tmp_solver_id = solver_id;
   if (tmp_solver_id == "")
     tmp_solver_id = this->default_solver_id;
 
   TimeStepSolver & tss = this->dof_manager->getTimeStepSolver(tmp_solver_id);
   return tss;
 }
 
 /* -------------------------------------------------------------------------- */
 const TimeStepSolver & ModelSolver::getSolver(const ID & solver_id) const {
   ID tmp_solver_id = solver_id;
   if (solver_id == "")
     tmp_solver_id = this->default_solver_id;
 
   const TimeStepSolver & tss =
       this->dof_manager->getTimeStepSolver(tmp_solver_id);
   return tss;
 }
 
 /* -------------------------------------------------------------------------- */
 TimeStepSolver & ModelSolver::getTimeStepSolver(const ID & solver_id) {
   return this->getSolver(solver_id);
 }
 
 /* -------------------------------------------------------------------------- */
 const TimeStepSolver &
 ModelSolver::getTimeStepSolver(const ID & solver_id) const {
   return this->getSolver(solver_id);
 }
 
 /* -------------------------------------------------------------------------- */
 NonLinearSolver & ModelSolver::getNonLinearSolver(const ID & solver_id) {
   return this->getSolver(solver_id).getNonLinearSolver();
 }
 /* -------------------------------------------------------------------------- */
 const NonLinearSolver &
 ModelSolver::getNonLinearSolver(const ID & solver_id) const {
   return this->getSolver(solver_id).getNonLinearSolver();
 }
 
 /* -------------------------------------------------------------------------- */
 bool ModelSolver::hasSolver(const ID & solver_id) const {
   ID tmp_solver_id = solver_id;
   if (solver_id == "")
     tmp_solver_id = this->default_solver_id;
 
   if (not this->dof_manager) {
     AKANTU_EXCEPTION("No DOF manager was initialized");
   }
   return this->dof_manager->hasTimeStepSolver(tmp_solver_id);
 }
 
 /* -------------------------------------------------------------------------- */
 void ModelSolver::setDefaultSolver(const ID & solver_id) {
   AKANTU_DEBUG_ASSERT(
       this->hasSolver(solver_id),
       "Cannot set the default solver to a solver that does not exists");
   this->default_solver_id = solver_id;
 }
 
 /* -------------------------------------------------------------------------- */
 void ModelSolver::solveStep(const ID & solver_id) {
   AKANTU_DEBUG_IN();
 
   TimeStepSolver & tss = this->getSolver(solver_id);
   // make one non linear solve
   tss.solveStep(*this);
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void ModelSolver::getNewSolver(const ID & solver_id,
                                TimeStepSolverType time_step_solver_type,
                                NonLinearSolverType non_linear_solver_type) {
   if (this->default_solver_id == "") {
     this->default_solver_id = solver_id;
   }
 
   if (non_linear_solver_type == _nls_auto) {
     switch (time_step_solver_type) {
     case _tsst_dynamic:
     case _tsst_static:
       non_linear_solver_type = _nls_newton_raphson;
       break;
     case _tsst_dynamic_lumped:
       non_linear_solver_type = _nls_lumped;
       break;
     case _tsst_not_defined:
       AKANTU_EXCEPTION(time_step_solver_type
                        << " is not a valid time step solver type");
       break;
     }
   }
 
   this->initSolver(time_step_solver_type, non_linear_solver_type);
 
   NonLinearSolver & nls = this->dof_manager->getNewNonLinearSolver(
       solver_id, non_linear_solver_type);
 
   this->dof_manager->getNewTimeStepSolver(solver_id, time_step_solver_type,
                                           nls);
 }
 
 /* -------------------------------------------------------------------------- */
 Real ModelSolver::getTimeStep(const ID & solver_id) const {
   const TimeStepSolver & tss = this->getSolver(solver_id);
 
   return tss.getTimeStep();
 }
 
 /* -------------------------------------------------------------------------- */
 void ModelSolver::setTimeStep(Real time_step, const ID & solver_id) {
   TimeStepSolver & tss = this->getSolver(solver_id);
 
   return tss.setTimeStep(time_step);
 }
 
 /* -------------------------------------------------------------------------- */
 void ModelSolver::setIntegrationScheme(
     const ID & solver_id, const ID & dof_id,
     const IntegrationSchemeType & integration_scheme_type,
     IntegrationScheme::SolutionType solution_type) {
   TimeStepSolver & tss = this->dof_manager->getTimeStepSolver(solver_id);
 
   tss.setIntegrationScheme(dof_id, integration_scheme_type, solution_type);
 }
 
 /* -------------------------------------------------------------------------- */
 bool ModelSolver::hasDefaultSolver() const {
   return (this->default_solver_id != "");
 }
 
 /* -------------------------------------------------------------------------- */
 bool ModelSolver::hasIntegrationScheme(const ID & solver_id,
                                        const ID & dof_id) const {
   TimeStepSolver & tss = this->dof_manager->getTimeStepSolver(solver_id);
   return tss.hasIntegrationScheme(dof_id);
 }
 
 /* -------------------------------------------------------------------------- */
 void ModelSolver::predictor() {}
 
 /* -------------------------------------------------------------------------- */
 void ModelSolver::corrector() {}
 
 /* -------------------------------------------------------------------------- */
 TimeStepSolverType ModelSolver::getDefaultSolverType() const {
   return _tsst_dynamic_lumped;
 }
 
 /* -------------------------------------------------------------------------- */
 ModelSolverOptions
 ModelSolver::getDefaultSolverOptions(__attribute__((unused))
                                      const TimeStepSolverType & type) const {
   ModelSolverOptions options;
   options.non_linear_solver_type = _nls_auto;
   return options;
 }
 
 } // namespace akantu
diff --git a/src/model/model_solver.hh b/src/model/model_solver.hh
index 4c6179ad9..7b2c61c21 100644
--- a/src/model/model_solver.hh
+++ b/src/model/model_solver.hh
@@ -1,193 +1,194 @@
 /**
  * @file   model_solver.hh
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
- * @date   Wed Jul 22 10:53:10 2015
+ * @date creation: Fri Jun 18 2010
+ * @date last modification: Wed Jan 31 2018
  *
  * @brief  Class regrouping the common solve interface to the different models
  *
  * @section LICENSE
  *
- * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * 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
+ * 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
+ * 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 "integration_scheme.hh"
 #include "parsable.hh"
 #include "solver_callback.hh"
 #include "synchronizer_registry.hh"
 /* -------------------------------------------------------------------------- */
 #include <set>
 /* -------------------------------------------------------------------------- */
 
 #ifndef __AKANTU_MODEL_SOLVER_HH__
 #define __AKANTU_MODEL_SOLVER_HH__
 
 namespace akantu {
 class Mesh;
 class DOFManager;
 class TimeStepSolver;
 class NonLinearSolver;
 struct ModelSolverOptions;
 }
 
 namespace akantu {
 
 class ModelSolver : public Parsable,
                     public SolverCallback,
                     public SynchronizerRegistry {
   /* ------------------------------------------------------------------------ */
   /* Constructors/Destructors                                                 */
   /* ------------------------------------------------------------------------ */
 public:
   ModelSolver(Mesh & mesh, const ModelType & type, const ID & id,
               UInt memory_id);
   ~ModelSolver() override;
 
   /// initialize the dof manager based on solver type passed in the input file
   void initDOFManager();
   /// initialize the dof manager based on the used chosen solver type
   void initDOFManager(const ID & solver_type);
 
 protected:
   /// initialize the dof manager based on the used chosen solver type
   void initDOFManager(const ParserSection & section, const ID & solver_type);
 
   /// Callback for the model to instantiate the matricees when needed
   virtual void initSolver(TimeStepSolverType /*time_step_solver_type*/,
                           NonLinearSolverType /*non_linear_solver_type*/) {}
 
   /// get the section in the input file (if it exsits) corresponding to this
   /// model
   std::tuple<ParserSection, bool> getParserSection();
 
   /* ------------------------------------------------------------------------ */
   /* Methods                                                                  */
   /* ------------------------------------------------------------------------ */
 public:
   /// solve a step using a given pre instantiated time step solver and
   /// nondynamic linear solver
   virtual void solveStep(const ID & solver_id = "");
 
   /// Initialize a time solver that can be used afterwards with its id
   void getNewSolver(const ID & solver_id,
                     TimeStepSolverType time_step_solver_type,
                     NonLinearSolverType non_linear_solver_type = _nls_auto);
 
   /// set an integration scheme for a given dof and a given solver
   void
   setIntegrationScheme(const ID & solver_id, const ID & dof_id,
                        const IntegrationSchemeType & integration_scheme_type,
                        IntegrationScheme::SolutionType solution_type =
                            IntegrationScheme::_not_defined);
 
   /// set an externally instantiated integration scheme
   void setIntegrationScheme(const ID & solver_id, const ID & dof_id,
                             IntegrationScheme & integration_scheme,
                             IntegrationScheme::SolutionType solution_type =
                                 IntegrationScheme::_not_defined);
 
   /* ------------------------------------------------------------------------ */
   /* SolverCallback interface                                                 */
   /* ------------------------------------------------------------------------ */
 public:
   /// Predictor interface for the callback
   void predictor() override;
 
   /// Corrector interface for the callback
   void corrector() override;
 
   /* ------------------------------------------------------------------------ */
   /* Accessors                                                                */
   /* ------------------------------------------------------------------------ */
 public:
   /// Default time step solver to instantiate for this model
   virtual TimeStepSolverType getDefaultSolverType() const;
 
   /// Default configurations for a given time step solver
   virtual ModelSolverOptions
   getDefaultSolverOptions(const TimeStepSolverType & type) const;
 
   /// get access to the internal dof manager
   DOFManager & getDOFManager() { return *this->dof_manager; }
 
   /// get the time step of a given solver
   Real getTimeStep(const ID & solver_id = "") const;
   /// set the time step of a given solver
   virtual void setTimeStep(Real time_step, const ID & solver_id = "");
 
   /// set the parameter 'param' of the solver 'solver_id'
   // template <typename T>
   // void set(const ID & param, const T & value, const ID & solver_id = "");
 
   /// get the parameter 'param' of the solver 'solver_id'
   // const Parameter & get(const ID & param, const ID & solver_id = "") const;
 
   /// answer to the question "does the solver exists ?"
   bool hasSolver(const ID & solver_id) const;
 
   /// changes the current default solver
   void setDefaultSolver(const ID & solver_id);
 
   /// is a default solver defined
   bool hasDefaultSolver() const;
 
   /// is an integration scheme set for a given solver and a given dof
   bool hasIntegrationScheme(const ID & solver_id, const ID & dof_id) const;
 
   TimeStepSolver & getTimeStepSolver(const ID & solver_id = "");
   NonLinearSolver & getNonLinearSolver(const ID & solver_id = "");
 
   const TimeStepSolver & getTimeStepSolver(const ID & solver_id = "") const;
   const NonLinearSolver & getNonLinearSolver(const ID & solver_id = "") const;
 
 private:
   TimeStepSolver & getSolver(const ID & solver_id);
   const TimeStepSolver & getSolver(const ID & solver_id) const;
 
   /* ------------------------------------------------------------------------ */
   /* Class Members                                                            */
   /* ------------------------------------------------------------------------ */
 protected:
   ModelType model_type;
 
 private:
   ID parent_id;
   UInt parent_memory_id;
 
   /// Underlying mesh
   Mesh & mesh;
 
   /// Underlying dof_manager (the brain...)
   std::unique_ptr<DOFManager> dof_manager;
 
   /// Default time step solver to use
   ID default_solver_id;
 };
 
 struct ModelSolverOptions {
   NonLinearSolverType non_linear_solver_type;
   std::map<ID, IntegrationSchemeType> integration_scheme_type;
   std::map<ID, IntegrationScheme::SolutionType> solution_type;
 };
 
 } // akantu
 
 #endif /* __AKANTU_MODEL_SOLVER_HH__ */
diff --git a/src/model/non_linear_solver.cc b/src/model/non_linear_solver.cc
index a6333d41e..0fcf58024 100644
--- a/src/model/non_linear_solver.cc
+++ b/src/model/non_linear_solver.cc
@@ -1,78 +1,79 @@
 /**
  * @file   non_linear_solver.cc
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
- * @date   Tue Oct 13 15:34:43 2015
+ * @date creation: Tue Jul 20 2010
+ * @date last modification: Wed Feb 21 2018
  *
  * @brief  Implementation of the base class NonLinearSolver
  *
  * @section LICENSE
  *
- * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * Copyright (©) 2015-2018 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
- * terms  of the  GNU Lesser  General Public  License as  published by  the Free
+ * 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
+ * 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 "non_linear_solver.hh"
 #include "dof_manager.hh"
 #include "solver_callback.hh"
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 NonLinearSolver::NonLinearSolver(
     DOFManager & dof_manager,
     const NonLinearSolverType & non_linear_solver_type, const ID & id,
     UInt memory_id)
     : Memory(id, memory_id), Parsable(ParserType::_non_linear_solver, id),
       _dof_manager(dof_manager),
       non_linear_solver_type(non_linear_solver_type) {
 
   this->registerParam("type", this->non_linear_solver_type, _pat_parsable,
                       "Non linear solver type");
 }
 
 /* -------------------------------------------------------------------------- */
 NonLinearSolver::~NonLinearSolver() = default;
 
 /* -------------------------------------------------------------------------- */
 void NonLinearSolver::checkIfTypeIsSupported() {
   if (this->supported_type.find(this->non_linear_solver_type) ==
       this->supported_type.end()) {
     AKANTU_EXCEPTION("The resolution method "
                      << this->non_linear_solver_type
                      << " is not implemented in the non linear solver "
                      << this->id << "!");
   }
 }
 
 /* -------------------------------------------------------------------------- */
 void NonLinearSolver::assembleResidual(SolverCallback & solver_callback) {
   if (solver_callback.canSplitResidual() and
       non_linear_solver_type == _nls_linear) {
     this->_dof_manager.clearResidual();
     solver_callback.assembleResidual("external");
     this->_dof_manager.assembleMatMulDOFsToResidual("K", -1.);
     solver_callback.assembleResidual("inertial");
   } else {
     solver_callback.assembleResidual();
   }
 }
 
 } // akantu
diff --git a/src/model/non_linear_solver.hh b/src/model/non_linear_solver.hh
index 2cea85168..ef6d5a624 100644
--- a/src/model/non_linear_solver.hh
+++ b/src/model/non_linear_solver.hh
@@ -1,98 +1,99 @@
 /**
  * @file   non_linear_solver.hh
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
- * @date   Mon Aug 24 23:48:41 2015
+ * @date creation: Fri Jun 18 2010
+ * @date last modification: Wed Feb 21 2018
  *
  * @brief  Non linear solver interface
  *
  * @section LICENSE
  *
- * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * 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
+ * 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
+ * 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 "aka_memory.hh"
 #include "parsable.hh"
 /* -------------------------------------------------------------------------- */
 #include <set>
 /* -------------------------------------------------------------------------- */
 
 #ifndef __AKANTU_NON_LINEAR_SOLVER_HH__
 #define __AKANTU_NON_LINEAR_SOLVER_HH__
 
 namespace akantu {
 class DOFManager;
 class SolverCallback;
 }
 
 namespace akantu {
 
 class NonLinearSolver : private Memory, public Parsable {
   /* ------------------------------------------------------------------------ */
   /* Constructors/Destructors                                                 */
   /* ------------------------------------------------------------------------ */
 public:
   NonLinearSolver(DOFManager & dof_manager,
                   const NonLinearSolverType & non_linear_solver_type,
                   const ID & id = "non_linear_solver", UInt memory_id = 0);
   ~NonLinearSolver() override;
 
   /* ------------------------------------------------------------------------ */
   /* Methods                                                                  */
   /* ------------------------------------------------------------------------ */
 public:
   /// solve the system described by the jacobian matrix, and rhs contained in
   /// the dof manager
   virtual void solve(SolverCallback & callback) = 0;
 
 protected:
   void checkIfTypeIsSupported();
 
   void assembleResidual(SolverCallback & callback);
 
   /* ------------------------------------------------------------------------ */
   /* Class Members                                                            */
   /* ------------------------------------------------------------------------ */
 protected:
   DOFManager & _dof_manager;
 
   /// type of non linear solver
   NonLinearSolverType non_linear_solver_type;
 
   /// list of supported non linear solver types
   std::set<NonLinearSolverType> supported_type;
 };
 
 namespace debug {
   class NLSNotConvergedException : public Exception {
   public:
     NLSNotConvergedException(Real threshold, UInt niter, Real error)
         : Exception("The non linear solver did not converge."),
           threshold(threshold), niter(niter), error(error) {}
     Real threshold;
     UInt niter;
     Real error;
   };
 }
 
 } // akantu
 
 #endif /* __AKANTU_NON_LINEAR_SOLVER_HH__ */
diff --git a/src/model/non_linear_solver_callback.hh b/src/model/non_linear_solver_callback.hh
index 43895ca8e..45fe7cddd 100644
--- a/src/model/non_linear_solver_callback.hh
+++ b/src/model/non_linear_solver_callback.hh
@@ -1,60 +1,61 @@
 /**
  * @file   non_linear_solver_callback.hh
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
- * @date   Mon Sep 28 18:48:21 2015
+ * @date creation: Fri Jun 18 2010
+ * @date last modification: Tue Feb 20 2018
  *
  * @brief  Interface to implement for the non linear solver to work
  *
  * @section LICENSE
  *
- * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * 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
+ * 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
+ * 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_NON_LINEAR_SOLVER_CALLBACK_HH__
 #define __AKANTU_NON_LINEAR_SOLVER_CALLBACK_HH__
 
 namespace akantu {
 
 class NonLinearSolverCallback {
   /* ------------------------------------------------------------------------ */
   /* Methods                                                                  */
   /* ------------------------------------------------------------------------ */
 public:
   /// callback to assemble the Jacobian Matrix
   virtual void assembleJacobian() { AKANTU_TO_IMPLEMENT(); }
 
   /// callback to assemble the residual (rhs)
   virtual void assembleResidual() { AKANTU_TO_IMPLEMENT(); }
 
   /* ------------------------------------------------------------------------ */
   /* Dynamic simulations part                                                 */
   /* ------------------------------------------------------------------------ */
   /// callback for the predictor (in case of dynamic simulation)
   virtual void predictor() { AKANTU_TO_IMPLEMENT(); }
 
   /// callback for the corrector (in case of dynamic simulation)
   virtual void corrector() { AKANTU_TO_IMPLEMENT(); }
 };
 
 } // akantu
 
 #endif /* __AKANTU_NON_LINEAR_SOLVER_CALLBACK_HH__ */
diff --git a/src/model/non_linear_solver_default.hh b/src/model/non_linear_solver_default.hh
index 3f7dad3e2..7cc1f2b53 100644
--- a/src/model/non_linear_solver_default.hh
+++ b/src/model/non_linear_solver_default.hh
@@ -1,44 +1,45 @@
 /**
  * @file   non_linear_solver_default.hh
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
- * @date   Tue Feb 16 10:37:01 2016
+ * @date creation: Fri Jun 18 2010
+ * @date last modification: Wed Jan 31 2018
  *
  * @brief  Include for the default non linear solvers
  *
  * @section LICENSE
  *
- * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * 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
+ * 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
+ * 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"
 /* -------------------------------------------------------------------------- */
 
 #ifndef __AKANTU_NON_LINEAR_SOLVER_DEFAULT_HH__
 #define __AKANTU_NON_LINEAR_SOLVER_DEFAULT_HH__
 
 #if defined(AKANTU_IMPLICIT)
 #include "non_linear_solver_linear.hh"
 #include "non_linear_solver_newton_raphson.hh"
 #endif
 
 #include "non_linear_solver_lumped.hh"
 
 #endif /* __AKANTU_NON_LINEAR_SOLVER_DEFAULT_HH__ */
diff --git a/src/model/non_linear_solver_linear.cc b/src/model/non_linear_solver_linear.cc
index 4a5704d52..6530cc27d 100644
--- a/src/model/non_linear_solver_linear.cc
+++ b/src/model/non_linear_solver_linear.cc
@@ -1,73 +1,74 @@
 /**
  * @file   non_linear_solver_linear.cc
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
- * @date   Tue Aug 25 00:57:00 2015
+ * @date creation: Tue Jul 20 2010
+ * @date last modification: Wed Feb 21 2018
  *
  * @brief  Implementation of the default NonLinearSolver
  *
  * @section LICENSE
  *
- * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * 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
+ * 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
+ * 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 "non_linear_solver_linear.hh"
 #include "dof_manager_default.hh"
 #include "solver_callback.hh"
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 NonLinearSolverLinear::NonLinearSolverLinear(
     DOFManagerDefault & dof_manager,
     const NonLinearSolverType & non_linear_solver_type, const ID & id,
     UInt memory_id)
     : NonLinearSolver(dof_manager, non_linear_solver_type, id, memory_id),
       dof_manager(dof_manager),
       solver(dof_manager, "J", id + ":sparse_solver", memory_id) {
 
   this->supported_type.insert(_nls_linear);
   this->checkIfTypeIsSupported();
 }
 
 /* -------------------------------------------------------------------------- */
 NonLinearSolverLinear::~NonLinearSolverLinear() = default;
 
 /* ------------------------------------------------------------------------ */
 void NonLinearSolverLinear::solve(SolverCallback & solver_callback) {
   this->dof_manager.updateGlobalBlockedDofs();
 
   solver_callback.predictor();
 
   solver_callback.assembleMatrix("J");
 
   // Residual computed after J to allow the model to use K to compute the
   // residual
   this->assembleResidual(solver_callback);
 
   this->solver.solve();
 
   solver_callback.corrector();
 }
 
 /* -------------------------------------------------------------------------- */
 
 } // akantu
diff --git a/src/model/non_linear_solver_linear.hh b/src/model/non_linear_solver_linear.hh
index d402ec16e..155fb8246 100644
--- a/src/model/non_linear_solver_linear.hh
+++ b/src/model/non_linear_solver_linear.hh
@@ -1,78 +1,80 @@
 /**
  * @file   non_linear_solver_linear.hh
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
- * @date   Tue Aug 25 00:48:07 2015
+ * @date creation: Fri Jun 18 2010
+ * @date last modification: Wed Jan 31 2018
  *
- * @brief Default implementation of NonLinearSolver, in case no external library
+ * @brief  Default implementation of NonLinearSolver, in case no external
+ * library
  * is there to do the job
  *
  * @section LICENSE
  *
- * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * 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
+ * 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
+ * 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 "non_linear_solver.hh"
 #include "sparse_solver_mumps.hh"
 /* -------------------------------------------------------------------------- */
 
 #ifndef __AKANTU_NON_LINEAR_SOLVER_LINEAR_HH__
 #define __AKANTU_NON_LINEAR_SOLVER_LINEAR_HH__
 
 namespace akantu {
 class DOFManagerDefault;
 }
 
 namespace akantu {
 
 class NonLinearSolverLinear : public NonLinearSolver {
   /* ------------------------------------------------------------------------ */
   /* Constructors/Destructors                                                 */
   /* ------------------------------------------------------------------------ */
 public:
   NonLinearSolverLinear(DOFManagerDefault & dof_manager,
                         const NonLinearSolverType & non_linear_solver_type,
                         const ID & id = "non_linear_solver_linear",
                         UInt memory_id = 0);
   ~NonLinearSolverLinear() override;
 
   /* ------------------------------------------------------------------------ */
   /* Methods                                                                  */
   /* ------------------------------------------------------------------------ */
 public:
   /// Function that solve the non linear system described by the dof manager and
   /// the solver callback functions
   void solve(SolverCallback & solver_callback) override;
 
   AKANTU_GET_MACRO_NOT_CONST(Solver, solver, SparseSolverMumps &);
   AKANTU_GET_MACRO(Solver, solver, const SparseSolverMumps &);
   /* ------------------------------------------------------------------------ */
   /* Class Members                                                            */
   /* ------------------------------------------------------------------------ */
 protected:
   DOFManagerDefault & dof_manager;
 
   /// Sparse solver used for the linear solves
   SparseSolverMumps solver;
 };
 
 } // akantu
 
 #endif /* __AKANTU_NON_LINEAR_SOLVER_LINEAR_HH__ */
diff --git a/src/model/non_linear_solver_lumped.cc b/src/model/non_linear_solver_lumped.cc
index 1b0f70487..69e3e3a0f 100644
--- a/src/model/non_linear_solver_lumped.cc
+++ b/src/model/non_linear_solver_lumped.cc
@@ -1,102 +1,103 @@
 /**
  * @file   non_linear_solver_lumped.cc
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
- * @date   Tue Aug 25 00:57:00 2015
+ * @date creation: Tue Feb 16 2016
+ * @date last modification: Wed Jan 31 2018
  *
  * @brief  Implementation of the default NonLinearSolver
  *
  * @section LICENSE
  *
- * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * 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
+ * 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
+ * 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 "non_linear_solver_lumped.hh"
 #include "communicator.hh"
 #include "dof_manager_default.hh"
 #include "solver_callback.hh"
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 NonLinearSolverLumped::NonLinearSolverLumped(
     DOFManagerDefault & dof_manager,
     const NonLinearSolverType & non_linear_solver_type, const ID & id,
     UInt memory_id)
     : NonLinearSolver(dof_manager, non_linear_solver_type, id, memory_id),
       dof_manager(dof_manager) {
   this->supported_type.insert(_nls_lumped);
   this->checkIfTypeIsSupported();
 
   this->registerParam("b_a2x", this->alpha, 1., _pat_parsmod,
                       "Conversion coefficient between x and A^{-1} b");
 }
 
 /* -------------------------------------------------------------------------- */
 NonLinearSolverLumped::~NonLinearSolverLumped() = default;
 
 /* ------------------------------------------------------------------------ */
 void NonLinearSolverLumped::solve(SolverCallback & solver_callback) {
   this->dof_manager.updateGlobalBlockedDofs();
   solver_callback.predictor();
 
   auto & x = this->dof_manager.getGlobalSolution();
   const auto & b = this->dof_manager.getResidual();
 
   x.resize(b.size());
 
   this->dof_manager.updateGlobalBlockedDofs();
   const Array<bool> & blocked_dofs = this->dof_manager.getGlobalBlockedDOFs();
 
   solver_callback.assembleResidual();
 
   const auto & A = this->dof_manager.getLumpedMatrix("M");
   // alpha is the conversion factor from from force/mass to acceleration needed
   // in model coupled with atomistic \todo find a way to define alpha per dof
   // type
 
   this->solveLumped(A, x, b, blocked_dofs, alpha);
   this->dof_manager.splitSolutionPerDOFs();
 
   solver_callback.corrector();
 }
 
 /* -------------------------------------------------------------------------- */
 void NonLinearSolverLumped::solveLumped(const Array<Real> & A, Array<Real> & x,
                                         const Array<Real> & b,
                                         const Array<bool> & blocked_dofs,
                                         Real alpha) {
   auto A_it = A.begin();
   auto x_it = x.begin();
   auto x_end = x.end();
   auto b_it = b.begin();
   auto blocked_it = blocked_dofs.begin();
 
   for (; x_it != x_end; ++x_it, ++b_it, ++A_it, ++blocked_it) {
     if (!(*blocked_it)) {
       *x_it = alpha * (*b_it / *A_it);
     }
   }
 }
 
 /* -------------------------------------------------------------------------- */
 
 } // akantu
diff --git a/src/model/non_linear_solver_lumped.hh b/src/model/non_linear_solver_lumped.hh
index b27623579..8241391b0 100644
--- a/src/model/non_linear_solver_lumped.hh
+++ b/src/model/non_linear_solver_lumped.hh
@@ -1,79 +1,81 @@
 /**
  * @file   non_linear_solver_lumped.hh
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
- * @date   Tue Aug 25 00:48:07 2015
+ * @date creation: Fri Jun 18 2010
+ * @date last modification: Wed Jan 31 2018
  *
- * @brief Default implementation of NonLinearSolver, in case no external library
+ * @brief  Default implementation of NonLinearSolver, in case no external
+ * library
  * is there to do the job
  *
  * @section LICENSE
  *
- * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * 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
+ * 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
+ * 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 "non_linear_solver.hh"
 /* -------------------------------------------------------------------------- */
 
 #ifndef __AKANTU_NON_LINEAR_SOLVER_LUMPED_HH__
 #define __AKANTU_NON_LINEAR_SOLVER_LUMPED_HH__
 
 namespace akantu {
 class DOFManagerDefault;
 }
 
 namespace akantu {
 
 class NonLinearSolverLumped : public NonLinearSolver {
   /* ------------------------------------------------------------------------ */
   /* Constructors/Destructors                                                 */
   /* ------------------------------------------------------------------------ */
 public:
   NonLinearSolverLumped(DOFManagerDefault & dof_manager,
                         const NonLinearSolverType & non_linear_solver_type,
                         const ID & id = "non_linear_solver_lumped",
                         UInt memory_id = 0);
   ~NonLinearSolverLumped() override;
 
   /* ------------------------------------------------------------------------ */
   /* Methods                                                                  */
   /* ------------------------------------------------------------------------ */
 public:
   /// Function that solve the non linear system described by the dof manager and
   /// the solver callback functions
   void solve(SolverCallback & solver_callback) override;
 
   static void solveLumped(const Array<Real> & A, Array<Real> & x,
                           const Array<Real> & b,
                           const Array<bool> & blocked_dofs, Real alpha);
 
   /* ------------------------------------------------------------------------ */
   /* Class Members                                                            */
   /* ------------------------------------------------------------------------ */
 private:
   DOFManagerDefault & dof_manager;
 
   /// Coefficient to apply between x and A^{-1} b
   Real alpha;
 };
 
 } // akantu
 
 #endif /* __AKANTU_NON_LINEAR_SOLVER_LUMPED_HH__ */
diff --git a/src/model/non_linear_solver_newton_raphson.cc b/src/model/non_linear_solver_newton_raphson.cc
index 540ac8dd0..67618fff6 100644
--- a/src/model/non_linear_solver_newton_raphson.cc
+++ b/src/model/non_linear_solver_newton_raphson.cc
@@ -1,191 +1,192 @@
 /**
  * @file   non_linear_solver_newton_raphson.cc
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
- * @date   Tue Aug 25 00:57:00 2015
+ * @date creation: Tue Sep 15 2015
+ * @date last modification: Wed Feb 21 2018
  *
  * @brief  Implementation of the default NonLinearSolver
  *
  * @section LICENSE
  *
- * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * Copyright (©) 2015-2018 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
- * terms  of the  GNU Lesser  General Public  License as  published by  the Free
+ * 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
+ * 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 "non_linear_solver_newton_raphson.hh"
 #include "communicator.hh"
 #include "dof_manager_default.hh"
 #include "solver_callback.hh"
 #include "sparse_solver_mumps.hh"
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 NonLinearSolverNewtonRaphson::NonLinearSolverNewtonRaphson(
     DOFManagerDefault & dof_manager,
     const NonLinearSolverType & non_linear_solver_type, const ID & id,
     UInt memory_id)
     : NonLinearSolver(dof_manager, non_linear_solver_type, id, memory_id),
       dof_manager(dof_manager),
       solver(std::make_unique<SparseSolverMumps>(
           dof_manager, "J", id + ":sparse_solver", memory_id)) {
 
   this->supported_type.insert(_nls_newton_raphson_modified);
   this->supported_type.insert(_nls_newton_raphson);
   this->supported_type.insert(_nls_linear);
 
   this->checkIfTypeIsSupported();
 
   this->registerParam("threshold", convergence_criteria, 1e-10, _pat_parsmod,
                       "Threshold to consider results as converged");
   this->registerParam("convergence_type", convergence_criteria_type,
                       _scc_solution, _pat_parsmod,
                       "Type of convergence criteria");
   this->registerParam("max_iterations", max_iterations, 10, _pat_parsmod,
                       "Max number of iterations");
   this->registerParam("error", error, _pat_readable, "Last reached error");
   this->registerParam("nb_iterations", n_iter, _pat_readable,
                       "Last reached number of iterations");
   this->registerParam("converged", converged, _pat_readable,
                       "Did last solve converged");
   this->registerParam("force_linear_recompute", force_linear_recompute, true,
                       _pat_modifiable,
                       "Force reassembly of the jacobian matrix");
 }
 
 /* -------------------------------------------------------------------------- */
 NonLinearSolverNewtonRaphson::~NonLinearSolverNewtonRaphson() = default;
 
 /* ------------------------------------------------------------------------ */
 void NonLinearSolverNewtonRaphson::solve(SolverCallback & solver_callback) {
   this->dof_manager.updateGlobalBlockedDofs();
 
   solver_callback.predictor();
 
   if (non_linear_solver_type == _nls_linear and
       solver_callback.canSplitResidual())
     solver_callback.assembleMatrix("K");
 
   this->assembleResidual(solver_callback);
 
   if (this->non_linear_solver_type == _nls_newton_raphson_modified ||
       (this->non_linear_solver_type == _nls_linear &&
        this->force_linear_recompute)) {
     solver_callback.assembleMatrix("J");
     this->force_linear_recompute = false;
   }
 
   this->n_iter = 0;
   this->converged = false;
 
   if (this->convergence_criteria_type == _scc_residual) {
     this->converged = this->testConvergence(this->dof_manager.getResidual());
 
     if (this->converged)
       return;
   }
 
   do {
     if (this->non_linear_solver_type == _nls_newton_raphson)
       solver_callback.assembleMatrix("J");
 
     this->solver->solve();
 
     solver_callback.corrector();
 
     // EventManager::sendEvent(NonLinearSolver::AfterSparseSolve(method));
 
     if (this->convergence_criteria_type == _scc_residual) {
       this->assembleResidual(solver_callback);
       this->converged = this->testConvergence(this->dof_manager.getResidual());
     } else {
       this->converged =
           this->testConvergence(this->dof_manager.getGlobalSolution());
     }
 
     if (this->convergence_criteria_type == _scc_solution and
         not this->converged)
       this->assembleResidual(solver_callback);
     // this->dump();
 
     this->n_iter++;
     AKANTU_DEBUG_INFO(
         "[" << this->convergence_criteria_type << "] Convergence iteration "
             << std::setw(std::log10(this->max_iterations)) << this->n_iter
             << ": error " << this->error << (this->converged ? " < " : " > ")
             << this->convergence_criteria);
 
   } while (not this->converged and this->n_iter < this->max_iterations);
 
   // this makes sure that you have correct strains and stresses after the
   // solveStep function (e.g., for dumping)
   if (this->convergence_criteria_type == _scc_solution)
     this->assembleResidual(solver_callback);
 
   if (this->converged) {
     // this->sendEvent(NonLinearSolver::ConvergedEvent(method));
   } else if (this->n_iter == this->max_iterations) {
     AKANTU_CUSTOM_EXCEPTION(debug::NLSNotConvergedException(
         this->convergence_criteria, this->n_iter, this->error));
 
     AKANTU_DEBUG_WARNING("[" << this->convergence_criteria_type
                              << "] Convergence not reached after "
                              << std::setw(std::log10(this->max_iterations))
                              << this->n_iter << " iteration"
                              << (this->n_iter == 1 ? "" : "s") << "!");
   }
 
   return;
 }
 
 /* -------------------------------------------------------------------------- */
 bool NonLinearSolverNewtonRaphson::testConvergence(const Array<Real> & array) {
   AKANTU_DEBUG_IN();
 
   const Array<bool> & blocked_dofs = this->dof_manager.getGlobalBlockedDOFs();
 
   UInt nb_degree_of_freedoms = array.size();
 
   auto arr_it = array.begin();
   auto bld_it = blocked_dofs.begin();
 
   Real norm = 0.;
   for (UInt n = 0; n < nb_degree_of_freedoms; ++n, ++arr_it, ++bld_it) {
     bool is_local_node = this->dof_manager.isLocalOrMasterDOF(n);
     if ((!*bld_it) && is_local_node) {
       norm += *arr_it * *arr_it;
     }
   }
 
   dof_manager.getCommunicator().allReduce(norm, SynchronizerOperation::_sum);
 
   norm = std::sqrt(norm);
 
   AKANTU_DEBUG_ASSERT(!Math::isnan(norm),
                       "Something went wrong in the solve phase");
 
   this->error = norm;
 
   return (error < this->convergence_criteria);
 }
 
 /* -------------------------------------------------------------------------- */
 
 } // akantu
diff --git a/src/model/non_linear_solver_newton_raphson.hh b/src/model/non_linear_solver_newton_raphson.hh
index aff6ee6b8..f55719533 100644
--- a/src/model/non_linear_solver_newton_raphson.hh
+++ b/src/model/non_linear_solver_newton_raphson.hh
@@ -1,104 +1,106 @@
 /**
  * @file   non_linear_solver_newton_raphson.hh
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
- * @date   Tue Aug 25 00:48:07 2015
+ * @date creation: Fri Jun 18 2010
+ * @date last modification: Wed Jan 31 2018
  *
- * @brief Default implementation of NonLinearSolver, in case no external library
+ * @brief  Default implementation of NonLinearSolver, in case no external
+ * library
  * is there to do the job
  *
  * @section LICENSE
  *
- * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * 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
+ * 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
+ * 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 "non_linear_solver.hh"
 /* -------------------------------------------------------------------------- */
 
 #ifndef __AKANTU_NON_LINEAR_SOLVER_NEWTON_RAPHSON_HH__
 #define __AKANTU_NON_LINEAR_SOLVER_NEWTON_RAPHSON_HH__
 
 namespace akantu {
 class DOFManagerDefault;
 class SparseSolverMumps;
 }
 
 namespace akantu {
 
 class NonLinearSolverNewtonRaphson : public NonLinearSolver {
   /* ------------------------------------------------------------------------ */
   /* Constructors/Destructors                                                 */
   /* ------------------------------------------------------------------------ */
 public:
   NonLinearSolverNewtonRaphson(
       DOFManagerDefault & dof_manager,
       const NonLinearSolverType & non_linear_solver_type,
       const ID & id = "non_linear_solver_newton_raphson", UInt memory_id = 0);
   ~NonLinearSolverNewtonRaphson() override;
 
   /* ------------------------------------------------------------------------ */
   /* Methods                                                                  */
   /* ------------------------------------------------------------------------ */
 public:
   /// Function that solve the non linear system described by the dof manager and
   /// the solver callback functions
   void solve(SolverCallback & solver_callback) override;
 
   AKANTU_GET_MACRO_NOT_CONST(Solver, *solver, SparseSolverMumps &);
   AKANTU_GET_MACRO(Solver, *solver, const SparseSolverMumps &);
 
 protected:
   /// test the convergence compare norm of array to convergence_criteria
   bool testConvergence(const Array<Real> & array);
 
   /* ------------------------------------------------------------------------ */
   /* Class Members                                                            */
   /* ------------------------------------------------------------------------ */
 private:
   DOFManagerDefault & dof_manager;
 
   /// Sparse solver used for the linear solves
   std::unique_ptr<SparseSolverMumps> solver;
 
   /// Type of convergence criteria
   SolveConvergenceCriteria convergence_criteria_type;
 
   /// convergence threshold
   Real convergence_criteria;
 
   /// Max number of iterations
   int max_iterations;
 
   /// Number of iterations at last solve call
   int n_iter{0};
 
   /// Convergence error at last solve call
   Real error{0.};
 
   /// Did the last call to solve reached convergence
   bool converged{false};
 
   /// Force a re-computation of the jacobian matrix
   bool force_linear_recompute{true};
 };
 
 } // akantu
 
 #endif /* __AKANTU_NON_LINEAR_SOLVER_NEWTON_RAPHSON_HH__ */
diff --git a/src/model/solid_mechanics/material.cc b/src/model/solid_mechanics/material.cc
index d266c906c..638092d44 100644
--- a/src/model/solid_mechanics/material.cc
+++ b/src/model/solid_mechanics/material.cc
@@ -1,1377 +1,1377 @@
 /**
  * @file   material.cc
  *
+ * @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
  * @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
  * @author Daniel Pino Muñoz <daniel.pinomunoz@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  * @author Marco Vocialta <marco.vocialta@epfl.ch>
  *
  * @date creation: Tue Jul 27 2010
- * @date last modification: Tue Nov 24 2015
+ * @date last modification: Wed Feb 21 2018
  *
  * @brief  Implementation of the common part of the material class
  *
  * @section LICENSE
  *
- * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
- * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
- * Solides)
+ * 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
+ * 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
+ * A PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 #include "material.hh"
 #include "solid_mechanics_model.hh"
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 Material::Material(SolidMechanicsModel & model, const ID & id)
     : Memory(id, model.getMemoryID()), Parsable(ParserType::_material, id),
       is_init(false), fem(model.getFEEngine()), finite_deformation(false),
       name(""), model(model),
       spatial_dimension(this->model.getSpatialDimension()),
       element_filter("element_filter", id, this->memory_id),
       stress("stress", *this), eigengradu("eigen_grad_u", *this),
       gradu("grad_u", *this), green_strain("green_strain", *this),
       piola_kirchhoff_2("piola_kirchhoff_2", *this),
       potential_energy("potential_energy", *this), is_non_local(false),
       use_previous_stress(false), use_previous_gradu(false),
       interpolation_inverse_coordinates("interpolation inverse coordinates",
                                         *this),
       interpolation_points_matrices("interpolation points matrices", *this) {
   AKANTU_DEBUG_IN();
 
   /// for each connectivity types allocate the element filer array of the
   /// material
   element_filter.initialize(model.getMesh(),
                             _spatial_dimension = spatial_dimension);
   // model.getMesh().initElementTypeMapArray(element_filter, 1,
   // spatial_dimension,
   //                                         false, _ek_regular);
 
   this->initialize();
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 Material::Material(SolidMechanicsModel & model, UInt dim, const Mesh & mesh,
                    FEEngine & fe_engine, const ID & id)
     : Memory(id, model.getMemoryID()), Parsable(ParserType::_material, id),
       is_init(false), fem(fe_engine), finite_deformation(false), name(""),
       model(model), spatial_dimension(dim),
       element_filter("element_filter", id, this->memory_id),
       stress("stress", *this, dim, fe_engine, this->element_filter),
       eigengradu("eigen_grad_u", *this, dim, fe_engine, this->element_filter),
       gradu("gradu", *this, dim, fe_engine, this->element_filter),
       green_strain("green_strain", *this, dim, fe_engine, this->element_filter),
       piola_kirchhoff_2("piola_kirchhoff_2", *this, dim, fe_engine,
                         this->element_filter),
       potential_energy("potential_energy", *this, dim, fe_engine,
                        this->element_filter),
       is_non_local(false), use_previous_stress(false),
       use_previous_gradu(false),
       interpolation_inverse_coordinates("interpolation inverse_coordinates",
                                         *this, dim, fe_engine,
                                         this->element_filter),
       interpolation_points_matrices("interpolation points matrices", *this, dim,
                                     fe_engine, this->element_filter) {
 
   AKANTU_DEBUG_IN();
   element_filter.initialize(mesh, _spatial_dimension = spatial_dimension);
   // mesh.initElementTypeMapArray(element_filter, 1, spatial_dimension, false,
   //                              _ek_regular);
 
   this->initialize();
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 Material::~Material() = default;
 
 /* -------------------------------------------------------------------------- */
 void Material::initialize() {
   registerParam("rho", rho, Real(0.), _pat_parsable | _pat_modifiable,
                 "Density");
   registerParam("name", name, std::string(), _pat_parsable | _pat_readable);
   registerParam("finite_deformation", finite_deformation, false,
                 _pat_parsable | _pat_readable, "Is finite deformation");
   registerParam("inelastic_deformation", inelastic_deformation, false,
                 _pat_internal, "Is inelastic deformation");
 
   /// allocate gradu stress for local elements
   eigengradu.initialize(spatial_dimension * spatial_dimension);
   gradu.initialize(spatial_dimension * spatial_dimension);
   stress.initialize(spatial_dimension * spatial_dimension);
 
   potential_energy.initialize(1);
 
   this->model.registerEventHandler(*this);
 }
 
 /* -------------------------------------------------------------------------- */
 void Material::initMaterial() {
   AKANTU_DEBUG_IN();
 
   if (finite_deformation) {
     this->piola_kirchhoff_2.initialize(spatial_dimension * spatial_dimension);
     if (use_previous_stress)
       this->piola_kirchhoff_2.initializeHistory();
     this->green_strain.initialize(spatial_dimension * spatial_dimension);
   }
 
   if (use_previous_stress)
     this->stress.initializeHistory();
   if (use_previous_gradu)
     this->gradu.initializeHistory();
 
   for (auto it = internal_vectors_real.begin();
        it != internal_vectors_real.end(); ++it)
     it->second->resize();
 
   for (auto it = internal_vectors_uint.begin();
        it != internal_vectors_uint.end(); ++it)
     it->second->resize();
 
   for (auto it = internal_vectors_bool.begin();
        it != internal_vectors_bool.end(); ++it)
     it->second->resize();
 
   is_init = true;
 
   updateInternalParameters();
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void Material::savePreviousState() {
   AKANTU_DEBUG_IN();
 
   for (auto it = internal_vectors_real.begin();
        it != internal_vectors_real.end(); ++it) {
     if (it->second->hasHistory())
       it->second->saveCurrentValues();
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 /**
  * Compute  the  residual  by  assembling  @f$\int_{e}  \sigma_e  \frac{\partial
  * \varphi}{\partial X} dX @f$
  *
  * @param[in] displacements nodes displacements
  * @param[in] ghost_type compute the residual for _ghost or _not_ghost element
  */
 // void Material::updateResidual(GhostType ghost_type) {
 //   AKANTU_DEBUG_IN();
 
 //   computeAllStresses(ghost_type);
 //   assembleResidual(ghost_type);
 
 //   AKANTU_DEBUG_OUT();
 // }
 
 /* -------------------------------------------------------------------------- */
 void Material::assembleInternalForces(GhostType ghost_type) {
   AKANTU_DEBUG_IN();
 
   UInt spatial_dimension = model.getSpatialDimension();
 
   if (!finite_deformation) {
 
     auto & internal_force = const_cast<Array<Real> &>(model.getInternalForce());
 
     // Mesh & mesh = fem.getMesh();
     for (auto && type :
          element_filter.elementTypes(spatial_dimension, ghost_type)) {
       Array<UInt> & elem_filter = element_filter(type, ghost_type);
       UInt nb_element = elem_filter.size();
 
       if (nb_element == 0)
         continue;
 
       const Array<Real> & shapes_derivatives =
           fem.getShapesDerivatives(type, ghost_type);
 
       UInt size_of_shapes_derivatives = shapes_derivatives.getNbComponent();
       UInt nb_quadrature_points = fem.getNbIntegrationPoints(type, ghost_type);
       UInt nb_nodes_per_element = Mesh::getNbNodesPerElement(type);
 
       /// compute @f$\sigma \frac{\partial \varphi}{\partial X}@f$ by
       /// @f$\mathbf{B}^t \mathbf{\sigma}_q@f$
       Array<Real> * sigma_dphi_dx =
           new Array<Real>(nb_element * nb_quadrature_points,
                           size_of_shapes_derivatives, "sigma_x_dphi_/_dX");
 
       fem.computeBtD(stress(type, ghost_type), *sigma_dphi_dx, type, ghost_type,
                      elem_filter);
 
       /**
        * compute @f$\int \sigma  * \frac{\partial \varphi}{\partial X}dX@f$ by
        * @f$ \sum_q \mathbf{B}^t
        * \mathbf{\sigma}_q \overline w_q J_q@f$
        */
       Array<Real> * int_sigma_dphi_dx =
           new Array<Real>(nb_element, nb_nodes_per_element * spatial_dimension,
                           "int_sigma_x_dphi_/_dX");
 
       fem.integrate(*sigma_dphi_dx, *int_sigma_dphi_dx,
                     size_of_shapes_derivatives, type, ghost_type, elem_filter);
       delete sigma_dphi_dx;
 
       /// assemble
       model.getDOFManager().assembleElementalArrayLocalArray(
           *int_sigma_dphi_dx, internal_force, type, ghost_type, -1,
           elem_filter);
       delete int_sigma_dphi_dx;
     }
   } else {
     switch (spatial_dimension) {
     case 1:
       this->assembleInternalForces<1>(ghost_type);
       break;
     case 2:
       this->assembleInternalForces<2>(ghost_type);
       break;
     case 3:
       this->assembleInternalForces<3>(ghost_type);
       break;
     }
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 /**
  * Compute  the  stress from the gradu
  *
  * @param[in] current_position nodes postition + displacements
  * @param[in] ghost_type compute the residual for _ghost or _not_ghost element
  */
 void Material::computeAllStresses(GhostType ghost_type) {
   AKANTU_DEBUG_IN();
 
   UInt spatial_dimension = model.getSpatialDimension();
 
   for (const auto & type :
        element_filter.elementTypes(spatial_dimension, ghost_type)) {
     Array<UInt> & elem_filter = element_filter(type, ghost_type);
 
     if (elem_filter.size() == 0)
       continue;
     Array<Real> & gradu_vect = gradu(type, ghost_type);
 
     /// compute @f$\nabla u@f$
     fem.gradientOnIntegrationPoints(model.getDisplacement(), gradu_vect,
                                     spatial_dimension, type, ghost_type,
                                     elem_filter);
 
     gradu_vect -= eigengradu(type, ghost_type);
 
     /// compute @f$\mathbf{\sigma}_q@f$ from @f$\nabla u@f$
     computeStress(type, ghost_type);
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void Material::computeAllCauchyStresses(GhostType ghost_type) {
   AKANTU_DEBUG_IN();
 
   AKANTU_DEBUG_ASSERT(finite_deformation, "The Cauchy stress can only be "
                                           "computed if you are working in "
                                           "finite deformation.");
 
   for (auto type : element_filter.elementTypes(spatial_dimension, ghost_type)) {
     switch (spatial_dimension) {
     case 1:
       this->computeCauchyStress<1>(type, ghost_type);
       break;
     case 2:
       this->computeCauchyStress<2>(type, ghost_type);
       break;
     case 3:
       this->computeCauchyStress<3>(type, ghost_type);
       break;
     }
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <UInt dim>
 void Material::computeCauchyStress(ElementType el_type, GhostType ghost_type) {
   AKANTU_DEBUG_IN();
 
   Array<Real>::matrix_iterator gradu_it =
       this->gradu(el_type, ghost_type).begin(dim, dim);
 
   Array<Real>::matrix_iterator gradu_end =
       this->gradu(el_type, ghost_type).end(dim, dim);
 
   Array<Real>::matrix_iterator piola_it =
       this->piola_kirchhoff_2(el_type, ghost_type).begin(dim, dim);
 
   Array<Real>::matrix_iterator stress_it =
       this->stress(el_type, ghost_type).begin(dim, dim);
 
   Matrix<Real> F_tensor(dim, dim);
 
   for (; gradu_it != gradu_end; ++gradu_it, ++piola_it, ++stress_it) {
     Matrix<Real> & grad_u = *gradu_it;
     Matrix<Real> & piola = *piola_it;
     Matrix<Real> & sigma = *stress_it;
 
     gradUToF<dim>(grad_u, F_tensor);
     this->computeCauchyStressOnQuad<dim>(F_tensor, piola, sigma);
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void Material::setToSteadyState(GhostType ghost_type) {
   AKANTU_DEBUG_IN();
 
   const Array<Real> & displacement = model.getDisplacement();
 
   // resizeInternalArray(gradu);
 
   UInt spatial_dimension = model.getSpatialDimension();
 
   for (auto type : element_filter.elementTypes(spatial_dimension, ghost_type)) {
     Array<UInt> & elem_filter = element_filter(type, ghost_type);
     Array<Real> & gradu_vect = gradu(type, ghost_type);
 
     /// compute @f$\nabla u@f$
     fem.gradientOnIntegrationPoints(displacement, gradu_vect, spatial_dimension,
                                     type, ghost_type, elem_filter);
 
     setToSteadyState(type, ghost_type);
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 /**
  * Compute  the stiffness  matrix by  assembling @f$\int_{\omega}  B^t  \times D
  * \times B d\omega @f$
  *
  * @param[in] current_position nodes postition + displacements
  * @param[in] ghost_type compute the residual for _ghost or _not_ghost element
  */
 void Material::assembleStiffnessMatrix(GhostType ghost_type) {
   AKANTU_DEBUG_IN();
 
   UInt spatial_dimension = model.getSpatialDimension();
 
   for (auto type : element_filter.elementTypes(spatial_dimension, ghost_type)) {
     if (finite_deformation) {
       switch (spatial_dimension) {
       case 1: {
         assembleStiffnessMatrixNL<1>(type, ghost_type);
         assembleStiffnessMatrixL2<1>(type, ghost_type);
         break;
       }
       case 2: {
         assembleStiffnessMatrixNL<2>(type, ghost_type);
         assembleStiffnessMatrixL2<2>(type, ghost_type);
         break;
       }
       case 3: {
         assembleStiffnessMatrixNL<3>(type, ghost_type);
         assembleStiffnessMatrixL2<3>(type, ghost_type);
         break;
       }
       }
     } else {
       switch (spatial_dimension) {
       case 1: {
         assembleStiffnessMatrix<1>(type, ghost_type);
         break;
       }
       case 2: {
         assembleStiffnessMatrix<2>(type, ghost_type);
         break;
       }
       case 3: {
         assembleStiffnessMatrix<3>(type, ghost_type);
         break;
       }
       }
     }
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <UInt dim>
 void Material::assembleStiffnessMatrix(const ElementType & type,
                                        GhostType ghost_type) {
   AKANTU_DEBUG_IN();
 
   Array<UInt> & elem_filter = element_filter(type, ghost_type);
   if (elem_filter.size() == 0) {
     AKANTU_DEBUG_OUT();
     return;
   }
 
   // const Array<Real> & shapes_derivatives =
   //     fem.getShapesDerivatives(type, ghost_type);
 
   Array<Real> & gradu_vect = gradu(type, ghost_type);
 
   UInt nb_element = elem_filter.size();
   UInt nb_nodes_per_element = Mesh::getNbNodesPerElement(type);
   UInt nb_quadrature_points = fem.getNbIntegrationPoints(type, ghost_type);
 
   gradu_vect.resize(nb_quadrature_points * nb_element);
 
   fem.gradientOnIntegrationPoints(model.getDisplacement(), gradu_vect, dim,
                                   type, ghost_type, elem_filter);
 
   UInt tangent_size = getTangentStiffnessVoigtSize(dim);
 
   Array<Real> * tangent_stiffness_matrix =
       new Array<Real>(nb_element * nb_quadrature_points,
                       tangent_size * tangent_size, "tangent_stiffness_matrix");
 
   tangent_stiffness_matrix->clear();
 
   computeTangentModuli(type, *tangent_stiffness_matrix, ghost_type);
 
   /// compute @f$\mathbf{B}^t * \mathbf{D} * \mathbf{B}@f$
   UInt bt_d_b_size = dim * nb_nodes_per_element;
 
   Array<Real> * bt_d_b = new Array<Real>(nb_element * nb_quadrature_points,
                                          bt_d_b_size * bt_d_b_size, "B^t*D*B");
 
   fem.computeBtDB(*tangent_stiffness_matrix, *bt_d_b, 4, type, ghost_type,
                   elem_filter);
 
   delete tangent_stiffness_matrix;
 
   /// compute @f$ k_e = \int_e \mathbf{B}^t * \mathbf{D} * \mathbf{B}@f$
   Array<Real> * K_e =
       new Array<Real>(nb_element, bt_d_b_size * bt_d_b_size, "K_e");
 
   fem.integrate(*bt_d_b, *K_e, bt_d_b_size * bt_d_b_size, type, ghost_type,
                 elem_filter);
 
   delete bt_d_b;
 
   model.getDOFManager().assembleElementalMatricesToMatrix(
       "K", "displacement", *K_e, type, ghost_type, _symmetric, elem_filter);
   delete K_e;
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <UInt dim>
 void Material::assembleStiffnessMatrixNL(const ElementType & type,
                                          GhostType ghost_type) {
   AKANTU_DEBUG_IN();
 
   const Array<Real> & shapes_derivatives =
       fem.getShapesDerivatives(type, ghost_type);
 
   Array<UInt> & elem_filter = element_filter(type, ghost_type);
   // Array<Real> & gradu_vect = delta_gradu(type, ghost_type);
 
   UInt nb_element = elem_filter.size();
   UInt nb_nodes_per_element = Mesh::getNbNodesPerElement(type);
   UInt nb_quadrature_points = fem.getNbIntegrationPoints(type, ghost_type);
 
   Array<Real> * shapes_derivatives_filtered = new Array<Real>(
       nb_element * nb_quadrature_points, dim * nb_nodes_per_element,
       "shapes derivatives filtered");
 
   fem.filterElementalData(fem.getMesh(), shapes_derivatives,
                           *shapes_derivatives_filtered, type, ghost_type,
                           elem_filter);
 
   /// compute @f$\mathbf{B}^t * \mathbf{D} * \mathbf{B}@f$
   UInt bt_s_b_size = dim * nb_nodes_per_element;
 
   Array<Real> * bt_s_b = new Array<Real>(nb_element * nb_quadrature_points,
                                          bt_s_b_size * bt_s_b_size, "B^t*D*B");
 
   UInt piola_matrix_size = getCauchyStressMatrixSize(dim);
 
   Matrix<Real> B(piola_matrix_size, bt_s_b_size);
   Matrix<Real> Bt_S(bt_s_b_size, piola_matrix_size);
   Matrix<Real> S(piola_matrix_size, piola_matrix_size);
 
   auto shapes_derivatives_filtered_it = shapes_derivatives_filtered->begin(
       spatial_dimension, nb_nodes_per_element);
 
   auto Bt_S_B_it = bt_s_b->begin(bt_s_b_size, bt_s_b_size);
   auto Bt_S_B_end = bt_s_b->end(bt_s_b_size, bt_s_b_size);
   auto piola_it = piola_kirchhoff_2(type, ghost_type).begin(dim, dim);
 
   for (; Bt_S_B_it != Bt_S_B_end;
        ++Bt_S_B_it, ++shapes_derivatives_filtered_it, ++piola_it) {
     auto & Bt_S_B = *Bt_S_B_it;
     const auto & Piola_kirchhoff_matrix = *piola_it;
 
     setCauchyStressMatrix<dim>(Piola_kirchhoff_matrix, S);
     VoigtHelper<dim>::transferBMatrixToBNL(*shapes_derivatives_filtered_it, B,
                                            nb_nodes_per_element);
     Bt_S.template mul<true, false>(B, S);
     Bt_S_B.template mul<false, false>(Bt_S, B);
   }
 
   delete shapes_derivatives_filtered;
 
   /// compute @f$ k_e = \int_e \mathbf{B}^t * \mathbf{D} * \mathbf{B}@f$
   Array<Real> * K_e =
       new Array<Real>(nb_element, bt_s_b_size * bt_s_b_size, "K_e");
 
   fem.integrate(*bt_s_b, *K_e, bt_s_b_size * bt_s_b_size, type, ghost_type,
                 elem_filter);
 
   delete bt_s_b;
 
   model.getDOFManager().assembleElementalMatricesToMatrix(
       "K", "displacement", *K_e, type, ghost_type, _symmetric, elem_filter);
 
   delete K_e;
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <UInt dim>
 void Material::assembleStiffnessMatrixL2(const ElementType & type,
                                          GhostType ghost_type) {
   AKANTU_DEBUG_IN();
 
   const Array<Real> & shapes_derivatives =
       fem.getShapesDerivatives(type, ghost_type);
 
   Array<UInt> & elem_filter = element_filter(type, ghost_type);
   Array<Real> & gradu_vect = gradu(type, ghost_type);
 
   UInt nb_element = elem_filter.size();
   UInt nb_nodes_per_element = Mesh::getNbNodesPerElement(type);
   UInt nb_quadrature_points = fem.getNbIntegrationPoints(type, ghost_type);
 
   gradu_vect.resize(nb_quadrature_points * nb_element);
 
   fem.gradientOnIntegrationPoints(model.getDisplacement(), gradu_vect, dim,
                                   type, ghost_type, elem_filter);
 
   UInt tangent_size = getTangentStiffnessVoigtSize(dim);
 
   Array<Real> * tangent_stiffness_matrix =
       new Array<Real>(nb_element * nb_quadrature_points,
                       tangent_size * tangent_size, "tangent_stiffness_matrix");
 
   tangent_stiffness_matrix->clear();
 
   computeTangentModuli(type, *tangent_stiffness_matrix, ghost_type);
 
   Array<Real> * shapes_derivatives_filtered = new Array<Real>(
       nb_element * nb_quadrature_points, dim * nb_nodes_per_element,
       "shapes derivatives filtered");
   fem.filterElementalData(fem.getMesh(), shapes_derivatives,
                           *shapes_derivatives_filtered, type, ghost_type,
                           elem_filter);
 
   /// compute @f$\mathbf{B}^t * \mathbf{D} * \mathbf{B}@f$
   UInt bt_d_b_size = dim * nb_nodes_per_element;
 
   Array<Real> * bt_d_b = new Array<Real>(nb_element * nb_quadrature_points,
                                          bt_d_b_size * bt_d_b_size, "B^t*D*B");
 
   Matrix<Real> B(tangent_size, dim * nb_nodes_per_element);
   Matrix<Real> B2(tangent_size, dim * nb_nodes_per_element);
   Matrix<Real> Bt_D(dim * nb_nodes_per_element, tangent_size);
 
   auto shapes_derivatives_filtered_it = shapes_derivatives_filtered->begin(
       spatial_dimension, nb_nodes_per_element);
 
   auto Bt_D_B_it = bt_d_b->begin(bt_d_b_size, bt_d_b_size);
   auto grad_u_it = gradu_vect.begin(dim, dim);
   auto D_it = tangent_stiffness_matrix->begin(tangent_size, tangent_size);
   auto D_end = tangent_stiffness_matrix->end(tangent_size, tangent_size);
 
   for (; D_it != D_end;
        ++D_it, ++Bt_D_B_it, ++shapes_derivatives_filtered_it, ++grad_u_it) {
     const auto & grad_u = *grad_u_it;
     const auto & D = *D_it;
     auto & Bt_D_B = *Bt_D_B_it;
 
     // transferBMatrixToBL1<dim > (*shapes_derivatives_filtered_it, B,
     // nb_nodes_per_element);
     VoigtHelper<dim>::transferBMatrixToSymVoigtBMatrix(
         *shapes_derivatives_filtered_it, B, nb_nodes_per_element);
     VoigtHelper<dim>::transferBMatrixToBL2(*shapes_derivatives_filtered_it,
                                            grad_u, B2, nb_nodes_per_element);
     B += B2;
     Bt_D.template mul<true, false>(B, D);
     Bt_D_B.template mul<false, false>(Bt_D, B);
   }
 
   delete tangent_stiffness_matrix;
   delete shapes_derivatives_filtered;
 
   /// compute @f$ k_e = \int_e \mathbf{B}^t * \mathbf{D} * \mathbf{B}@f$
   Array<Real> * K_e =
       new Array<Real>(nb_element, bt_d_b_size * bt_d_b_size, "K_e");
 
   fem.integrate(*bt_d_b, *K_e, bt_d_b_size * bt_d_b_size, type, ghost_type,
                 elem_filter);
 
   delete bt_d_b;
 
   model.getDOFManager().assembleElementalMatricesToMatrix(
       "K", "displacement", *K_e, type, ghost_type, _symmetric, elem_filter);
   delete K_e;
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <UInt dim>
 void Material::assembleInternalForces(GhostType ghost_type) {
 
   AKANTU_DEBUG_IN();
 
   Array<Real> & internal_force = model.getInternalForce();
 
   Mesh & mesh = fem.getMesh();
   for (auto type : element_filter.elementTypes(spatial_dimension, ghost_type)) {
     const Array<Real> & shapes_derivatives =
         fem.getShapesDerivatives(type, ghost_type);
 
     Array<UInt> & elem_filter = element_filter(type, ghost_type);
     if (elem_filter.size() == 0)
       continue;
     UInt size_of_shapes_derivatives = shapes_derivatives.getNbComponent();
     UInt nb_element = elem_filter.size();
     UInt nb_nodes_per_element = Mesh::getNbNodesPerElement(type);
     UInt nb_quadrature_points = fem.getNbIntegrationPoints(type, ghost_type);
 
     Array<Real> * shapesd_filtered = new Array<Real>(
         nb_element, size_of_shapes_derivatives, "filtered shapesd");
 
     fem.filterElementalData(mesh, shapes_derivatives, *shapesd_filtered, type,
                             ghost_type, elem_filter);
 
     Array<Real>::matrix_iterator shapes_derivatives_filtered_it =
         shapesd_filtered->begin(dim, nb_nodes_per_element);
 
     // Set stress vectors
     UInt stress_size = getTangentStiffnessVoigtSize(dim);
 
     // Set matrices B and BNL*
     UInt bt_s_size = dim * nb_nodes_per_element;
 
     auto * bt_s =
         new Array<Real>(nb_element * nb_quadrature_points, bt_s_size, "B^t*S");
 
     auto grad_u_it = this->gradu(type, ghost_type).begin(dim, dim);
     auto grad_u_end = this->gradu(type, ghost_type).end(dim, dim);
     auto stress_it = this->piola_kirchhoff_2(type, ghost_type).begin(dim, dim);
     shapes_derivatives_filtered_it =
         shapesd_filtered->begin(dim, nb_nodes_per_element);
 
     Array<Real>::matrix_iterator bt_s_it = bt_s->begin(bt_s_size, 1);
 
     Matrix<Real> S_vect(stress_size, 1);
     Matrix<Real> B_tensor(stress_size, bt_s_size);
     Matrix<Real> B2_tensor(stress_size, bt_s_size);
 
     for (; grad_u_it != grad_u_end; ++grad_u_it, ++stress_it,
                                     ++shapes_derivatives_filtered_it,
                                     ++bt_s_it) {
       auto & grad_u = *grad_u_it;
       auto & r_it = *bt_s_it;
       auto & S_it = *stress_it;
 
       setCauchyStressArray<dim>(S_it, S_vect);
       VoigtHelper<dim>::transferBMatrixToSymVoigtBMatrix(
           *shapes_derivatives_filtered_it, B_tensor, nb_nodes_per_element);
       VoigtHelper<dim>::transferBMatrixToBL2(*shapes_derivatives_filtered_it,
                                              grad_u, B2_tensor,
                                              nb_nodes_per_element);
 
       B_tensor += B2_tensor;
 
       r_it.template mul<true, false>(B_tensor, S_vect);
     }
 
     delete shapesd_filtered;
 
     /// compute @f$ k_e = \int_e \mathbf{B}^t * \mathbf{D} * \mathbf{B}@f$
     Array<Real> * r_e = new Array<Real>(nb_element, bt_s_size, "r_e");
 
     fem.integrate(*bt_s, *r_e, bt_s_size, type, ghost_type, elem_filter);
 
     delete bt_s;
 
     model.getDOFManager().assembleElementalArrayLocalArray(
         *r_e, internal_force, type, ghost_type, -1., elem_filter);
     delete r_e;
   }
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void Material::computePotentialEnergyByElements() {
   AKANTU_DEBUG_IN();
 
   for (auto type : element_filter.elementTypes(spatial_dimension, _not_ghost)) {
     computePotentialEnergy(type);
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void Material::computePotentialEnergy(ElementType, GhostType) {
   AKANTU_DEBUG_IN();
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 Real Material::getPotentialEnergy() {
   AKANTU_DEBUG_IN();
   Real epot = 0.;
 
   computePotentialEnergyByElements();
 
   /// integrate the potential energy for each type of elements
   for (auto type : element_filter.elementTypes(spatial_dimension, _not_ghost)) {
     epot += fem.integrate(potential_energy(type, _not_ghost), type, _not_ghost,
                           element_filter(type, _not_ghost));
   }
 
   AKANTU_DEBUG_OUT();
   return epot;
 }
 
 /* -------------------------------------------------------------------------- */
 Real Material::getPotentialEnergy(ElementType & type, UInt index) {
   AKANTU_DEBUG_IN();
   Real epot = 0.;
 
   Vector<Real> epot_on_quad_points(fem.getNbIntegrationPoints(type));
 
   computePotentialEnergyByElement(type, index, epot_on_quad_points);
 
   epot = fem.integrate(epot_on_quad_points, type, element_filter(type)(index));
 
   AKANTU_DEBUG_OUT();
   return epot;
 }
 
 /* -------------------------------------------------------------------------- */
 Real Material::getEnergy(const std::string & type) {
   AKANTU_DEBUG_IN();
   if (type == "potential")
     return getPotentialEnergy();
   AKANTU_DEBUG_OUT();
   return 0.;
 }
 
 /* -------------------------------------------------------------------------- */
 Real Material::getEnergy(const std::string & energy_id, ElementType type,
                          UInt index) {
   AKANTU_DEBUG_IN();
   if (energy_id == "potential")
     return getPotentialEnergy(type, index);
   AKANTU_DEBUG_OUT();
   return 0.;
 }
 
 /* -------------------------------------------------------------------------- */
 void Material::initElementalFieldInterpolation(
     const ElementTypeMapArray<Real> & interpolation_points_coordinates) {
   AKANTU_DEBUG_IN();
 
   this->fem.initElementalFieldInterpolationFromIntegrationPoints(
       interpolation_points_coordinates, this->interpolation_points_matrices,
       this->interpolation_inverse_coordinates, &(this->element_filter));
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void Material::interpolateStress(ElementTypeMapArray<Real> & result,
                                  const GhostType ghost_type) {
 
   this->fem.interpolateElementalFieldFromIntegrationPoints(
       this->stress, this->interpolation_points_matrices,
       this->interpolation_inverse_coordinates, result, ghost_type,
       &(this->element_filter));
 }
 
 /* -------------------------------------------------------------------------- */
 void Material::interpolateStressOnFacets(
     ElementTypeMapArray<Real> & result,
     ElementTypeMapArray<Real> & by_elem_result, const GhostType ghost_type) {
 
   interpolateStress(by_elem_result, ghost_type);
 
   UInt stress_size = this->stress.getNbComponent();
 
   const Mesh & mesh = this->model.getMesh();
   const Mesh & mesh_facets = mesh.getMeshFacets();
 
   for (auto type : element_filter.elementTypes(spatial_dimension, ghost_type)) {
     Array<UInt> & elem_fil = element_filter(type, ghost_type);
     Array<Real> & by_elem_res = by_elem_result(type, ghost_type);
     UInt nb_element = elem_fil.size();
     UInt nb_element_full = this->model.getMesh().getNbElement(type, ghost_type);
     UInt nb_interpolation_points_per_elem =
         by_elem_res.size() / nb_element_full;
 
     const Array<Element> & facet_to_element =
         mesh_facets.getSubelementToElement(type, ghost_type);
     ElementType type_facet = Mesh::getFacetType(type);
     UInt nb_facet_per_elem = facet_to_element.getNbComponent();
     UInt nb_quad_per_facet =
         nb_interpolation_points_per_elem / nb_facet_per_elem;
     Element element_for_comparison{type, 0, ghost_type};
     const Array<std::vector<Element>> * element_to_facet = nullptr;
     GhostType current_ghost_type = _casper;
     Array<Real> * result_vec = nullptr;
 
     Array<Real>::const_matrix_iterator result_it =
         by_elem_res.begin_reinterpret(
             stress_size, nb_interpolation_points_per_elem, nb_element_full);
 
     for (UInt el = 0; el < nb_element; ++el) {
       UInt global_el = elem_fil(el);
       element_for_comparison.element = global_el;
       for (UInt f = 0; f < nb_facet_per_elem; ++f) {
 
         Element facet_elem = facet_to_element(global_el, f);
         UInt global_facet = facet_elem.element;
         if (facet_elem.ghost_type != current_ghost_type) {
           current_ghost_type = facet_elem.ghost_type;
           element_to_facet = &mesh_facets.getElementToSubelement(
               type_facet, current_ghost_type);
           result_vec = &result(type_facet, current_ghost_type);
         }
 
         bool is_second_element =
             (*element_to_facet)(global_facet)[0] != element_for_comparison;
 
         for (UInt q = 0; q < nb_quad_per_facet; ++q) {
           Vector<Real> result_local(result_vec->storage() +
                                         (global_facet * nb_quad_per_facet + q) *
                                             result_vec->getNbComponent() +
                                         is_second_element * stress_size,
                                     stress_size);
 
           const Matrix<Real> & result_tmp(result_it[global_el]);
           result_local = result_tmp(f * nb_quad_per_facet + q);
         }
       }
     }
   }
 }
 
 /* -------------------------------------------------------------------------- */
 template <typename T>
 const Array<T> & Material::getArray(const ID & /*vect_id*/,
                                     const ElementType & /*type*/,
                                     const GhostType & /*ghost_type*/) const {
   AKANTU_TO_IMPLEMENT();
   return NULL;
 }
 
 /* -------------------------------------------------------------------------- */
 template <typename T>
 Array<T> & Material::getArray(const ID & /*vect_id*/,
                               const ElementType & /*type*/,
                               const GhostType & /*ghost_type*/) {
   AKANTU_TO_IMPLEMENT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <>
 const Array<Real> & Material::getArray(const ID & vect_id,
                                        const ElementType & type,
                                        const GhostType & ghost_type) const {
   std::stringstream sstr;
   std::string ghost_id = "";
   if (ghost_type == _ghost)
     ghost_id = ":ghost";
   sstr << getID() << ":" << vect_id << ":" << type << ghost_id;
 
   ID fvect_id = sstr.str();
   try {
     return Memory::getArray<Real>(fvect_id);
   } catch (debug::Exception & e) {
     AKANTU_SILENT_EXCEPTION("The material " << name << "(" << getID()
                                             << ") does not contain a vector "
                                             << vect_id << " (" << fvect_id
                                             << ") [" << e << "]");
   }
 }
 
 /* -------------------------------------------------------------------------- */
 template <>
 Array<Real> & Material::getArray(const ID & vect_id, const ElementType & type,
                                  const GhostType & ghost_type) {
   std::stringstream sstr;
   std::string ghost_id = "";
   if (ghost_type == _ghost)
     ghost_id = ":ghost";
   sstr << getID() << ":" << vect_id << ":" << type << ghost_id;
 
   ID fvect_id = sstr.str();
   try {
     return Memory::getArray<Real>(fvect_id);
   } catch (debug::Exception & e) {
     AKANTU_SILENT_EXCEPTION("The material " << name << "(" << getID()
                                             << ") does not contain a vector "
                                             << vect_id << " (" << fvect_id
                                             << ") [" << e << "]");
   }
 }
 
 /* -------------------------------------------------------------------------- */
 template <>
 const Array<UInt> & Material::getArray(const ID & vect_id,
                                        const ElementType & type,
                                        const GhostType & ghost_type) const {
   std::stringstream sstr;
   std::string ghost_id = "";
   if (ghost_type == _ghost)
     ghost_id = ":ghost";
   sstr << getID() << ":" << vect_id << ":" << type << ghost_id;
 
   ID fvect_id = sstr.str();
   try {
     return Memory::getArray<UInt>(fvect_id);
   } catch (debug::Exception & e) {
     AKANTU_SILENT_EXCEPTION("The material " << name << "(" << getID()
                                             << ") does not contain a vector "
                                             << vect_id << " (" << fvect_id
                                             << ") [" << e << "]");
   }
 }
 
 /* -------------------------------------------------------------------------- */
 template <>
 Array<UInt> & Material::getArray(const ID & vect_id, const ElementType & type,
                                  const GhostType & ghost_type) {
   std::stringstream sstr;
   std::string ghost_id = "";
   if (ghost_type == _ghost)
     ghost_id = ":ghost";
   sstr << getID() << ":" << vect_id << ":" << type << ghost_id;
 
   ID fvect_id = sstr.str();
   try {
     return Memory::getArray<UInt>(fvect_id);
   } catch (debug::Exception & e) {
     AKANTU_SILENT_EXCEPTION("The material " << name << "(" << getID()
                                             << ") does not contain a vector "
                                             << vect_id << "(" << fvect_id
                                             << ") [" << e << "]");
   }
 }
 
 /* -------------------------------------------------------------------------- */
 template <typename T>
 const InternalField<T> & Material::getInternal(__attribute__((unused))
                                                const ID & int_id) const {
   AKANTU_TO_IMPLEMENT();
   return NULL;
 }
 
 /* -------------------------------------------------------------------------- */
 template <typename T>
 InternalField<T> & Material::getInternal(__attribute__((unused))
                                          const ID & int_id) {
   AKANTU_TO_IMPLEMENT();
   return NULL;
 }
 
 /* -------------------------------------------------------------------------- */
 template <>
 const InternalField<Real> & Material::getInternal(const ID & int_id) const {
   auto it = internal_vectors_real.find(getID() + ":" + int_id);
   if (it == internal_vectors_real.end()) {
     AKANTU_SILENT_EXCEPTION("The material " << name << "(" << getID()
                                             << ") does not contain an internal "
                                             << int_id << " ("
                                             << (getID() + ":" + int_id) << ")");
   }
   return *it->second;
 }
 
 /* -------------------------------------------------------------------------- */
 template <> InternalField<Real> & Material::getInternal(const ID & int_id) {
   auto it = internal_vectors_real.find(getID() + ":" + int_id);
   if (it == internal_vectors_real.end()) {
     AKANTU_SILENT_EXCEPTION("The material " << name << "(" << getID()
                                             << ") does not contain an internal "
                                             << int_id << " ("
                                             << (getID() + ":" + int_id) << ")");
   }
   return *it->second;
 }
 
 /* -------------------------------------------------------------------------- */
 template <>
 const InternalField<UInt> & Material::getInternal(const ID & int_id) const {
   auto it = internal_vectors_uint.find(getID() + ":" + int_id);
   if (it == internal_vectors_uint.end()) {
     AKANTU_SILENT_EXCEPTION("The material " << name << "(" << getID()
                                             << ") does not contain an internal "
                                             << int_id << " ("
                                             << (getID() + ":" + int_id) << ")");
   }
   return *it->second;
 }
 
 /* -------------------------------------------------------------------------- */
 template <> InternalField<UInt> & Material::getInternal(const ID & int_id) {
   auto it = internal_vectors_uint.find(getID() + ":" + int_id);
   if (it == internal_vectors_uint.end()) {
     AKANTU_SILENT_EXCEPTION("The material " << name << "(" << getID()
                                             << ") does not contain an internal "
                                             << int_id << " ("
                                             << (getID() + ":" + int_id) << ")");
   }
   return *it->second;
 }
 
 /* -------------------------------------------------------------------------- */
 void Material::addElements(const Array<Element> & elements_to_add) {
   AKANTU_DEBUG_IN();
   UInt mat_id = model.getInternalIndexFromID(getID());
   Array<Element>::const_iterator<Element> el_begin = elements_to_add.begin();
   Array<Element>::const_iterator<Element> el_end = elements_to_add.end();
   for (; el_begin != el_end; ++el_begin) {
     const Element & element = *el_begin;
     Array<UInt> & mat_indexes =
         model.getMaterialByElement(element.type, element.ghost_type);
     Array<UInt> & mat_loc_num =
         model.getMaterialLocalNumbering(element.type, element.ghost_type);
 
     UInt index =
         this->addElement(element.type, element.element, element.ghost_type);
     mat_indexes(element.element) = mat_id;
     mat_loc_num(element.element) = index;
   }
 
   this->resizeInternals();
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void Material::removeElements(const Array<Element> & elements_to_remove) {
   AKANTU_DEBUG_IN();
 
   Array<Element>::const_iterator<Element> el_begin = elements_to_remove.begin();
   Array<Element>::const_iterator<Element> el_end = elements_to_remove.end();
 
   if (el_begin == el_end)
     return;
 
   ElementTypeMapArray<UInt> material_local_new_numbering(
       "remove mat filter elem", getID(), getMemoryID());
 
   Element element;
   for (ghost_type_t::iterator gt = ghost_type_t::begin();
        gt != ghost_type_t::end(); ++gt) {
     GhostType ghost_type = *gt;
     element.ghost_type = ghost_type;
 
     ElementTypeMapArray<UInt>::type_iterator it =
         element_filter.firstType(_all_dimensions, ghost_type, _ek_not_defined);
     ElementTypeMapArray<UInt>::type_iterator end =
         element_filter.lastType(_all_dimensions, ghost_type, _ek_not_defined);
 
     for (; it != end; ++it) {
       ElementType type = *it;
       element.type = type;
 
       Array<UInt> & elem_filter = this->element_filter(type, ghost_type);
       Array<UInt> & mat_loc_num =
           this->model.getMaterialLocalNumbering(type, ghost_type);
 
       if (!material_local_new_numbering.exists(type, ghost_type))
         material_local_new_numbering.alloc(elem_filter.size(), 1, type,
                                            ghost_type);
       Array<UInt> & mat_renumbering =
           material_local_new_numbering(type, ghost_type);
 
       UInt nb_element = elem_filter.size();
       Array<UInt> elem_filter_tmp;
 
       UInt new_id = 0;
       for (UInt el = 0; el < nb_element; ++el) {
         element.element = elem_filter(el);
 
         if (std::find(el_begin, el_end, element) == el_end) {
           elem_filter_tmp.push_back(element.element);
 
           mat_renumbering(el) = new_id;
           mat_loc_num(element.element) = new_id;
           ++new_id;
         } else {
           mat_renumbering(el) = UInt(-1);
         }
       }
 
       elem_filter.resize(elem_filter_tmp.size());
       elem_filter.copy(elem_filter_tmp);
     }
   }
 
   for (auto it = internal_vectors_real.begin();
        it != internal_vectors_real.end(); ++it)
     it->second->removeIntegrationPoints(material_local_new_numbering);
 
   for (auto it = internal_vectors_uint.begin();
        it != internal_vectors_uint.end(); ++it)
     it->second->removeIntegrationPoints(material_local_new_numbering);
 
   for (auto it = internal_vectors_bool.begin();
        it != internal_vectors_bool.end(); ++it)
     it->second->removeIntegrationPoints(material_local_new_numbering);
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void Material::resizeInternals() {
   AKANTU_DEBUG_IN();
   for (auto it = internal_vectors_real.begin();
        it != internal_vectors_real.end(); ++it)
     it->second->resize();
 
   for (auto it = internal_vectors_uint.begin();
        it != internal_vectors_uint.end(); ++it)
     it->second->resize();
 
   for (auto it = internal_vectors_bool.begin();
        it != internal_vectors_bool.end(); ++it)
     it->second->resize();
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void Material::onElementsAdded(const Array<Element> &,
                                const NewElementsEvent &) {
   this->resizeInternals();
 }
 
 /* -------------------------------------------------------------------------- */
 void Material::onElementsRemoved(
     const Array<Element> & element_list,
     const ElementTypeMapArray<UInt> & new_numbering,
     __attribute__((unused)) const RemovedElementsEvent & event) {
   UInt my_num = model.getInternalIndexFromID(getID());
 
   ElementTypeMapArray<UInt> material_local_new_numbering(
       "remove mat filter elem", getID(), getMemoryID());
 
   auto el_begin = element_list.begin();
   auto el_end = element_list.end();
 
   for (auto && gt : ghost_types) {
     for (auto && type :
          new_numbering.elementTypes(_all_dimensions, gt, _ek_not_defined)) {
 
       if (not element_filter.exists(type, gt) ||
           element_filter(type, gt).size() == 0)
         continue;
 
       auto & elem_filter = element_filter(type, gt);
       auto & mat_indexes = this->model.getMaterialByElement(type, gt);
       auto & mat_loc_num = this->model.getMaterialLocalNumbering(type, gt);
       auto nb_element = this->model.getMesh().getNbElement(type, gt);
 
       // all materials will resize of the same size...
       mat_indexes.resize(nb_element);
       mat_loc_num.resize(nb_element);
 
       if (!material_local_new_numbering.exists(type, gt))
         material_local_new_numbering.alloc(elem_filter.size(), 1, type, gt);
 
       auto & mat_renumbering = material_local_new_numbering(type, gt);
       const auto & renumbering = new_numbering(type, gt);
       Array<UInt> elem_filter_tmp;
       UInt ni = 0;
       Element el{type, 0, gt};
 
       for (UInt i = 0; i < elem_filter.size(); ++i) {
         el.element = elem_filter(i);
         if (std::find(el_begin, el_end, el) == el_end) {
           UInt new_el = renumbering(el.element);
           AKANTU_DEBUG_ASSERT(new_el != UInt(-1),
                               "A not removed element as been badly renumbered");
           elem_filter_tmp.push_back(new_el);
           mat_renumbering(i) = ni;
 
           mat_indexes(new_el) = my_num;
           mat_loc_num(new_el) = ni;
           ++ni;
         } else {
           mat_renumbering(i) = UInt(-1);
         }
       }
 
       elem_filter.resize(elem_filter_tmp.size());
       elem_filter.copy(elem_filter_tmp);
     }
   }
 
   for (auto it = internal_vectors_real.begin();
        it != internal_vectors_real.end(); ++it)
     it->second->removeIntegrationPoints(material_local_new_numbering);
 
   for (auto it = internal_vectors_uint.begin();
        it != internal_vectors_uint.end(); ++it)
     it->second->removeIntegrationPoints(material_local_new_numbering);
 
   for (auto it = internal_vectors_bool.begin();
        it != internal_vectors_bool.end(); ++it)
     it->second->removeIntegrationPoints(material_local_new_numbering);
 }
 
 /* -------------------------------------------------------------------------- */
 void Material::beforeSolveStep() { this->savePreviousState(); }
 
 /* -------------------------------------------------------------------------- */
 void Material::afterSolveStep() {
   for (auto & type : element_filter.elementTypes(_all_dimensions, _not_ghost,
                                                  _ek_not_defined)) {
     this->updateEnergies(type, _not_ghost);
   }
 }
 /* -------------------------------------------------------------------------- */
 void Material::onDamageIteration() { this->savePreviousState(); }
 
 /* -------------------------------------------------------------------------- */
 void Material::onDamageUpdate() {
   ElementTypeMapArray<UInt>::type_iterator it = this->element_filter.firstType(
       _all_dimensions, _not_ghost, _ek_not_defined);
   ElementTypeMapArray<UInt>::type_iterator end =
       element_filter.lastType(_all_dimensions, _not_ghost, _ek_not_defined);
 
   for (; it != end; ++it) {
     this->updateEnergiesAfterDamage(*it, _not_ghost);
   }
 }
 
 /* -------------------------------------------------------------------------- */
 void Material::onDump() {
   if (this->isFiniteDeformation())
     this->computeAllCauchyStresses(_not_ghost);
 }
 
 /* -------------------------------------------------------------------------- */
 void Material::printself(std::ostream & stream, int indent) const {
   std::string space;
   for (Int i = 0; i < indent; i++, space += AKANTU_INDENT)
     ;
 
   std::string type = getID().substr(getID().find_last_of(':') + 1);
 
   stream << space << "Material " << type << " [" << std::endl;
   Parsable::printself(stream, indent);
   stream << space << "]" << std::endl;
 }
 
 /* -------------------------------------------------------------------------- */
 /// extrapolate internal values
 void Material::extrapolateInternal(const ID & id, const Element & element,
                                    __attribute__((unused))
                                    const Matrix<Real> & point,
                                    Matrix<Real> & extrapolated) {
   if (this->isInternal<Real>(id, element.kind())) {
     UInt nb_element =
         this->element_filter(element.type, element.ghost_type).size();
     const ID name = this->getID() + ":" + id;
     UInt nb_quads =
         this->internal_vectors_real[name]->getFEEngine().getNbIntegrationPoints(
             element.type, element.ghost_type);
     const Array<Real> & internal =
         this->getArray<Real>(id, element.type, element.ghost_type);
     UInt nb_component = internal.getNbComponent();
     Array<Real>::const_matrix_iterator internal_it =
         internal.begin_reinterpret(nb_component, nb_quads, nb_element);
     Element local_element = this->convertToLocalElement(element);
 
     /// instead of really extrapolating, here the value of the first GP
     /// is copied into the result vector. This works only for linear
     /// elements
     /// @todo extrapolate!!!!
     AKANTU_DEBUG_WARNING("This is a fix, values are not truly extrapolated");
 
     const Matrix<Real> & values = internal_it[local_element.element];
     UInt index = 0;
     Vector<Real> tmp(nb_component);
     for (UInt j = 0; j < values.cols(); ++j) {
       tmp = values(j);
       if (tmp.norm() > 0) {
         index = j;
         break;
       }
     }
 
     for (UInt i = 0; i < extrapolated.size(); ++i) {
       extrapolated(i) = values(index);
     }
   } else {
     Matrix<Real> default_values(extrapolated.rows(), extrapolated.cols(), 0.);
     extrapolated = default_values;
   }
 }
 
 /* -------------------------------------------------------------------------- */
 void Material::applyEigenGradU(const Matrix<Real> & prescribed_eigen_grad_u,
                                const GhostType ghost_type) {
 
   for (auto && type : element_filter.elementTypes(_all_dimensions, _not_ghost,
                                                   _ek_not_defined)) {
     if (!element_filter(type, ghost_type).size())
       continue;
     auto eigen_it = this->eigengradu(type, ghost_type)
                         .begin(spatial_dimension, spatial_dimension);
     auto eigen_end = this->eigengradu(type, ghost_type)
                          .end(spatial_dimension, spatial_dimension);
     for (; eigen_it != eigen_end; ++eigen_it) {
       auto & current_eigengradu = *eigen_it;
       current_eigengradu = prescribed_eigen_grad_u;
     }
   }
 }
 
 } // namespace akantu
diff --git a/src/model/solid_mechanics/material.hh b/src/model/solid_mechanics/material.hh
index d66f49984..fae76952a 100644
--- a/src/model/solid_mechanics/material.hh
+++ b/src/model/solid_mechanics/material.hh
@@ -1,680 +1,679 @@
 /**
  * @file   material.hh
  *
  * @author Daniel Pino Muñoz <daniel.pinomunoz@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  * @author Marco Vocialta <marco.vocialta@epfl.ch>
  *
  * @date creation: Fri Jun 18 2010
- * @date last modification: Wed Nov 25 2015
+ * @date last modification: Wed Feb 21 2018
  *
  * @brief  Mother class for all materials
  *
  * @section LICENSE
  *
- * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
- * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
- * Solides)
+ * 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
+ * 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
+ * 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_factory.hh"
 #include "aka_voigthelper.hh"
 #include "data_accessor.hh"
 #include "integration_point.hh"
 #include "parsable.hh"
 #include "parser.hh"
 /* -------------------------------------------------------------------------- */
 #include "internal_field.hh"
 #include "random_internal_field.hh"
 /* -------------------------------------------------------------------------- */
 #include "mesh_events.hh"
 #include "solid_mechanics_model_event_handler.hh"
 /* -------------------------------------------------------------------------- */
 
 #ifndef __AKANTU_MATERIAL_HH__
 #define __AKANTU_MATERIAL_HH__
 
 /* -------------------------------------------------------------------------- */
 namespace akantu {
 class Model;
 class SolidMechanicsModel;
 } // namespace akantu
 
 namespace akantu {
 
 /**
  * Interface of all materials
  * Prerequisites for a new material
  * - inherit from this class
  * - implement the following methods:
  * \code
  *  virtual Real getStableTimeStep(Real h, const Element & element =
  * ElementNull);
  *
  *  virtual void computeStress(ElementType el_type,
  *                             GhostType ghost_type = _not_ghost);
  *
  *  virtual void computeTangentStiffness(const ElementType & el_type,
  *                                       Array<Real> & tangent_matrix,
  *                                       GhostType ghost_type = _not_ghost);
  * \endcode
  *
  */
 class Material : public Memory,
                  public DataAccessor<Element>,
                  public Parsable,
                  public MeshEventHandler,
                  protected SolidMechanicsModelEventHandler {
   /* ------------------------------------------------------------------------ */
   /* Constructors/Destructors                                                 */
   /* ------------------------------------------------------------------------ */
 public:
 #if __cplusplus > 199711L
   Material(const Material & mat) = delete;
   Material & operator=(const Material & mat) = delete;
 #endif
 
   /// Initialize material with defaults
   Material(SolidMechanicsModel & model, const ID & id = "");
 
   /// Initialize material with custom mesh & fe_engine
   Material(SolidMechanicsModel & model, UInt dim, const Mesh & mesh,
            FEEngine & fe_engine, const ID & id = "");
 
   /// Destructor
   ~Material() override;
 
 protected:
   void initialize();
 
   /* ------------------------------------------------------------------------ */
   /* Function that materials can/should reimplement                           */
   /* ------------------------------------------------------------------------ */
 protected:
   /// constitutive law
   virtual void computeStress(__attribute__((unused)) ElementType el_type,
                              __attribute__((unused))
                              GhostType ghost_type = _not_ghost) {
     AKANTU_TO_IMPLEMENT();
   }
 
   /// compute the tangent stiffness matrix
   virtual void computeTangentModuli(__attribute__((unused))
                                     const ElementType & el_type,
                                     __attribute__((unused))
                                     Array<Real> & tangent_matrix,
                                     __attribute__((unused))
                                     GhostType ghost_type = _not_ghost) {
     AKANTU_TO_IMPLEMENT();
   }
 
   /// compute the potential energy
   virtual void computePotentialEnergy(ElementType el_type,
                                       GhostType ghost_type = _not_ghost);
 
   /// compute the potential energy for an element
   virtual void
   computePotentialEnergyByElement(__attribute__((unused)) ElementType type,
                                   __attribute__((unused)) UInt index,
                                   __attribute__((unused))
                                   Vector<Real> & epot_on_quad_points) {
     AKANTU_TO_IMPLEMENT();
   }
 
   virtual void updateEnergies(__attribute__((unused)) ElementType el_type,
                               __attribute__((unused))
                               GhostType ghost_type = _not_ghost) {}
 
   virtual void updateEnergiesAfterDamage(__attribute__((unused))
                                          ElementType el_type,
                                          __attribute__((unused))
                                          GhostType ghost_type = _not_ghost) {}
 
   /// set the material to steady state (to be implemented for materials that
   /// need it)
   virtual void setToSteadyState(__attribute__((unused)) ElementType el_type,
                                 __attribute__((unused))
                                 GhostType ghost_type = _not_ghost) {}
 
   /// function called to update the internal parameters when the modifiable
   /// parameters are modified
   virtual void updateInternalParameters() {}
 
 public:
   /// extrapolate internal values
   virtual void extrapolateInternal(const ID & id, const Element & element,
                                    const Matrix<Real> & points,
                                    Matrix<Real> & extrapolated);
 
   /// compute the p-wave speed in the material
   virtual Real getPushWaveSpeed(__attribute__((unused))
                                 const Element & element) const {
     AKANTU_TO_IMPLEMENT();
   }
 
   /// compute the s-wave speed in the material
   virtual Real getShearWaveSpeed(__attribute__((unused))
                                  const Element & element) const {
     AKANTU_TO_IMPLEMENT();
   }
 
   /// get a material celerity to compute the stable time step (default: is the
   /// push wave speed)
   virtual Real getCelerity(const Element & element) const {
     return getPushWaveSpeed(element);
   }
 
   /* ------------------------------------------------------------------------ */
   /* Methods                                                                  */
   /* ------------------------------------------------------------------------ */
 public:
   template <typename T>
   void registerInternal(__attribute__((unused)) InternalField<T> & vect) {
     AKANTU_TO_IMPLEMENT();
   }
 
   template <typename T>
   void unregisterInternal(__attribute__((unused)) InternalField<T> & vect) {
     AKANTU_TO_IMPLEMENT();
   }
 
   /// initialize the material computed parameter
   virtual void initMaterial();
 
   /// compute the residual for this material
   //  virtual void updateResidual(GhostType ghost_type = _not_ghost);
 
   /// assemble the residual for this material
   virtual void assembleInternalForces(GhostType ghost_type);
 
   /// save the stress in the previous_stress if needed
   virtual void savePreviousState();
 
   /// compute the stresses for this material
   virtual void computeAllStresses(GhostType ghost_type = _not_ghost);
   // virtual void
   // computeAllStressesFromTangentModuli(GhostType ghost_type = _not_ghost);
   virtual void computeAllCauchyStresses(GhostType ghost_type = _not_ghost);
 
   /// set material to steady state
   void setToSteadyState(GhostType ghost_type = _not_ghost);
 
   /// compute the stiffness matrix
   virtual void assembleStiffnessMatrix(GhostType ghost_type);
 
   /// add an element to the local mesh filter
   inline UInt addElement(const ElementType & type, UInt element,
                          const GhostType & ghost_type);
   inline UInt addElement(const Element & element);
 
   /// add many elements at once
   void addElements(const Array<Element> & elements_to_add);
 
   /// remove many element at once
   void removeElements(const Array<Element> & elements_to_remove);
 
   /// function to print the contain of the class
   void printself(std::ostream & stream, int indent = 0) const override;
 
   /**
    * interpolate stress on given positions for each element by means
    * of a geometrical interpolation on quadrature points
    */
   void interpolateStress(ElementTypeMapArray<Real> & result,
                          const GhostType ghost_type = _not_ghost);
 
   /**
    * interpolate stress on given positions for each element by means
    * of a geometrical interpolation on quadrature points and store the
    * results per facet
    */
   void interpolateStressOnFacets(ElementTypeMapArray<Real> & result,
                                  ElementTypeMapArray<Real> & by_elem_result,
                                  const GhostType ghost_type = _not_ghost);
 
   /**
    * function to initialize the elemental field interpolation
    * function by inverting the quadrature points' coordinates
    */
   void initElementalFieldInterpolation(
       const ElementTypeMapArray<Real> & interpolation_points_coordinates);
 
   /* ------------------------------------------------------------------------ */
   /* Common part                                                              */
   /* ------------------------------------------------------------------------ */
 protected:
   /* ------------------------------------------------------------------------ */
   inline UInt getTangentStiffnessVoigtSize(UInt spatial_dimension) const;
 
   /// compute the potential energy by element
   void computePotentialEnergyByElements();
 
   /// resize the intenals arrays
   virtual void resizeInternals();
 
   /* ------------------------------------------------------------------------ */
   /* Finite deformation functions                                             */
   /* This functions area implementing what is described in the paper of Bathe */
   /* et al, in IJNME, Finite Element Formulations For Large Deformation       */
   /* Dynamic Analysis, Vol 9, 353-386, 1975                                   */
   /* ------------------------------------------------------------------------ */
 protected:
   /// assemble the residual
   template <UInt dim> void assembleInternalForces(GhostType ghost_type);
 
   /// Computation of Cauchy stress tensor in the case of finite deformation from
   /// the 2nd Piola-Kirchhoff for a given element type
   template <UInt dim>
   void computeCauchyStress(ElementType el_type,
                            GhostType ghost_type = _not_ghost);
 
   /// Computation the Cauchy stress the 2nd Piola-Kirchhoff and the deformation
   /// gradient
   template <UInt dim>
   inline void computeCauchyStressOnQuad(const Matrix<Real> & F,
                                         const Matrix<Real> & S,
                                         Matrix<Real> & cauchy,
                                         const Real & C33 = 1.0) const;
 
   template <UInt dim>
   void computeAllStressesFromTangentModuli(const ElementType & type,
                                            GhostType ghost_type);
 
   template <UInt dim>
   void assembleStiffnessMatrix(const ElementType & type, GhostType ghost_type);
 
   /// assembling in finite deformation
   template <UInt dim>
   void assembleStiffnessMatrixNL(const ElementType & type,
                                  GhostType ghost_type);
 
   template <UInt dim>
   void assembleStiffnessMatrixL2(const ElementType & type,
                                  GhostType ghost_type);
 
   /// Size of the Stress matrix for the case of finite deformation see: Bathe et
   /// al, IJNME, Vol 9, 353-386, 1975
   inline UInt getCauchyStressMatrixSize(UInt spatial_dimension) const;
 
   /// Sets the stress matrix according to Bathe et al, IJNME, Vol 9, 353-386,
   /// 1975
   template <UInt dim>
   inline void setCauchyStressMatrix(const Matrix<Real> & S_t,
                                     Matrix<Real> & sigma);
 
   /// write the stress tensor in the Voigt notation.
   template <UInt dim>
   inline void setCauchyStressArray(const Matrix<Real> & S_t,
                                    Matrix<Real> & sigma_voight);
 
   /* ------------------------------------------------------------------------ */
   /* Conversion functions                                                     */
   /* ------------------------------------------------------------------------ */
 public:
   template <UInt dim>
   static inline void gradUToF(const Matrix<Real> & grad_u, Matrix<Real> & F);
   static inline void rightCauchy(const Matrix<Real> & F, Matrix<Real> & C);
   static inline void leftCauchy(const Matrix<Real> & F, Matrix<Real> & B);
 
   template <UInt dim>
   static inline void gradUToEpsilon(const Matrix<Real> & grad_u,
                                     Matrix<Real> & epsilon);
   template <UInt dim>
   static inline void gradUToGreenStrain(const Matrix<Real> & grad_u,
                                         Matrix<Real> & epsilon);
 
   static inline Real stressToVonMises(const Matrix<Real> & stress);
 
 protected:
   /// converts global element to local element
   inline Element convertToLocalElement(const Element & global_element) const;
   /// converts local element to global element
   inline Element convertToGlobalElement(const Element & local_element) const;
 
   /// converts global quadrature point to local quadrature point
   inline IntegrationPoint
   convertToLocalPoint(const IntegrationPoint & global_point) const;
   /// converts local quadrature point to global quadrature point
   inline IntegrationPoint
   convertToGlobalPoint(const IntegrationPoint & local_point) const;
 
   /* ------------------------------------------------------------------------ */
   /* DataAccessor inherited members                                           */
   /* ------------------------------------------------------------------------ */
 public:
   inline UInt getNbData(const Array<Element> & elements,
                         const SynchronizationTag & tag) const override;
 
   inline void packData(CommunicationBuffer & buffer,
                        const Array<Element> & elements,
                        const SynchronizationTag & tag) const override;
 
   inline void unpackData(CommunicationBuffer & buffer,
                          const Array<Element> & elements,
                          const SynchronizationTag & tag) override;
 
   template <typename T>
   inline void packElementDataHelper(const ElementTypeMapArray<T> & data_to_pack,
                                     CommunicationBuffer & buffer,
                                     const Array<Element> & elements,
                                     const ID & fem_id = ID()) const;
 
   template <typename T>
   inline void unpackElementDataHelper(ElementTypeMapArray<T> & data_to_unpack,
                                       CommunicationBuffer & buffer,
                                       const Array<Element> & elements,
                                       const ID & fem_id = ID());
 
   /* ------------------------------------------------------------------------ */
   /* MeshEventHandler inherited members                                       */
   /* ------------------------------------------------------------------------ */
 public:
   /* ------------------------------------------------------------------------ */
   void onNodesAdded(const Array<UInt> &, const NewNodesEvent &) override{};
   void onNodesRemoved(const Array<UInt> &, const Array<UInt> &,
                       const RemovedNodesEvent &) override{};
 
   void onElementsAdded(const Array<Element> & element_list,
                        const NewElementsEvent & event) override;
 
   void onElementsRemoved(const Array<Element> & element_list,
                          const ElementTypeMapArray<UInt> & new_numbering,
                          const RemovedElementsEvent & event) override;
 
   void onElementsChanged(const Array<Element> &, const Array<Element> &,
                          const ElementTypeMapArray<UInt> &,
                          const ChangedElementsEvent &) override{};
 
   /* ------------------------------------------------------------------------ */
   /* SolidMechanicsModelEventHandler inherited members                        */
   /* ------------------------------------------------------------------------ */
 public:
   virtual void beforeSolveStep();
   virtual void afterSolveStep();
 
   void onDamageIteration() override;
   void onDamageUpdate() override;
   void onDump() override;
 
   /* ------------------------------------------------------------------------ */
   /* Accessors                                                                */
   /* ------------------------------------------------------------------------ */
 public:
   AKANTU_GET_MACRO(Name, name, const std::string &);
 
   AKANTU_GET_MACRO(Model, model, const SolidMechanicsModel &)
 
   AKANTU_GET_MACRO(ID, Memory::getID(), const ID &);
   AKANTU_GET_MACRO(Rho, rho, Real);
   AKANTU_SET_MACRO(Rho, rho, Real);
 
   AKANTU_GET_MACRO(SpatialDimension, spatial_dimension, UInt);
 
   /// return the potential energy for the subset of elements contained by the
   /// material
   Real getPotentialEnergy();
   /// return the potential energy for the provided element
   Real getPotentialEnergy(ElementType & type, UInt index);
 
   /// return the energy (identified by id) for the subset of elements contained
   /// by the material
   virtual Real getEnergy(const std::string & energy_id);
   /// return the energy (identified by id) for the provided element
   virtual Real getEnergy(const std::string & energy_id, ElementType type,
                          UInt index);
 
   AKANTU_GET_MACRO_BY_ELEMENT_TYPE_CONST(ElementFilter, element_filter, UInt);
   AKANTU_GET_MACRO_BY_ELEMENT_TYPE_CONST(GradU, gradu, Real);
   AKANTU_GET_MACRO_BY_ELEMENT_TYPE_CONST(Stress, stress, Real);
   AKANTU_GET_MACRO_BY_ELEMENT_TYPE_CONST(PotentialEnergy, potential_energy,
                                          Real);
   AKANTU_GET_MACRO(GradU, gradu, const ElementTypeMapArray<Real> &);
   AKANTU_GET_MACRO(Stress, stress, const ElementTypeMapArray<Real> &);
   AKANTU_GET_MACRO(ElementFilter, element_filter,
                    const ElementTypeMapArray<UInt> &);
   AKANTU_GET_MACRO(FEEngine, fem, FEEngine &);
 
   bool isNonLocal() const { return is_non_local; }
 
   template <typename T>
   const Array<T> & getArray(const ID & id, const ElementType & type,
                             const GhostType & ghost_type = _not_ghost) const;
   template <typename T>
   Array<T> & getArray(const ID & id, const ElementType & type,
                       const GhostType & ghost_type = _not_ghost);
 
   template <typename T>
   const InternalField<T> & getInternal(const ID & id) const;
   template <typename T> InternalField<T> & getInternal(const ID & id);
 
   template <typename T>
   inline bool isInternal(const ID & id, const ElementKind & element_kind) const;
 
   template <typename T>
   ElementTypeMap<UInt>
   getInternalDataPerElem(const ID & id, const ElementKind & element_kind) const;
 
   bool isFiniteDeformation() const { return finite_deformation; }
   bool isInelasticDeformation() const { return inelastic_deformation; }
 
   template <typename T> inline void setParam(const ID & param, T value);
   inline const Parameter & getParam(const ID & param) const;
 
   template <typename T>
   void flattenInternal(const std::string & field_id,
                        ElementTypeMapArray<T> & internal_flat,
                        const GhostType ghost_type = _not_ghost,
                        ElementKind element_kind = _ek_not_defined) const;
 
   /// apply a constant eigengrad_u everywhere in the material
   virtual void applyEigenGradU(const Matrix<Real> & prescribed_eigen_grad_u,
                                const GhostType = _not_ghost);
 
   /// specify if the matrix need to be recomputed for this material
   virtual bool hasStiffnessMatrixChanged() { return true; }
 
 protected:
   bool isInit() const { return is_init; }
 
   /* ------------------------------------------------------------------------ */
   /* Class Members                                                            */
   /* ------------------------------------------------------------------------ */
 protected:
   /// boolean to know if the material has been initialized
   bool is_init;
 
   std::map<ID, InternalField<Real> *> internal_vectors_real;
   std::map<ID, InternalField<UInt> *> internal_vectors_uint;
   std::map<ID, InternalField<bool> *> internal_vectors_bool;
 
 protected:
   /// Link to the fem object in the model
   FEEngine & fem;
 
   /// Finite deformation
   bool finite_deformation;
 
   /// Finite deformation
   bool inelastic_deformation;
 
   /// material name
   std::string name;
 
   /// The model to witch the material belong
   SolidMechanicsModel & model;
 
   /// density : rho
   Real rho;
 
   /// spatial dimension
   UInt spatial_dimension;
 
   /// list of element handled by the material
   ElementTypeMapArray<UInt> element_filter;
 
   /// stresses arrays ordered by element types
   InternalField<Real> stress;
 
   /// eigengrad_u arrays ordered by element types
   InternalField<Real> eigengradu;
 
   /// grad_u arrays ordered by element types
   InternalField<Real> gradu;
 
   /// Green Lagrange strain (Finite deformation)
   InternalField<Real> green_strain;
 
   /// Second Piola-Kirchhoff stress tensor arrays ordered by element types
   /// (Finite deformation)
   InternalField<Real> piola_kirchhoff_2;
 
   /// potential energy by element
   InternalField<Real> potential_energy;
 
   /// tell if using in non local mode or not
   bool is_non_local;
 
   /// tell if the material need the previous stress state
   bool use_previous_stress;
 
   /// tell if the material need the previous strain state
   bool use_previous_gradu;
 
   /// elemental field interpolation coordinates
   InternalField<Real> interpolation_inverse_coordinates;
 
   /// elemental field interpolation points
   InternalField<Real> interpolation_points_matrices;
 
   /// vector that contains the names of all the internals that need to
   /// be transferred when material interfaces move
   std::vector<ID> internals_to_transfer;
 };
 
 /// standard output stream operator
 inline std::ostream & operator<<(std::ostream & stream,
                                  const Material & _this) {
   _this.printself(stream);
   return stream;
 }
 
 } // namespace akantu
 
 #include "material_inline_impl.cc"
 
 #include "internal_field_tmpl.hh"
 #include "random_internal_field_tmpl.hh"
 
 /* -------------------------------------------------------------------------- */
 /* Auto loop                                                                  */
 /* -------------------------------------------------------------------------- */
 /// This can be used to automatically write the loop on quadrature points in
 /// functions such as computeStress. This macro in addition to write the loop
 /// provides two tensors (matrices) sigma and grad_u
 #define MATERIAL_STRESS_QUADRATURE_POINT_LOOP_BEGIN(el_type, ghost_type)       \
   Array<Real>::matrix_iterator gradu_it =                                      \
       this->gradu(el_type, ghost_type)                                         \
           .begin(this->spatial_dimension, this->spatial_dimension);            \
   Array<Real>::matrix_iterator gradu_end =                                     \
       this->gradu(el_type, ghost_type)                                         \
           .end(this->spatial_dimension, this->spatial_dimension);              \
                                                                                \
   this->stress(el_type, ghost_type)                                            \
       .resize(this->gradu(el_type, ghost_type).size());                        \
                                                                                \
   Array<Real>::iterator<Matrix<Real>> stress_it =                              \
       this->stress(el_type, ghost_type)                                        \
           .begin(this->spatial_dimension, this->spatial_dimension);            \
                                                                                \
   if (this->isFiniteDeformation()) {                                           \
     this->piola_kirchhoff_2(el_type, ghost_type)                               \
         .resize(this->gradu(el_type, ghost_type).size());                      \
     stress_it = this->piola_kirchhoff_2(el_type, ghost_type)                   \
                     .begin(this->spatial_dimension, this->spatial_dimension);  \
   }                                                                            \
                                                                                \
   for (; gradu_it != gradu_end; ++gradu_it, ++stress_it) {                     \
     Matrix<Real> & __attribute__((unused)) grad_u = *gradu_it;                 \
     Matrix<Real> & __attribute__((unused)) sigma = *stress_it
 
 #define MATERIAL_STRESS_QUADRATURE_POINT_LOOP_END }
 
 /// This can be used to automatically write the loop on quadrature points in
 /// functions such as computeTangentModuli. This macro in addition to write the
 /// loop provides two tensors (matrices) sigma_tensor, grad_u, and a matrix
 /// where the elemental tangent moduli should be stored in Voigt Notation
 #define MATERIAL_TANGENT_QUADRATURE_POINT_LOOP_BEGIN(tangent_mat)              \
   Array<Real>::matrix_iterator gradu_it =                                      \
       this->gradu(el_type, ghost_type)                                         \
           .begin(this->spatial_dimension, this->spatial_dimension);            \
   Array<Real>::matrix_iterator gradu_end =                                     \
       this->gradu(el_type, ghost_type)                                         \
           .end(this->spatial_dimension, this->spatial_dimension);              \
   Array<Real>::matrix_iterator sigma_it =                                      \
       this->stress(el_type, ghost_type)                                        \
           .begin(this->spatial_dimension, this->spatial_dimension);            \
                                                                                \
   tangent_mat.resize(this->gradu(el_type, ghost_type).size());                 \
                                                                                \
   UInt tangent_size =                                                          \
       this->getTangentStiffnessVoigtSize(this->spatial_dimension);             \
   Array<Real>::matrix_iterator tangent_it =                                    \
       tangent_mat.begin(tangent_size, tangent_size);                           \
                                                                                \
   for (; gradu_it != gradu_end; ++gradu_it, ++sigma_it, ++tangent_it) {        \
     Matrix<Real> & __attribute__((unused)) grad_u = *gradu_it;                 \
     Matrix<Real> & __attribute__((unused)) sigma_tensor = *sigma_it;           \
     Matrix<Real> & tangent = *tangent_it
 
 #define MATERIAL_TANGENT_QUADRATURE_POINT_LOOP_END }
 
 /* -------------------------------------------------------------------------- */
 namespace akantu {
 using MaterialFactory =
     Factory<Material, ID, UInt, const ID &, SolidMechanicsModel &, const ID &>;
 } // namespace akantu
 
 #define INSTANTIATE_MATERIAL_ONLY(mat_name)                                    \
   template class mat_name<1>;                                                  \
   template class mat_name<2>;                                                  \
   template class mat_name<3>
 
 #define MATERIAL_DEFAULT_PER_DIM_ALLOCATOR(id, mat_name)                       \
   [](UInt dim, const ID &, SolidMechanicsModel & model,                        \
      const ID & id) -> std::unique_ptr<Material> {                             \
     switch (dim) {                                                             \
     case 1:                                                                    \
       return std::make_unique<mat_name<1>>(model, id);                         \
     case 2:                                                                    \
       return std::make_unique<mat_name<2>>(model, id);                         \
     case 3:                                                                    \
       return std::make_unique<mat_name<3>>(model, id);                         \
     default:                                                                   \
       AKANTU_EXCEPTION("The dimension "                                        \
                        << dim << "is not a valid dimension for the material "  \
                        << #id);                                                \
     }                                                                          \
   }
 
 #define INSTANTIATE_MATERIAL(id, mat_name)                                     \
   INSTANTIATE_MATERIAL_ONLY(mat_name);                                         \
   static bool material_is_alocated_##id[[gnu::unused]] =                       \
       MaterialFactory::getInstance().registerAllocator(                        \
           #id, MATERIAL_DEFAULT_PER_DIM_ALLOCATOR(id, mat_name))
 
 #endif /* __AKANTU_MATERIAL_HH__ */
diff --git a/src/model/solid_mechanics/material_inline_impl.cc b/src/model/solid_mechanics/material_inline_impl.cc
index 41f6de00b..19d753e5a 100644
--- a/src/model/solid_mechanics/material_inline_impl.cc
+++ b/src/model/solid_mechanics/material_inline_impl.cc
@@ -1,462 +1,461 @@
 /**
  * @file   material_inline_impl.cc
  *
  * @author Daniel Pino Muñoz <daniel.pinomunoz@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  * @author Marco Vocialta <marco.vocialta@epfl.ch>
  *
  * @date creation: Tue Jul 27 2010
- * @date last modification: Wed Nov 25 2015
+ * @date last modification: Tue Feb 20 2018
  *
  * @brief  Implementation of the inline functions of the class material
  *
  * @section LICENSE
  *
- * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
- * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
- * Solides)
+ * 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
+ * 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
+ * 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"
 /* -------------------------------------------------------------------------- */
 
 #ifndef __AKANTU_MATERIAL_INLINE_IMPL_CC__
 #define __AKANTU_MATERIAL_INLINE_IMPL_CC__
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 inline UInt Material::addElement(const ElementType & type, UInt element,
                                  const GhostType & ghost_type) {
   Array<UInt> & el_filter = this->element_filter(type, ghost_type);
   el_filter.push_back(element);
   return el_filter.size() - 1;
 }
 
 /* -------------------------------------------------------------------------- */
 inline UInt Material::addElement(const Element & element) {
   return this->addElement(element.type, element.element, element.ghost_type);
 }
 
 /* -------------------------------------------------------------------------- */
 inline UInt Material::getTangentStiffnessVoigtSize(UInt dim) const {
   return (dim * (dim - 1) / 2 + dim);
 }
 /* -------------------------------------------------------------------------- */
 inline UInt Material::getCauchyStressMatrixSize(UInt dim) const {
   return (dim * dim);
 }
 /* -------------------------------------------------------------------------- */
 template <UInt dim>
 inline void Material::gradUToF(const Matrix<Real> & grad_u, Matrix<Real> & F) {
   AKANTU_DEBUG_ASSERT(F.size() >= grad_u.size() && grad_u.size() == dim * dim,
                       "The dimension of the tensor F should be greater or "
                       "equal to the dimension of the tensor grad_u.");
 
   F.eye();
 
   for (UInt i = 0; i < dim; ++i)
     for (UInt j = 0; j < dim; ++j)
       F(i, j) += grad_u(i, j);
 }
 
 /* -------------------------------------------------------------------------- */
 template <UInt dim>
 inline void Material::computeCauchyStressOnQuad(const Matrix<Real> & F,
                                                 const Matrix<Real> & piola,
                                                 Matrix<Real> & sigma,
                                                 const Real & C33) const {
 
   Real J = F.det() * sqrt(C33);
 
   Matrix<Real> F_S(dim, dim);
   F_S.mul<false, false>(F, piola);
   Real constant = J ? 1. / J : 0;
   sigma.mul<false, true>(F_S, F, constant);
 }
 
 /* -------------------------------------------------------------------------- */
 inline void Material::rightCauchy(const Matrix<Real> & F, Matrix<Real> & C) {
   C.mul<true, false>(F, F);
 }
 
 /* -------------------------------------------------------------------------- */
 inline void Material::leftCauchy(const Matrix<Real> & F, Matrix<Real> & B) {
   B.mul<false, true>(F, F);
 }
 
 /* -------------------------------------------------------------------------- */
 template <UInt dim>
 inline void Material::gradUToEpsilon(const Matrix<Real> & grad_u,
                                      Matrix<Real> & epsilon) {
   for (UInt i = 0; i < dim; ++i)
     for (UInt j = 0; j < dim; ++j)
       epsilon(i, j) = 0.5 * (grad_u(i, j) + grad_u(j, i));
 }
 
 /* -------------------------------------------------------------------------- */
 template <UInt dim>
 inline void Material::gradUToGreenStrain(const Matrix<Real> & grad_u,
                                          Matrix<Real> & epsilon) {
   epsilon.mul<true, false>(grad_u, grad_u, .5);
 
   for (UInt i = 0; i < dim; ++i)
     for (UInt j = 0; j < dim; ++j)
       epsilon(i, j) += 0.5 * (grad_u(i, j) + grad_u(j, i));
 }
 
 /* -------------------------------------------------------------------------- */
 inline Real Material::stressToVonMises(const Matrix<Real> & stress) {
   // compute deviatoric stress
   UInt dim = stress.cols();
   Matrix<Real> deviatoric_stress =
       Matrix<Real>::eye(dim, -1. * stress.trace() / 3.);
 
   for (UInt i = 0; i < dim; ++i)
     for (UInt j = 0; j < dim; ++j)
       deviatoric_stress(i, j) += stress(i, j);
 
   // return Von Mises stress
   return std::sqrt(3. * deviatoric_stress.doubleDot(deviatoric_stress) / 2.);
 }
 
 /* ---------------------------------------------------------------------------*/
 template <UInt dim>
 inline void Material::setCauchyStressArray(const Matrix<Real> & S_t,
                                            Matrix<Real> & sigma_voight) {
   AKANTU_DEBUG_IN();
   sigma_voight.clear();
   // see Finite element formulations for large deformation dynamic analysis,
   // Bathe et al. IJNME vol 9, 1975, page 364 ^t\tau
 
   /*
    * 1d: [ s11 ]'
    * 2d: [ s11 s22 s12 ]'
    * 3d: [ s11 s22 s33 s23 s13 s12 ]
    */
   for (UInt i = 0; i < dim; ++i) // diagonal terms
     sigma_voight(i, 0) = S_t(i, i);
 
   for (UInt i = 1; i < dim; ++i) // term s12 in 2D and terms s23 s13 in 3D
     sigma_voight(dim + i - 1, 0) = S_t(dim - i - 1, dim - 1);
 
   for (UInt i = 2; i < dim; ++i) // term s13 in 3D
     sigma_voight(dim + i, 0) = S_t(0, 1);
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <UInt dim>
 inline void Material::setCauchyStressMatrix(const Matrix<Real> & S_t,
                                             Matrix<Real> & sigma) {
   AKANTU_DEBUG_IN();
 
   sigma.clear();
 
   /// see Finite ekement formulations for large deformation dynamic analysis,
   /// Bathe et al. IJNME vol 9, 1975, page 364 ^t\tau
   for (UInt i = 0; i < dim; ++i) {
     for (UInt m = 0; m < dim; ++m) {
       for (UInt n = 0; n < dim; ++n) {
         sigma(i * dim + m, i * dim + n) = S_t(m, n);
       }
     }
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 inline Element
 Material::convertToLocalElement(const Element & global_element) const {
   UInt ge = global_element.element;
 #ifndef AKANTU_NDEBUG
   UInt model_mat_index = this->model.getMaterialByElement(
       global_element.type, global_element.ghost_type)(ge);
 
   UInt mat_index = this->model.getMaterialIndex(this->name);
   AKANTU_DEBUG_ASSERT(model_mat_index == mat_index,
                       "Conversion of a global  element in a local element for "
                       "the wrong material "
                           << this->name << std::endl);
 #endif
   UInt le = this->model.getMaterialLocalNumbering(
       global_element.type, global_element.ghost_type)(ge);
 
   Element tmp_quad{global_element.type, le, global_element.ghost_type};
   return tmp_quad;
 }
 
 /* -------------------------------------------------------------------------- */
 inline Element
 Material::convertToGlobalElement(const Element & local_element) const {
   UInt le = local_element.element;
   UInt ge =
       this->element_filter(local_element.type, local_element.ghost_type)(le);
 
   Element tmp_quad{local_element.type, ge, local_element.ghost_type};
   return tmp_quad;
 }
 
 /* -------------------------------------------------------------------------- */
 inline IntegrationPoint
 Material::convertToLocalPoint(const IntegrationPoint & global_point) const {
   const FEEngine & fem = this->model.getFEEngine();
   UInt nb_quad = fem.getNbIntegrationPoints(global_point.type);
   Element el =
       this->convertToLocalElement(static_cast<const Element &>(global_point));
   IntegrationPoint tmp_quad(el, global_point.num_point, nb_quad);
   return tmp_quad;
 }
 
 /* -------------------------------------------------------------------------- */
 inline IntegrationPoint
 Material::convertToGlobalPoint(const IntegrationPoint & local_point) const {
   const FEEngine & fem = this->model.getFEEngine();
   UInt nb_quad = fem.getNbIntegrationPoints(local_point.type);
   Element el =
       this->convertToGlobalElement(static_cast<const Element &>(local_point));
   IntegrationPoint tmp_quad(el, local_point.num_point, nb_quad);
   return tmp_quad;
 }
 
 /* -------------------------------------------------------------------------- */
 inline UInt Material::getNbData(const Array<Element> & elements,
                                 const SynchronizationTag & tag) const {
   if (tag == _gst_smm_stress) {
     return (this->isFiniteDeformation() ? 3 : 1) * spatial_dimension *
            spatial_dimension * sizeof(Real) *
            this->getModel().getNbIntegrationPoints(elements);
   }
   return 0;
 }
 
 /* -------------------------------------------------------------------------- */
 inline void Material::packData(CommunicationBuffer & buffer,
                                const Array<Element> & elements,
                                const SynchronizationTag & tag) const {
   if (tag == _gst_smm_stress) {
     if (this->isFiniteDeformation()) {
       packElementDataHelper(piola_kirchhoff_2, buffer, elements);
       packElementDataHelper(gradu, buffer, elements);
     }
     packElementDataHelper(stress, buffer, elements);
   }
 }
 
 /* -------------------------------------------------------------------------- */
 inline void Material::unpackData(CommunicationBuffer & buffer,
                                  const Array<Element> & elements,
                                  const SynchronizationTag & tag) {
   if (tag == _gst_smm_stress) {
     if (this->isFiniteDeformation()) {
       unpackElementDataHelper(piola_kirchhoff_2, buffer, elements);
       unpackElementDataHelper(gradu, buffer, elements);
     }
     unpackElementDataHelper(stress, buffer, elements);
   }
 }
 
 /* -------------------------------------------------------------------------- */
 inline const Parameter & Material::getParam(const ID & param) const {
   try {
     return get(param);
   } catch (...) {
     AKANTU_EXCEPTION("No parameter " << param << " in the material "
                                      << getID());
   }
 }
 
 /* -------------------------------------------------------------------------- */
 template <typename T>
 inline void Material::setParam(const ID & param, T value) {
   try {
     set<T>(param, value);
   } catch (...) {
     AKANTU_EXCEPTION("No parameter " << param << " in the material "
                                      << getID());
   }
   updateInternalParameters();
 }
 
 /* -------------------------------------------------------------------------- */
 template <typename T>
 inline void Material::packElementDataHelper(
     const ElementTypeMapArray<T> & data_to_pack, CommunicationBuffer & buffer,
     const Array<Element> & elements, const ID & fem_id) const {
   DataAccessor::packElementalDataHelper<T>(data_to_pack, buffer, elements, true,
                                            model.getFEEngine(fem_id));
 }
 
 /* -------------------------------------------------------------------------- */
 template <typename T>
 inline void Material::unpackElementDataHelper(
     ElementTypeMapArray<T> & data_to_unpack, CommunicationBuffer & buffer,
     const Array<Element> & elements, const ID & fem_id) {
   DataAccessor::unpackElementalDataHelper<T>(data_to_unpack, buffer, elements,
                                              true, model.getFEEngine(fem_id));
 }
 
 /* -------------------------------------------------------------------------- */
 template <>
 inline void Material::registerInternal<Real>(InternalField<Real> & vect) {
   internal_vectors_real[vect.getID()] = &vect;
 }
 
 template <>
 inline void Material::registerInternal<UInt>(InternalField<UInt> & vect) {
   internal_vectors_uint[vect.getID()] = &vect;
 }
 
 template <>
 inline void Material::registerInternal<bool>(InternalField<bool> & vect) {
   internal_vectors_bool[vect.getID()] = &vect;
 }
 
 /* -------------------------------------------------------------------------- */
 template <>
 inline void Material::unregisterInternal<Real>(InternalField<Real> & vect) {
   internal_vectors_real.erase(vect.getID());
 }
 
 template <>
 inline void Material::unregisterInternal<UInt>(InternalField<UInt> & vect) {
   internal_vectors_uint.erase(vect.getID());
 }
 
 template <>
 inline void Material::unregisterInternal<bool>(InternalField<bool> & vect) {
   internal_vectors_bool.erase(vect.getID());
 }
 
 /* -------------------------------------------------------------------------- */
 template <typename T>
 inline bool Material::isInternal(__attribute__((unused)) const ID & id,
                                  __attribute__((unused))
                                  const ElementKind & element_kind) const {
   AKANTU_TO_IMPLEMENT();
 }
 
 template <>
 inline bool Material::isInternal<Real>(const ID & id,
                                        const ElementKind & element_kind) const {
   auto internal_array = internal_vectors_real.find(this->getID() + ":" + id);
 
   if (internal_array == internal_vectors_real.end() ||
       internal_array->second->getElementKind() != element_kind)
     return false;
   return true;
 }
 
 /* -------------------------------------------------------------------------- */
 template <typename T>
 inline ElementTypeMap<UInt>
 Material::getInternalDataPerElem(const ID & field_id,
                                  const ElementKind & element_kind) const {
 
   if (!this->template isInternal<T>(field_id, element_kind))
     AKANTU_EXCEPTION("Cannot find internal field " << id << " in material "
                                                    << this->name);
 
   const InternalField<T> & internal_field =
       this->template getInternal<T>(field_id);
   const FEEngine & fe_engine = internal_field.getFEEngine();
   UInt nb_data_per_quad = internal_field.getNbComponent();
 
   ElementTypeMap<UInt> res;
   for (ghost_type_t::iterator gt = ghost_type_t::begin();
        gt != ghost_type_t::end(); ++gt) {
 
     using type_iterator = typename InternalField<T>::type_iterator;
     type_iterator tit = internal_field.firstType(*gt);
     type_iterator tend = internal_field.lastType(*gt);
 
     for (; tit != tend; ++tit) {
       UInt nb_quadrature_points = fe_engine.getNbIntegrationPoints(*tit, *gt);
       res(*tit, *gt) = nb_data_per_quad * nb_quadrature_points;
     }
   }
   return res;
 }
 
 /* -------------------------------------------------------------------------- */
 template <typename T>
 void Material::flattenInternal(const std::string & field_id,
                                ElementTypeMapArray<T> & internal_flat,
                                const GhostType ghost_type,
                                ElementKind element_kind) const {
 
   if (!this->template isInternal<T>(field_id, element_kind))
     AKANTU_EXCEPTION("Cannot find internal field " << id << " in material "
                                                    << this->name);
 
   const InternalField<T> & internal_field =
       this->template getInternal<T>(field_id);
 
   const FEEngine & fe_engine = internal_field.getFEEngine();
   const Mesh & mesh = fe_engine.getMesh();
 
   using type_iterator = typename InternalField<T>::filter_type_iterator;
   type_iterator tit = internal_field.filterFirstType(ghost_type);
   type_iterator tend = internal_field.filterLastType(ghost_type);
 
   for (; tit != tend; ++tit) {
     ElementType type = *tit;
 
     const Array<Real> & src_vect = internal_field(type, ghost_type);
     const Array<UInt> & filter = internal_field.getFilter(type, ghost_type);
 
     // total number of elements in the corresponding mesh
     UInt nb_element_dst = mesh.getNbElement(type, ghost_type);
     // number of element in the internal field
     UInt nb_element_src = filter.size();
     // number of quadrature points per elem
     UInt nb_quad_per_elem = fe_engine.getNbIntegrationPoints(type);
     // number of data per quadrature point
     UInt nb_data_per_quad = internal_field.getNbComponent();
 
     if (!internal_flat.exists(type, ghost_type)) {
       internal_flat.alloc(nb_element_dst * nb_quad_per_elem, nb_data_per_quad,
                           type, ghost_type);
     }
 
     if (nb_element_src == 0)
       continue;
 
     // number of data per element
     UInt nb_data = nb_quad_per_elem * nb_data_per_quad;
 
     Array<Real> & dst_vect = internal_flat(type, ghost_type);
     dst_vect.resize(nb_element_dst * nb_quad_per_elem);
 
     Array<UInt>::const_scalar_iterator it = filter.begin();
     Array<UInt>::const_scalar_iterator end = filter.end();
 
     auto it_src = src_vect.begin_reinterpret(nb_data, nb_element_src);
     auto it_dst = dst_vect.begin_reinterpret(nb_data, nb_element_dst);
 
     for (; it != end; ++it, ++it_src) {
       it_dst[*it] = *it_src;
     }
   }
 }
 
 } // akantu
 
 #endif /* __AKANTU_MATERIAL_INLINE_IMPL_CC__ */
diff --git a/src/model/solid_mechanics/material_list.hh.in b/src/model/solid_mechanics/material_list.hh.in
index bd556cd36..cd6ca5b68 100644
--- a/src/model/solid_mechanics/material_list.hh.in
+++ b/src/model/solid_mechanics/material_list.hh.in
@@ -1,51 +1,43 @@
 /**
  * @file   material_list.hh.in
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
- * @date creation: Thu Feb 21 2013
- * @date last modification: Sat Jul 18 2015
+ * @date creation: Wed Sep 01 2010
+ * @date last modification: Wed Feb 03 2016
  *
  * @brief  List of materials and all includes
  *
  * @section LICENSE
  *
- * Copyright  (©)  2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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 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.
+ * 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/>.
+ * 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_MATERIAL_LIST_HH__
 #define __AKANTU_MATERIAL_LIST_HH__
 
 #include "aka_config.hh"
 
 /* -------------------------------------------------------------------------- */
 /* Material includes                                                          */
 /* -------------------------------------------------------------------------- */
 @AKANTU_MATERIAL_INCLUDES@
 
 /* -------------------------------------------------------------------------- */
 /* Material list                                                              */
 /* -------------------------------------------------------------------------- */
 #define AKANTU_MATERIAL_LIST			\
 @AKANTU_MATERIAL_LISTS@
 
 // leave an empty line after the list
 
 #endif /* __AKANTU_MATERIAL_LIST_HH__ */
diff --git a/src/model/solid_mechanics/material_selector.hh b/src/model/solid_mechanics/material_selector.hh
index eb9d161b8..552274dc9 100644
--- a/src/model/solid_mechanics/material_selector.hh
+++ b/src/model/solid_mechanics/material_selector.hh
@@ -1,160 +1,161 @@
 /**
  * @file   material_selector.hh
  *
  * @author Lucas Frerot <lucas.frerot@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Wed Nov 13 2013
- * @date last modification: Thu Dec 17 2015
+ * @date last modification: Mon Dec 18 2017
  *
  * @brief  class describing how to choose a material for a given element
  *
  * @section LICENSE
  *
- * Copyright  (©)  2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de Lausanne)
+ * 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
+ * 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
+ * A PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
+
 /* -------------------------------------------------------------------------- */
 #include "element.hh"
 #include "mesh.hh"
 /* -------------------------------------------------------------------------- */
 #include <memory>
 /* -------------------------------------------------------------------------- */
 
 #ifndef __AKANTU_MATERIAL_SELECTOR_HH__
 #define __AKANTU_MATERIAL_SELECTOR_HH__
 
 /* -------------------------------------------------------------------------- */
 namespace akantu {
 
 class SolidMechanicsModel;
 
 /**
  * main class to assign same or different materials for different
  * elements
  */
 class MaterialSelector : public std::enable_shared_from_this<MaterialSelector> {
 public:
   MaterialSelector() = default;
   virtual ~MaterialSelector() = default;
   virtual inline UInt operator()(const Element & element) {
     if (fallback_selector)
       return (*fallback_selector)(element);
 
     return fallback_value;
   }
 
   inline void setFallback(UInt f) { fallback_value = f; }
   inline void
   setFallback(const std::shared_ptr<MaterialSelector> & fallback_selector) {
     this->fallback_selector = fallback_selector;
   }
 
   inline void setFallback(MaterialSelector & fallback_selector) {
     this->fallback_selector = fallback_selector.shared_from_this();
   }
 
   inline std::shared_ptr<MaterialSelector> & getFallbackSelector() {
     return this->fallback_selector;
   }
 
   inline UInt getFallbackValue() { return this->fallback_value; }
 
 protected:
   UInt fallback_value{0};
   std::shared_ptr<MaterialSelector> fallback_selector;
 };
 
 /* -------------------------------------------------------------------------- */
 /**
  * class that assigns the first material to regular elements by default
  */
 class DefaultMaterialSelector : public MaterialSelector {
 public:
   explicit DefaultMaterialSelector(
       const ElementTypeMapArray<UInt> & material_index)
       : material_index(material_index) {}
 
   UInt operator()(const Element & element) override {
     if (not material_index.exists(element.type, element.ghost_type))
       return MaterialSelector::operator()(element);
 
     const auto & mat_indexes = material_index(element.type, element.ghost_type);
     if (element.element < mat_indexes.size()) {
       auto && tmp_mat = mat_indexes(element.element);
       if (tmp_mat != UInt(-1))
         return tmp_mat;
     }
 
     return MaterialSelector::operator()(element);
   }
 
 private:
   const ElementTypeMapArray<UInt> & material_index;
 };
 
 /* -------------------------------------------------------------------------- */
 /**
  * Use elemental data to assign materials
  */
 template <typename T>
 class ElementDataMaterialSelector : public MaterialSelector {
 public:
   ElementDataMaterialSelector(const ElementTypeMapArray<T> & element_data,
                               const SolidMechanicsModel & model,
                               UInt first_index = 1)
       : element_data(element_data), model(model), first_index(first_index) {}
 
   inline T elementData(const Element & element) {
     DebugLevel dbl = debug::getDebugLevel();
     debug::setDebugLevel(dblError);
     T data = element_data(element.type, element.ghost_type)(element.element);
     debug::setDebugLevel(dbl);
     return data;
   }
 
   inline UInt operator()(const Element & element) override {
     return MaterialSelector::operator()(element);
   }
 
 protected:
   /// list of element with the specified data (i.e. tag value)
   const ElementTypeMapArray<T> & element_data;
 
   /// the model that the materials belong
   const SolidMechanicsModel & model;
 
   /// first material index: equal to 1 if none specified
   UInt first_index;
 };
 
 /* -------------------------------------------------------------------------- */
 /**
  * class to use mesh data information to assign different materials
  * where name is the tag value: tag_0, tag_1
  */
 template <typename T>
 class MeshDataMaterialSelector : public ElementDataMaterialSelector<T> {
 public:
   MeshDataMaterialSelector(const std::string & name,
                            const SolidMechanicsModel & model,
                            UInt first_index = 1);
 };
 
 } // namespace akantu
 
 #endif /* __AKANTU_MATERIAL_SELECTOR_HH__ */
diff --git a/src/model/solid_mechanics/material_selector_tmpl.hh b/src/model/solid_mechanics/material_selector_tmpl.hh
index 93fda1636..5c0a9b94b 100644
--- a/src/model/solid_mechanics/material_selector_tmpl.hh
+++ b/src/model/solid_mechanics/material_selector_tmpl.hh
@@ -1,73 +1,74 @@
 /**
  * @file   material_selector_tmpl.hh
  *
  * @author Lucas Frerot <lucas.frerot@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Wed Nov 13 2013
- * @date last modification: Fri May 01 2015
+ * @date last modification: Tue Nov 07 2017
  *
  * @brief  Implementation of the template MaterialSelector
  *
  * @section LICENSE
  *
- * Copyright  (©)  2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de Lausanne)
+ * 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
+ * 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
+ * A PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
+
 /* -------------------------------------------------------------------------- */
 #include "material_selector.hh"
 /* -------------------------------------------------------------------------- */
 
 #ifndef __AKANTU_MATERIAL_SELECTOR_TMPL_HH__
 #define __AKANTU_MATERIAL_SELECTOR_TMPL_HH__
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 template <>
 inline UInt ElementDataMaterialSelector<std::string>::
 operator()(const Element & element) {
   try {
     std::string material_name = this->elementData(element);
     return model.getMaterialIndex(material_name);
   } catch (...) {
     return MaterialSelector::operator()(element);
   }
 }
 
 /* -------------------------------------------------------------------------- */
 template <>
 inline UInt ElementDataMaterialSelector<UInt>::
 operator()(const Element & element) {
   try {
     return this->elementData(element) - first_index;
   } catch (...) {
     return MaterialSelector::operator()(element);
   }
 }
 
 /* -------------------------------------------------------------------------- */
 template <typename T>
 MeshDataMaterialSelector<T>::MeshDataMaterialSelector(
     const std::string & name, const SolidMechanicsModel & model,
     UInt first_index)
     : ElementDataMaterialSelector<T>(model.getMesh().getData<T>(name), model,
                                      first_index) {}
 
 } // namespace akantu
 
 #endif /* __AKANTU_MATERIAL_SELECTOR_TMPL_HH__ */
diff --git a/src/model/solid_mechanics/materials/internal_field.hh b/src/model/solid_mechanics/materials/internal_field.hh
index af8ae8eaa..54312dbeb 100644
--- a/src/model/solid_mechanics/materials/internal_field.hh
+++ b/src/model/solid_mechanics/materials/internal_field.hh
@@ -1,260 +1,259 @@
 /**
  * @file   internal_field.hh
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Fri Jun 18 2010
- * @date last modification: Tue Dec 08 2015
+ * @date last modification: Thu Feb 08 2018
  *
  * @brief  Material internal properties
  *
  * @section LICENSE
  *
- * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
- * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
- * Solides)
+ * 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
+ * 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
+ * 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 "element_type_map.hh"
 /* -------------------------------------------------------------------------- */
 
 #ifndef __AKANTU_INTERNAL_FIELD_HH__
 #define __AKANTU_INTERNAL_FIELD_HH__
 
 namespace akantu {
 
 class Material;
 class FEEngine;
 
 /**
  * class for the internal fields of materials
  * to store values for each quadrature
  */
 template <typename T> class InternalField : public ElementTypeMapArray<T> {
   /* ------------------------------------------------------------------------ */
   /* Constructors/Destructors                                                 */
   /* ------------------------------------------------------------------------ */
 public:
   InternalField(const ID & id, Material & material);
   ~InternalField() override;
 
   /// This constructor is only here to let cohesive elements compile
   InternalField(const ID & id, Material & material, FEEngine & fem,
                 const ElementTypeMapArray<UInt> & element_filter);
 
   /// More general constructor
   InternalField(const ID & id, Material & material, UInt dim, FEEngine & fem,
                 const ElementTypeMapArray<UInt> & element_filter);
 
   InternalField(const ID & id, const InternalField<T> & other);
 
 private:
   InternalField operator=(__attribute__((unused))
                           const InternalField & other){};
 
   /* ------------------------------------------------------------------------ */
   /* Methods                                                                  */
   /* ------------------------------------------------------------------------ */
 public:
   /// function to reset the FEEngine for the internal field
   virtual void setFEEngine(FEEngine & fe_engine);
 
   /// function to reset the element kind for the internal
   virtual void setElementKind(ElementKind element_kind);
 
   /// initialize the field to a given number of component
   virtual void initialize(UInt nb_component);
 
   /// activate the history of this field
   virtual void initializeHistory();
 
   /// resize the arrays and set the new element to 0
   virtual void resize();
 
   /// set the field to a given value v
   virtual void setDefaultValue(const T & v);
 
   /// reset all the fields to the default value
   virtual void reset();
 
   /// save the current values in the history
   virtual void saveCurrentValues();
 
   /// remove the quadrature points corresponding to suppressed elements
   virtual void
   removeIntegrationPoints(const ElementTypeMapArray<UInt> & new_numbering);
 
   /// print the content
   void printself(std::ostream & stream, int /*indent*/ = 0) const override;
 
   /// get the default value
   inline operator T() const;
 
   virtual FEEngine & getFEEngine() { return *fem; }
 
   virtual const FEEngine & getFEEngine() const { return *fem; }
 
   /// AKANTU_GET_MACRO(FEEngine, *fem, FEEngine &);
 
 protected:
   /// initialize the arrays in the ElementTypeMapArray<T>
   void internalInitialize(UInt nb_component);
 
   /// set the values for new internals
   virtual void setArrayValues(T * begin, T * end);
 
   /* ------------------------------------------------------------------------ */
   /* Accessors                                                                */
   /* ------------------------------------------------------------------------ */
 public:
   using type_iterator = typename ElementTypeMapArray<T>::type_iterator;
   using filter_type_iterator =
       typename ElementTypeMapArray<UInt>::type_iterator;
 
   /// get the type iterator on all types contained in the internal field
   type_iterator firstType(const GhostType & ghost_type = _not_ghost) const {
     return ElementTypeMapArray<T>::firstType(this->spatial_dimension,
                                              ghost_type, this->element_kind);
   }
 
   /// get the type iterator on the last type contained in the internal field
   type_iterator lastType(const GhostType & ghost_type = _not_ghost) const {
     return ElementTypeMapArray<T>::lastType(this->spatial_dimension, ghost_type,
                                             this->element_kind);
   }
 
   /// get the type iterator on all types contained in the internal field
   filter_type_iterator
   filterFirstType(const GhostType & ghost_type = _not_ghost) const {
     return this->element_filter.firstType(this->spatial_dimension, ghost_type,
                                           this->element_kind);
   }
 
   /// get the type iterator on the last type contained in the internal field
   filter_type_iterator
   filterLastType(const GhostType & ghost_type = _not_ghost) const {
     return this->element_filter.lastType(this->spatial_dimension, ghost_type,
                                          this->element_kind);
   }
 
   /// get the array for a given type of the element_filter
   const Array<UInt> getFilter(const ElementType & type,
                               const GhostType & ghost_type = _not_ghost) const {
     return this->element_filter(type, ghost_type);
   }
 
   /// get the Array corresponding to the type en ghost_type specified
   virtual Array<T> & operator()(const ElementType & type,
                                 const GhostType & ghost_type = _not_ghost) {
     return ElementTypeMapArray<T>::operator()(type, ghost_type);
   }
 
   virtual const Array<T> &
   operator()(const ElementType & type,
              const GhostType & ghost_type = _not_ghost) const {
     return ElementTypeMapArray<T>::operator()(type, ghost_type);
   }
 
   virtual Array<T> & previous(const ElementType & type,
                               const GhostType & ghost_type = _not_ghost) {
     AKANTU_DEBUG_ASSERT(previous_values != nullptr,
                         "The history of the internal "
                             << this->getID() << " has not been activated");
     return this->previous_values->operator()(type, ghost_type);
   }
 
   virtual const Array<T> &
   previous(const ElementType & type,
            const GhostType & ghost_type = _not_ghost) const {
     AKANTU_DEBUG_ASSERT(previous_values != nullptr,
                         "The history of the internal "
                             << this->getID() << " has not been activated");
     return this->previous_values->operator()(type, ghost_type);
   }
 
   virtual InternalField<T> & previous() {
     AKANTU_DEBUG_ASSERT(previous_values != nullptr,
                         "The history of the internal "
                             << this->getID() << " has not been activated");
     return *(this->previous_values);
   }
 
   virtual const InternalField<T> & previous() const {
     AKANTU_DEBUG_ASSERT(previous_values != nullptr,
                         "The history of the internal "
                             << this->getID() << " has not been activated");
     return *(this->previous_values);
   }
 
   /// check if the history is used or not
   bool hasHistory() const { return (previous_values != nullptr); }
 
   /// get the kind treated by the internal
   const ElementKind & getElementKind() const { return element_kind; }
 
   /// return the number of components
   UInt getNbComponent() const { return nb_component; }
 
   /// return the spatial dimension corresponding to the internal element type
   /// loop filter
   UInt getSpatialDimension() const { return this->spatial_dimension; }
 
   /* ------------------------------------------------------------------------ */
   /* Class Members                                                            */
   /* ------------------------------------------------------------------------ */
 protected:
   /// the material for which this is an internal parameter
   Material & material;
 
   /// the fem containing the mesh and the element informations
   FEEngine * fem;
 
   /// Element filter if needed
   const ElementTypeMapArray<UInt> & element_filter;
 
   /// default value
   T default_value;
 
   /// spatial dimension of the element to consider
   UInt spatial_dimension;
 
   /// ElementKind of the element to consider
   ElementKind element_kind;
 
   /// Number of component of the internal field
   UInt nb_component;
 
   /// Is the field initialized
   bool is_init;
 
   /// previous values
   InternalField<T> * previous_values;
 };
 
 /// standard output stream operator
 template <typename T>
 inline std::ostream & operator<<(std::ostream & stream,
                                  const InternalField<T> & _this) {
   _this.printself(stream);
   return stream;
 }
 
 } // akantu
 
 #endif /* __AKANTU_INTERNAL_FIELD_HH__ */
diff --git a/src/model/solid_mechanics/materials/internal_field_tmpl.hh b/src/model/solid_mechanics/materials/internal_field_tmpl.hh
index 9f694541b..c6476bcb9 100644
--- a/src/model/solid_mechanics/materials/internal_field_tmpl.hh
+++ b/src/model/solid_mechanics/materials/internal_field_tmpl.hh
@@ -1,317 +1,317 @@
 /**
  * @file   internal_field_tmpl.hh
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Wed Nov 13 2013
- * @date last modification: Tue Dec 08 2015
+ * @date last modification: Wed Feb 21 2018
  *
  * @brief  Material internal properties
  *
  * @section LICENSE
  *
- * Copyright  (©)  2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de Lausanne)
+ * 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
+ * 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
+ * A PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 #include "material.hh"
 /* -------------------------------------------------------------------------- */
 
 #ifndef __AKANTU_INTERNAL_FIELD_TMPL_HH__
 #define __AKANTU_INTERNAL_FIELD_TMPL_HH__
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 template <typename T>
 InternalField<T>::InternalField(const ID & id, Material & material)
     : ElementTypeMapArray<T>(id, material.getID(), material.getMemoryID()),
       material(material), fem(&(material.getModel().getFEEngine())),
       element_filter(material.getElementFilter()), default_value(T()),
       spatial_dimension(material.getModel().getSpatialDimension()),
       element_kind(_ek_regular), nb_component(0), is_init(false),
       previous_values(nullptr) {}
 
 /* -------------------------------------------------------------------------- */
 template <typename T>
 InternalField<T>::InternalField(
     const ID & id, Material & material, FEEngine & fem,
     const ElementTypeMapArray<UInt> & element_filter)
     : ElementTypeMapArray<T>(id, material.getID(), material.getMemoryID()),
       material(material), fem(&fem), element_filter(element_filter),
       default_value(T()), spatial_dimension(material.getSpatialDimension()),
       element_kind(_ek_regular), nb_component(0), is_init(false),
       previous_values(nullptr) {}
 
 /* -------------------------------------------------------------------------- */
 template <typename T>
 InternalField<T>::InternalField(
     const ID & id, Material & material, UInt dim, FEEngine & fem,
     const ElementTypeMapArray<UInt> & element_filter)
     : ElementTypeMapArray<T>(id, material.getID(), material.getMemoryID()),
       material(material), fem(&fem), element_filter(element_filter),
       default_value(T()), spatial_dimension(dim), element_kind(_ek_regular),
       nb_component(0), is_init(false), previous_values(nullptr) {}
 
 /* -------------------------------------------------------------------------- */
 template <typename T>
 InternalField<T>::InternalField(const ID & id, const InternalField<T> & other)
     : ElementTypeMapArray<T>(id, other.material.getID(),
                              other.material.getMemoryID()),
       material(other.material), fem(other.fem),
       element_filter(other.element_filter), default_value(other.default_value),
       spatial_dimension(other.spatial_dimension),
       element_kind(other.element_kind), nb_component(other.nb_component),
       is_init(false), previous_values(nullptr) {
 
   AKANTU_DEBUG_ASSERT(other.is_init,
                       "Cannot create a copy of a non initialized field");
   this->internalInitialize(this->nb_component);
 }
 
 /* -------------------------------------------------------------------------- */
 template <typename T> InternalField<T>::~InternalField() {
   if (this->is_init) {
     this->material.unregisterInternal(*this);
   }
 
   delete previous_values;
 }
 
 /* -------------------------------------------------------------------------- */
 template <typename T> void InternalField<T>::setFEEngine(FEEngine & fe_engine) {
   this->fem = &fe_engine;
 }
 
 /* -------------------------------------------------------------------------- */
 template <typename T>
 void InternalField<T>::setElementKind(ElementKind element_kind) {
   this->element_kind = element_kind;
 }
 
 /* -------------------------------------------------------------------------- */
 template <typename T> void InternalField<T>::initialize(UInt nb_component) {
   internalInitialize(nb_component);
 }
 
 /* -------------------------------------------------------------------------- */
 template <typename T> void InternalField<T>::initializeHistory() {
   if (!previous_values)
     previous_values = new InternalField<T>("previous_" + this->getID(), *this);
 }
 
 /* -------------------------------------------------------------------------- */
 template <typename T> void InternalField<T>::resize() {
   if (!this->is_init)
     return;
 
   for (ghost_type_t::iterator gt = ghost_type_t::begin();
        gt != ghost_type_t::end(); ++gt) {
 
     filter_type_iterator it = this->filterFirstType(*gt);
     filter_type_iterator end = this->filterLastType(*gt);
 
     for (; it != end; ++it) {
       UInt nb_element = this->element_filter(*it, *gt).size();
 
       UInt nb_quadrature_points = this->fem->getNbIntegrationPoints(*it, *gt);
       UInt new_size = nb_element * nb_quadrature_points;
 
       UInt old_size = 0;
       Array<T> * vect = nullptr;
 
       if (this->exists(*it, *gt)) {
         vect = &(this->operator()(*it, *gt));
         old_size = vect->size();
         vect->resize(new_size);
       } else {
         vect = &(this->alloc(nb_element * nb_quadrature_points, nb_component,
                              *it, *gt));
       }
 
       this->setArrayValues(vect->storage() + old_size * vect->getNbComponent(),
                            vect->storage() + new_size * vect->getNbComponent());
     }
   }
 }
 
 /* -------------------------------------------------------------------------- */
 template <typename T> void InternalField<T>::setDefaultValue(const T & value) {
   this->default_value = value;
   this->reset();
 }
 
 /* -------------------------------------------------------------------------- */
 template <typename T> void InternalField<T>::reset() {
   for (ghost_type_t::iterator gt = ghost_type_t::begin();
        gt != ghost_type_t::end(); ++gt) {
 
     type_iterator it = this->firstType(*gt);
     type_iterator end = this->lastType(*gt);
     for (; it != end; ++it) {
       Array<T> & vect = this->operator()(*it, *gt);
       vect.clear();
       this->setArrayValues(
           vect.storage(), vect.storage() + vect.size() * vect.getNbComponent());
     }
   }
 }
 
 /* -------------------------------------------------------------------------- */
 template <typename T>
 void InternalField<T>::internalInitialize(UInt nb_component) {
   if (!this->is_init) {
     this->nb_component = nb_component;
 
     for (ghost_type_t::iterator gt = ghost_type_t::begin();
          gt != ghost_type_t::end(); ++gt) {
       filter_type_iterator it = this->filterFirstType(*gt);
       filter_type_iterator end = this->filterLastType(*gt);
 
       for (; it != end; ++it) {
         UInt nb_element = this->element_filter(*it, *gt).size();
         UInt nb_quadrature_points = this->fem->getNbIntegrationPoints(*it, *gt);
         if (this->exists(*it, *gt))
           this->operator()(*it, *gt).resize(nb_element * nb_quadrature_points);
         else
           this->alloc(nb_element * nb_quadrature_points, nb_component, *it,
                       *gt);
       }
     }
 
     this->material.registerInternal(*this);
     this->is_init = true;
   }
   this->reset();
 
   if (this->previous_values)
     this->previous_values->internalInitialize(nb_component);
 }
 
 /* -------------------------------------------------------------------------- */
 template <typename T>
 void InternalField<T>::setArrayValues(T * begin, T * end) {
   for (; begin < end; ++begin)
     *begin = this->default_value;
 }
 
 /* -------------------------------------------------------------------------- */
 template <typename T> void InternalField<T>::saveCurrentValues() {
   AKANTU_DEBUG_ASSERT(this->previous_values != nullptr,
                       "The history of the internal "
                           << this->getID() << " has not been activated");
 
   if (!this->is_init)
     return;
 
   for (ghost_type_t::iterator gt = ghost_type_t::begin();
        gt != ghost_type_t::end(); ++gt) {
     type_iterator it = this->firstType(*gt);
     type_iterator end = this->lastType(*gt);
     for (; it != end; ++it) {
       this->previous_values->operator()(*it, *gt).copy(
           this->operator()(*it, *gt));
     }
   }
 }
 
 /* -------------------------------------------------------------------------- */
 template <typename T>
 void InternalField<T>::removeIntegrationPoints(
     const ElementTypeMapArray<UInt> & new_numbering) {
   for (auto ghost_type : ghost_types) {
     for (auto type : new_numbering.elementTypes(_all_dimensions, ghost_type,
                                                 _ek_not_defined)) {
       if (not this->exists(type, ghost_type))
         continue;
 
       Array<T> & vect = this->operator()(type, ghost_type);
       if (vect.size() == 0)
         continue;
 
       const Array<UInt> & renumbering = new_numbering(type, ghost_type);
 
       UInt nb_quad_per_elem = fem->getNbIntegrationPoints(type, ghost_type);
       UInt nb_component = vect.getNbComponent();
 
       Array<T> tmp(renumbering.size() * nb_quad_per_elem, nb_component);
 
       AKANTU_DEBUG_ASSERT(
           tmp.size() == vect.size(),
           "Something strange append some mater was created from nowhere!!");
 
       AKANTU_DEBUG_ASSERT(
           tmp.size() == vect.size(),
           "Something strange append some mater was created or disappeared in "
               << vect.getID() << "(" << vect.size() << "!=" << tmp.size()
               << ") "
                  "!!");
 
       UInt new_size = 0;
       for (UInt i = 0; i < renumbering.size(); ++i) {
         UInt new_i = renumbering(i);
         if (new_i != UInt(-1)) {
           memcpy(tmp.storage() + new_i * nb_component * nb_quad_per_elem,
                  vect.storage() + i * nb_component * nb_quad_per_elem,
                  nb_component * nb_quad_per_elem * sizeof(T));
           ++new_size;
         }
       }
       tmp.resize(new_size * nb_quad_per_elem);
       vect.copy(tmp);
     }
   }
 }
 
 /* -------------------------------------------------------------------------- */
 template <typename T>
 void InternalField<T>::printself(std::ostream & stream,
                                  int indent[[gnu::unused]]) const {
   stream << "InternalField [ " << this->getID();
 #if !defined(AKANTU_NDEBUG)
   if (AKANTU_DEBUG_TEST(dblDump)) {
     stream << std::endl;
     ElementTypeMapArray<T>::printself(stream, indent + 3);
   } else {
 #endif
     stream << " {" << this->getData(_not_ghost).size() << " types - "
            << this->getData(_ghost).size() << " ghost types"
            << "}";
 #if !defined(AKANTU_NDEBUG)
   }
 #endif
   stream << " ]";
 }
 
 /* -------------------------------------------------------------------------- */
 template <>
 inline void
 ParameterTyped<InternalField<Real>>::setAuto(const ParserParameter & in_param) {
   Parameter::setAuto(in_param);
   Real r = in_param;
   param.setDefaultValue(r);
 }
 
 /* -------------------------------------------------------------------------- */
 template <typename T> inline InternalField<T>::operator T() const {
   return default_value;
 }
 
 } // akantu
 
 #endif /* __AKANTU_INTERNAL_FIELD_TMPL_HH__ */
diff --git a/src/model/solid_mechanics/materials/material_core_includes.hh b/src/model/solid_mechanics/materials/material_core_includes.hh
index 5804db7da..a95a5b1a3 100644
--- a/src/model/solid_mechanics/materials/material_core_includes.hh
+++ b/src/model/solid_mechanics/materials/material_core_includes.hh
@@ -1,68 +1,68 @@
 /**
  * @file   material_core_includes.hh
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Thu Feb 21 2013
- * @date last modification: Sat Jul 18 2015
+ * @date last modification: Wed Feb 03 2016
  *
  * @brief  List of materials for core package
  *
  * @section LICENSE
  *
- * Copyright  (©)  2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de Lausanne)
+ * 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
+ * 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
+ * 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_MATERIAL_CORE_INCLUDES_HH__
 #define __AKANTU_MATERIAL_CORE_INCLUDES_HH__
 
 /* -------------------------------------------------------------------------- */
 /* Material list                                                              */
 /* -------------------------------------------------------------------------- */
 #ifndef AKANTU_CMAKE_LIST_MATERIALS
 
 // elastic materials
 #include "material_elastic.hh"
 #include "material_elastic_linear_anisotropic.hh"
 #include "material_elastic_orthotropic.hh"
 #include "material_neohookean.hh"
 
 // visco-elastic materials
 #include "material_standard_linear_solid_deviatoric.hh"
 
 // damage laws
 #include "material_marigo.hh"
 #include "material_mazars.hh"
 
 // small-deformation plasticity
 #include "material_linear_isotropic_hardening.hh"
 
 #endif
 
 #define AKANTU_CORE_MATERIAL_LIST                                              \
   ((2, (elastic, MaterialElastic)))((2, (neohookean, MaterialNeohookean)))(    \
       (2, (elastic_orthotropic, MaterialElasticOrthotropic)))(                 \
       (2, (elastic_anisotropic, MaterialElasticLinearAnisotropic)))(           \
       (2, (sls_deviatoric, MaterialStandardLinearSolidDeviatoric)))(           \
       (2, (marigo, MaterialMarigo)))((2, (mazars, MaterialMazars)))(           \
       (2, (plastic_linear_isotropic_hardening,                                 \
            MaterialLinearIsotropicHardening)))
 
 #endif /* __AKANTU_MATERIAL_CORE_INCLUDES_HH__ */
diff --git a/src/model/solid_mechanics/materials/material_damage/material_damage.hh b/src/model/solid_mechanics/materials/material_damage/material_damage.hh
index fb72e1549..6cefe9796 100644
--- a/src/model/solid_mechanics/materials/material_damage/material_damage.hh
+++ b/src/model/solid_mechanics/materials/material_damage/material_damage.hh
@@ -1,113 +1,112 @@
 /**
  * @file   material_damage.hh
  *
  * @author Marion Estelle Chambart <marion.chambart@epfl.ch>
  * @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Fri Jun 18 2010
- * @date last modification: Sat Jul 11 2015
+ * @date last modification: Sun Dec 03 2017
  *
  * @brief  Material isotropic elastic
  *
  * @section LICENSE
  *
- * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
- * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
- * Solides)
+ * 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
+ * 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
+ * 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 "material_elastic.hh"
 /* -------------------------------------------------------------------------- */
 
 #ifndef __AKANTU_MATERIAL_DAMAGE_HH__
 #define __AKANTU_MATERIAL_DAMAGE_HH__
 
 namespace akantu {
 template <UInt spatial_dimension,
           template <UInt> class Parent = MaterialElastic>
 class MaterialDamage : public Parent<spatial_dimension> {
   /* ------------------------------------------------------------------------ */
   /* Constructors/Destructors                                                 */
   /* ------------------------------------------------------------------------ */
 public:
   MaterialDamage(SolidMechanicsModel & model, const ID & id = "");
   ~MaterialDamage() override = default;
 
   /* ------------------------------------------------------------------------ */
   /* Methods                                                                  */
   /* ------------------------------------------------------------------------ */
 public:
   void initMaterial() override;
 
   /// compute the tangent stiffness matrix for an element type
   void computeTangentModuli(const ElementType & el_type,
                             Array<Real> & tangent_matrix,
                             GhostType ghost_type = _not_ghost) override;
   bool hasStiffnessMatrixChanged() override { return true; }
 
 protected:
   /// update the dissipated energy, must be called after the stress have been
   /// computed
   void updateEnergies(ElementType el_type, GhostType ghost_type) override;
 
   /// compute the tangent stiffness matrix for a given quadrature point
   inline void computeTangentModuliOnQuad(Matrix<Real> & tangent, Real & dam);
 
   /* ------------------------------------------------------------------------ */
   /* DataAccessor inherited members                                           */
   /* ------------------------------------------------------------------------ */
 public:
   /* ------------------------------------------------------------------------ */
   /* Accessors                                                                */
   /* ------------------------------------------------------------------------ */
 public:
   /// give the dissipated energy for the time step
   Real getDissipatedEnergy() const;
 
   Real getEnergy(const std::string & type) override;
   Real getEnergy(const std::string & energy_id, ElementType type,
                  UInt index) override {
     return Parent<spatial_dimension>::getEnergy(energy_id, type, index);
   };
 
   AKANTU_GET_MACRO_NOT_CONST(Damage, damage, ElementTypeMapArray<Real> &);
   AKANTU_GET_MACRO(Damage, damage, const ElementTypeMapArray<Real> &);
   AKANTU_GET_MACRO_BY_ELEMENT_TYPE_CONST(Damage, damage, Real)
 
   /* ------------------------------------------------------------------------ */
   /* Class Members                                                            */
   /* ------------------------------------------------------------------------ */
 protected:
   /// damage internal variable
   InternalField<Real> damage;
 
   /// dissipated energy
   InternalField<Real> dissipated_energy;
 
   /// contain the current value of @f$ \int_0^{\epsilon}\sigma(\omega)d\omega
   /// @f$ the dissipated energy
   InternalField<Real> int_sigma;
 };
 
 } // namespace akantu
 
 #include "material_damage_tmpl.hh"
 
 #endif /* __AKANTU_MATERIAL_DAMAGE_HH__ */
diff --git a/src/model/solid_mechanics/materials/material_damage/material_damage_non_local.hh b/src/model/solid_mechanics/materials/material_damage/material_damage_non_local.hh
index 707acab2a..f83923f3e 100644
--- a/src/model/solid_mechanics/materials/material_damage/material_damage_non_local.hh
+++ b/src/model/solid_mechanics/materials/material_damage/material_damage_non_local.hh
@@ -1,74 +1,73 @@
 /**
  * @file   material_damage_non_local.hh
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Thu Aug 23 2012
- * @date last modification: Wed Oct 21 2015
+ * @date last modification: Mon Sep 11 2017
  *
  * @brief  interface for non local damage material
  *
  * @section LICENSE
  *
- * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
- * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
- * Solides)
+ * 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
+ * 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
+ * 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 "material_non_local.hh"
 /* -------------------------------------------------------------------------- */
 
 #ifndef __AKANTU_MATERIAL_DAMAGE_NON_LOCAL_HH__
 #define __AKANTU_MATERIAL_DAMAGE_NON_LOCAL_HH__
 
 namespace akantu {
 
 template <UInt dim, class MaterialDamageLocal>
 class MaterialDamageNonLocal
     : public MaterialNonLocal<dim, MaterialDamageLocal> {
 public:
   using MaterialParent = MaterialNonLocal<dim, MaterialDamageLocal>;
 
   MaterialDamageNonLocal(SolidMechanicsModel & model, const ID & id)
       : MaterialParent(model, id){};
 
 protected:
   /* ------------------------------------------------------------------------ */
   virtual void computeNonLocalStress(ElementType type,
                                      GhostType ghost_type = _not_ghost) = 0;
 
   /* ------------------------------------------------------------------------ */
   void computeNonLocalStresses(GhostType ghost_type) override {
     AKANTU_DEBUG_IN();
 
     for (auto type : this->element_filter.elementTypes(dim, ghost_type)) {
       auto & elem_filter = this->element_filter(type, ghost_type);
       if (elem_filter.size() == 0)
         continue;
 
       computeNonLocalStress(type, ghost_type);
     }
 
     AKANTU_DEBUG_OUT();
   }
 };
 
 } // namespace akantu
 
 #endif /* __AKANTU_MATERIAL_DAMAGE_NON_LOCAL_HH__ */
diff --git a/src/model/solid_mechanics/materials/material_damage/material_damage_tmpl.hh b/src/model/solid_mechanics/materials/material_damage/material_damage_tmpl.hh
index 2876eb704..88e744546 100644
--- a/src/model/solid_mechanics/materials/material_damage/material_damage_tmpl.hh
+++ b/src/model/solid_mechanics/materials/material_damage/material_damage_tmpl.hh
@@ -1,181 +1,181 @@
 /**
  * @file   material_damage_tmpl.hh
  *
  * @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
+ * @author Marion Estelle Chambart <mchambart@stucky.ch>
  * @author Marion Estelle Chambart <marion.chambart@epfl.ch>
  * @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
  * @author Daniel Pino Muñoz <daniel.pinomunoz@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Fri Jun 18 2010
- * @date last modification: Tue Aug 18 2015
+ * @date last modification: Sun Dec 03 2017
  *
  * @brief  Specialization of the material class for the damage material
  *
  * @section LICENSE
  *
- * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
- * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
- * Solides)
+ * 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
+ * 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
+ * A PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 #include "material_damage.hh"
 #include "solid_mechanics_model.hh"
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 template <UInt spatial_dimension, template <UInt> class Parent>
 MaterialDamage<spatial_dimension, Parent>::MaterialDamage(
     SolidMechanicsModel & model, const ID & id)
     : Parent<spatial_dimension>(model, id), damage("damage", *this),
       dissipated_energy("damage dissipated energy", *this),
       int_sigma("integral of sigma", *this) {
   AKANTU_DEBUG_IN();
 
   this->is_non_local = false;
   this->use_previous_stress = true;
   this->use_previous_gradu = true;
 
   this->damage.initialize(1);
   this->dissipated_energy.initialize(1);
   this->int_sigma.initialize(1);
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <UInt spatial_dimension, template <UInt> class Parent>
 void MaterialDamage<spatial_dimension, Parent>::initMaterial() {
   AKANTU_DEBUG_IN();
   Parent<spatial_dimension>::initMaterial();
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 /**
  * Compute the dissipated energy in  each element by a trapezoidal approximation
  * of
  * @f$ Ed = \int_0^{\epsilon}\sigma(\omega)d\omega -
  * \frac{1}{2}\sigma:\epsilon@f$
  */
 template <UInt spatial_dimension, template <UInt> class Parent>
 void MaterialDamage<spatial_dimension, Parent>::updateEnergies(
     ElementType el_type, GhostType ghost_type) {
   Parent<spatial_dimension>::updateEnergies(el_type, ghost_type);
 
   this->computePotentialEnergy(el_type, ghost_type);
 
   Array<Real>::matrix_iterator epsilon_p =
       this->gradu.previous(el_type, ghost_type)
           .begin(spatial_dimension, spatial_dimension);
   Array<Real>::matrix_iterator sigma_p =
       this->stress.previous(el_type, ghost_type)
           .begin(spatial_dimension, spatial_dimension);
 
   Array<Real>::const_scalar_iterator epot =
       this->potential_energy(el_type, ghost_type).begin();
 
   Array<Real>::scalar_iterator ints =
       this->int_sigma(el_type, ghost_type).begin();
   Array<Real>::scalar_iterator ed =
       this->dissipated_energy(el_type, ghost_type).begin();
 
   MATERIAL_STRESS_QUADRATURE_POINT_LOOP_BEGIN(el_type, ghost_type);
 
   Matrix<Real> delta_gradu_it(*gradu_it);
   delta_gradu_it -= *epsilon_p;
 
   Matrix<Real> sigma_h(sigma);
   sigma_h += *sigma_p;
 
   Real dint = .5 * sigma_h.doubleDot(delta_gradu_it);
 
   *ints += dint;
   *ed = *ints - *epot;
 
   ++epsilon_p;
   ++sigma_p;
   ++epot;
   ++ints;
   ++ed;
 
   MATERIAL_STRESS_QUADRATURE_POINT_LOOP_END;
 }
 
 /* -------------------------------------------------------------------------- */
 template <UInt spatial_dimension, template <UInt> class Parent>
 void MaterialDamage<spatial_dimension, Parent>::computeTangentModuli(
     const ElementType & el_type, Array<Real> & tangent_matrix,
     GhostType ghost_type) {
   AKANTU_DEBUG_IN();
 
   Parent<spatial_dimension>::computeTangentModuli(el_type, tangent_matrix,
                                                   ghost_type);
 
   Real * dam = this->damage(el_type, ghost_type).storage();
 
   MATERIAL_TANGENT_QUADRATURE_POINT_LOOP_BEGIN(tangent_matrix);
   computeTangentModuliOnQuad(tangent, *dam);
 
   ++dam;
 
   MATERIAL_TANGENT_QUADRATURE_POINT_LOOP_END;
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <UInt spatial_dimension, template <UInt> class Parent>
 void MaterialDamage<spatial_dimension, Parent>::computeTangentModuliOnQuad(
     Matrix<Real> & tangent, Real & dam) {
   tangent *= (1 - dam);
 }
 
 /* -------------------------------------------------------------------------- */
 template <UInt spatial_dimension, template <UInt> class Parent>
 Real MaterialDamage<spatial_dimension, Parent>::getDissipatedEnergy() const {
   AKANTU_DEBUG_IN();
 
   Real de = 0.;
 
   /// integrate the dissipated energy for each type of elements
   for (auto & type :
        this->element_filter.elementTypes(spatial_dimension, _not_ghost)) {
     de +=
         this->fem.integrate(dissipated_energy(type, _not_ghost), type,
                             _not_ghost, this->element_filter(type, _not_ghost));
   }
 
   AKANTU_DEBUG_OUT();
   return de;
 }
 
 /* -------------------------------------------------------------------------- */
 template <UInt spatial_dimension, template <UInt> class Parent>
 Real MaterialDamage<spatial_dimension, Parent>::getEnergy(
     const std::string & type) {
   if (type == "dissipated")
     return getDissipatedEnergy();
   else
     return Parent<spatial_dimension>::getEnergy(type);
 }
 
 /* -------------------------------------------------------------------------- */
 
 } // namespace akantu
diff --git a/src/model/solid_mechanics/materials/material_damage/material_marigo.cc b/src/model/solid_mechanics/materials/material_damage/material_marigo.cc
index 83738f986..d29e96758 100644
--- a/src/model/solid_mechanics/materials/material_damage/material_marigo.cc
+++ b/src/model/solid_mechanics/materials/material_damage/material_marigo.cc
@@ -1,107 +1,106 @@
 /**
  * @file   material_marigo.cc
  *
  * @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
  * @author Marion Estelle Chambart <marion.chambart@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Fri Jun 18 2010
- * @date last modification: Thu Oct 08 2015
+ * @date last modification: Sun Jul 09 2017
  *
  * @brief  Specialization of the material class for the marigo material
  *
  * @section LICENSE
  *
- * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
- * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
- * Solides)
+ * 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
+ * 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
+ * A PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 #include "material_marigo.hh"
 #include "solid_mechanics_model.hh"
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 template <UInt spatial_dimension>
 MaterialMarigo<spatial_dimension>::MaterialMarigo(SolidMechanicsModel & model,
                                                   const ID & id)
     : MaterialDamage<spatial_dimension>(model, id), Yd("Yd", *this),
       damage_in_y(false), yc_limit(false) {
   AKANTU_DEBUG_IN();
 
   this->registerParam("Sd", Sd, Real(5000.), _pat_parsable | _pat_modifiable);
   this->registerParam("epsilon_c", epsilon_c, Real(0.), _pat_parsable,
                       "Critical strain");
   this->registerParam("Yc limit", yc_limit, false, _pat_internal,
                       "As the material a critical Y");
   this->registerParam("damage_in_y", damage_in_y, false, _pat_parsable,
                       "Use threshold (1-D)Y");
   this->registerParam("Yd", Yd, _pat_parsable, "Damaging energy threshold");
 
   this->Yd.initialize(1);
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <UInt spatial_dimension>
 void MaterialMarigo<spatial_dimension>::initMaterial() {
   AKANTU_DEBUG_IN();
   MaterialDamage<spatial_dimension>::initMaterial();
 
   updateInternalParameters();
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <UInt spatial_dimension>
 void MaterialMarigo<spatial_dimension>::updateInternalParameters() {
   MaterialDamage<spatial_dimension>::updateInternalParameters();
   Yc = .5 * epsilon_c * this->E * epsilon_c;
   if (std::abs(epsilon_c) > std::numeric_limits<Real>::epsilon())
     yc_limit = true;
   else
     yc_limit = false;
 }
 
 /* -------------------------------------------------------------------------- */
 template <UInt spatial_dimension>
 void MaterialMarigo<spatial_dimension>::computeStress(ElementType el_type,
                                                       GhostType ghost_type) {
   AKANTU_DEBUG_IN();
 
   Array<Real>::scalar_iterator dam = this->damage(el_type, ghost_type).begin();
   Array<Real>::scalar_iterator Yd_q = this->Yd(el_type, ghost_type).begin();
 
   MATERIAL_STRESS_QUADRATURE_POINT_LOOP_BEGIN(el_type, ghost_type);
 
   Real Y = 0.;
   computeStressOnQuad(grad_u, sigma, *dam, Y, *Yd_q);
 
   ++dam;
   ++Yd_q;
 
   MATERIAL_STRESS_QUADRATURE_POINT_LOOP_END;
 
   AKANTU_DEBUG_OUT();
 }
 
 INSTANTIATE_MATERIAL(marigo, MaterialMarigo);
 
 } // namespace akantu
diff --git a/src/model/solid_mechanics/materials/material_damage/material_marigo.hh b/src/model/solid_mechanics/materials/material_damage/material_marigo.hh
index 39cb01c1e..3f5b63277 100644
--- a/src/model/solid_mechanics/materials/material_damage/material_marigo.hh
+++ b/src/model/solid_mechanics/materials/material_damage/material_marigo.hh
@@ -1,124 +1,123 @@
 /**
  * @file   material_marigo.hh
  *
  * @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
  * @author Marion Estelle Chambart <marion.chambart@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Fri Jun 18 2010
- * @date last modification: Sun Oct 19 2014
+ * @date last modification: Wed Nov 08 2017
  *
  * @brief  Marigo damage law
  *
  * @section LICENSE
  *
- * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
- * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
- * Solides)
+ * 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
+ * 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
+ * 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 "material.hh"
 #include "material_damage.hh"
 /* -------------------------------------------------------------------------- */
 
 #ifndef __AKANTU_MATERIAL_MARIGO_HH__
 #define __AKANTU_MATERIAL_MARIGO_HH__
 
 namespace akantu {
 
 /**
  * Material marigo
  *
  * parameters in the material files :
  *   - Yd  : (default: 50)
  *   - Sd  : (default: 5000)
  *   - Ydrandomness  : (default:0)
  */
 template <UInt spatial_dimension>
 class MaterialMarigo : public MaterialDamage<spatial_dimension> {
   /* ------------------------------------------------------------------------ */
   /* Constructors/Destructors                                                 */
   /* ------------------------------------------------------------------------ */
 public:
   MaterialMarigo(SolidMechanicsModel & model, const ID & id = "");
   ~MaterialMarigo() override = default;
 
   /* ------------------------------------------------------------------------ */
   /* Methods                                                                  */
   /* ------------------------------------------------------------------------ */
 public:
   void initMaterial() override;
 
   void updateInternalParameters() override;
 
   /// constitutive law for all element of a type
   void computeStress(ElementType el_type,
                      GhostType ghost_type = _not_ghost) override;
 
 protected:
   /// constitutive law for a given quadrature point
   inline void computeStressOnQuad(Matrix<Real> & grad_u, Matrix<Real> & sigma,
                                   Real & dam, Real & Y, Real & Ydq);
 
   inline void computeDamageAndStressOnQuad(Matrix<Real> & sigma, Real & dam,
                                            Real & Y, Real & Ydq);
 
   /* ------------------------------------------------------------------------ */
   /* DataAccessor inherited members                                           */
   /* ------------------------------------------------------------------------ */
 public:
   inline UInt getNbData(const Array<Element> & elements,
                         const SynchronizationTag & tag) const override;
 
   inline void packData(CommunicationBuffer & buffer,
                        const Array<Element> & elements,
                        const SynchronizationTag & tag) const override;
 
   inline void unpackData(CommunicationBuffer & buffer,
                          const Array<Element> & elements,
                          const SynchronizationTag & tag) override;
 
   /* ------------------------------------------------------------------------ */
   /* Accessors                                                                */
   /* ------------------------------------------------------------------------ */
 public:
   /* ------------------------------------------------------------------------ */
   /* Class Members                                                            */
   /* ------------------------------------------------------------------------ */
 protected:
   /// resistance to damage
   RandomInternalField<Real> Yd;
 
   /// damage threshold
   Real Sd;
 
   /// critical epsilon when the material is considered as broken
   Real epsilon_c;
 
   Real Yc;
 
   bool damage_in_y;
   bool yc_limit;
 };
 
 } // akantu
 
 #include "material_marigo_inline_impl.cc"
 
 #endif /* __AKANTU_MATERIAL_MARIGO_HH__ */
diff --git a/src/model/solid_mechanics/materials/material_damage/material_marigo_inline_impl.cc b/src/model/solid_mechanics/materials/material_damage/material_marigo_inline_impl.cc
index a0df92944..1288d566f 100644
--- a/src/model/solid_mechanics/materials/material_damage/material_marigo_inline_impl.cc
+++ b/src/model/solid_mechanics/materials/material_damage/material_marigo_inline_impl.cc
@@ -1,132 +1,131 @@
 /**
  * @file   material_marigo_inline_impl.cc
  *
  * @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
  * @author Marion Estelle Chambart <marion.chambart@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Wed Aug 04 2010
- * @date last modification: Thu Oct 15 2015
+ * @date last modification: Fri Dec 02 2016
  *
  * @brief  Implementation of the inline functions of the material marigo
  *
  * @section LICENSE
  *
- * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
- * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
- * Solides)
+ * 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
+ * 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
+ * A PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 #include "material_marigo.hh"
 
 #ifndef __AKANTU_MATERIAL_MARIGO_INLINE_IMPL_CC__
 #define __AKANTU_MATERIAL_MARIGO_INLINE_IMPL_CC__
 
 namespace akantu {
 
 template <UInt spatial_dimension>
 inline void MaterialMarigo<spatial_dimension>::computeStressOnQuad(
     Matrix<Real> & grad_u, Matrix<Real> & sigma, Real & dam, Real & Y,
     Real & Ydq) {
   MaterialElastic<spatial_dimension>::computeStressOnQuad(grad_u, sigma);
 
   Y = 0;
   for (UInt i = 0; i < spatial_dimension; ++i) {
     for (UInt j = 0; j < spatial_dimension; ++j) {
       Y += sigma(i, j) * (grad_u(i, j) + grad_u(j, i)) / 2.;
     }
   }
   Y *= 0.5;
 
   if (damage_in_y)
     Y *= (1 - dam);
 
   if (yc_limit)
     Y = std::min(Y, Yc);
 
   if (!this->is_non_local) {
     computeDamageAndStressOnQuad(sigma, dam, Y, Ydq);
   }
 }
 
 /* -------------------------------------------------------------------------- */
 template <UInt spatial_dimension>
 inline void MaterialMarigo<spatial_dimension>::computeDamageAndStressOnQuad(
     Matrix<Real> & sigma, Real & dam, Real & Y, Real & Ydq) {
   Real Fd = Y - Ydq - Sd * dam;
 
   if (Fd > 0)
     dam = (Y - Ydq) / Sd;
   dam = std::min(dam, Real(1.));
 
   sigma *= 1 - dam;
 }
 
 /* -------------------------------------------------------------------------- */
 template <UInt spatial_dimension>
 inline UInt MaterialMarigo<spatial_dimension>::getNbData(
     const Array<Element> & elements, const SynchronizationTag & tag) const {
   AKANTU_DEBUG_IN();
 
   UInt size = 0;
   if (tag == _gst_smm_init_mat) {
     size += sizeof(Real) * this->getModel().getNbIntegrationPoints(elements);
   }
 
   size += MaterialDamage<spatial_dimension>::getNbData(elements, tag);
 
   AKANTU_DEBUG_OUT();
   return size;
 }
 
 /* -------------------------------------------------------------------------- */
 template <UInt spatial_dimension>
 inline void MaterialMarigo<spatial_dimension>::packData(
     CommunicationBuffer & buffer, const Array<Element> & elements,
     const SynchronizationTag & tag) const {
   AKANTU_DEBUG_IN();
 
   if (tag == _gst_smm_init_mat) {
     this->packElementDataHelper(Yd, buffer, elements);
   }
 
   MaterialDamage<spatial_dimension>::packData(buffer, elements, tag);
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <UInt spatial_dimension>
 inline void
 MaterialMarigo<spatial_dimension>::unpackData(CommunicationBuffer & buffer,
                                               const Array<Element> & elements,
                                               const SynchronizationTag & tag) {
   AKANTU_DEBUG_IN();
 
   if (tag == _gst_smm_init_mat) {
     this->unpackElementDataHelper(Yd, buffer, elements);
   }
 
   MaterialDamage<spatial_dimension>::unpackData(buffer, elements, tag);
 
   AKANTU_DEBUG_OUT();
 }
 
 } // akantu
 
 #endif /* __AKANTU_MATERIAL_MARIGO_INLINE_IMPL_CC__ */
diff --git a/src/model/solid_mechanics/materials/material_damage/material_marigo_non_local.cc b/src/model/solid_mechanics/materials/material_damage/material_marigo_non_local.cc
index 6eb060efe..731d6e099 100644
--- a/src/model/solid_mechanics/materials/material_damage/material_marigo_non_local.cc
+++ b/src/model/solid_mechanics/materials/material_damage/material_marigo_non_local.cc
@@ -1,106 +1,106 @@
 /**
  * @file   material_marigo_non_local.cc
  *
+ * @author Marion Estelle Chambart <mchambart@stucky.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Fri Jun 18 2010
- * @date last modification: Thu Oct 15 2015
+ * @date last modification: Mon Sep 11 2017
  *
  * @brief  Marigo non-local inline function implementation
  *
  * @section LICENSE
  *
- * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
- * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
- * Solides)
+ * 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
+ * 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
+ * A PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 #include "material_marigo_non_local.hh"
 #include "non_local_neighborhood_base.hh"
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 template <UInt spatial_dimension>
 MaterialMarigoNonLocal<spatial_dimension>::MaterialMarigoNonLocal(
     SolidMechanicsModel & model, const ID & id)
     : MaterialMarigoNonLocalParent(model, id), Y("Y", *this),
       Ynl("Y non local", *this) {
   AKANTU_DEBUG_IN();
   this->is_non_local = true;
   this->Y.initialize(1);
   this->Ynl.initialize(1);
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <UInt spatial_dimension>
 void MaterialMarigoNonLocal<spatial_dimension>::registerNonLocalVariables() {
   this->model.getNonLocalManager().registerNonLocalVariable(this->Y.getName(),
                                                             Ynl.getName(), 1);
   this->model.getNonLocalManager()
       .getNeighborhood(this->name)
       .registerNonLocalVariable(Ynl.getName());
 }
 
 /* -------------------------------------------------------------------------- */
 template <UInt spatial_dimension>
 void MaterialMarigoNonLocal<spatial_dimension>::computeStress(
     ElementType el_type, GhostType ghost_type) {
   AKANTU_DEBUG_IN();
 
   Real * dam = this->damage(el_type, ghost_type).storage();
   Real * Yt = this->Y(el_type, ghost_type).storage();
   Real * Ydq = this->Yd(el_type, ghost_type).storage();
 
   MATERIAL_STRESS_QUADRATURE_POINT_LOOP_BEGIN(el_type, ghost_type);
   MaterialMarigo<spatial_dimension>::computeStressOnQuad(grad_u, sigma, *dam,
                                                          *Yt, *Ydq);
   ++dam;
   ++Yt;
   ++Ydq;
   MATERIAL_STRESS_QUADRATURE_POINT_LOOP_END;
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <UInt spatial_dimension>
 void MaterialMarigoNonLocal<spatial_dimension>::computeNonLocalStress(
     ElementType type, GhostType ghost_type) {
   AKANTU_DEBUG_IN();
 
   Real * dam = this->damage(type, ghost_type).storage();
   Real * Ydq = this->Yd(type, ghost_type).storage();
   Real * Ynlt = this->Ynl(type, ghost_type).storage();
 
   MATERIAL_STRESS_QUADRATURE_POINT_LOOP_BEGIN(type, ghost_type);
   this->computeDamageAndStressOnQuad(sigma, *dam, *Ynlt, *Ydq);
 
   ++dam;
   ++Ynlt;
   ++Ydq;
   MATERIAL_STRESS_QUADRATURE_POINT_LOOP_END;
 
   AKANTU_DEBUG_OUT();
 }
 
 INSTANTIATE_MATERIAL(marigo_non_local, MaterialMarigoNonLocal);
 
 } // namespace akantu
diff --git a/src/model/solid_mechanics/materials/material_damage/material_marigo_non_local.hh b/src/model/solid_mechanics/materials/material_damage/material_marigo_non_local.hh
index b9085cdf5..7b563afa8 100644
--- a/src/model/solid_mechanics/materials/material_damage/material_marigo_non_local.hh
+++ b/src/model/solid_mechanics/materials/material_damage/material_marigo_non_local.hh
@@ -1,94 +1,93 @@
 /**
  * @file   material_marigo_non_local.hh
  *
  * @author Marion Estelle Chambart <marion.chambart@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Fri Jun 18 2010
- * @date last modification: Thu Oct 15 2015
+ * @date last modification: Wed Nov 08 2017
  *
  * @brief  Marigo non-local description
  *
  * @section LICENSE
  *
- * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
- * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
- * Solides)
+ * 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
+ * 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
+ * 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 "material_damage_non_local.hh"
 #include "material_marigo.hh"
 /* -------------------------------------------------------------------------- */
 
 #ifndef __AKANTU_MATERIAL_MARIGO_NON_LOCAL_HH__
 #define __AKANTU_MATERIAL_MARIGO_NON_LOCAL_HH__
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 
 /**
  * Material Marigo
  *
  * parameters in the material files :
  */
 template <UInt spatial_dimension>
 class MaterialMarigoNonLocal
     : public MaterialDamageNonLocal<spatial_dimension,
                                     MaterialMarigo<spatial_dimension>> {
   /* ------------------------------------------------------------------------ */
   /* Constructors/Destructors                                                 */
   /* ------------------------------------------------------------------------ */
 public:
   typedef MaterialDamageNonLocal<spatial_dimension,
                                  MaterialMarigo<spatial_dimension>>
       MaterialMarigoNonLocalParent;
   MaterialMarigoNonLocal(SolidMechanicsModel & model, const ID & id = "");
 
   /* ------------------------------------------------------------------------ */
   /* Methods                                                                  */
   /* ------------------------------------------------------------------------ */
 protected:
   void registerNonLocalVariables() override;
 
   /// constitutive law
   void computeStress(ElementType el_type,
                      GhostType ghost_type = _not_ghost) override;
 
   void computeNonLocalStress(ElementType type,
                              GhostType ghost_type = _not_ghost) override;
 
 private:
   /* ------------------------------------------------------------------------ */
   /* Accessors                                                                */
   /* ------------------------------------------------------------------------ */
 public:
   AKANTU_GET_MACRO_BY_ELEMENT_TYPE_CONST(Y, Y, Real);
 
   /* ------------------------------------------------------------------------ */
   /* Class Members                                                            */
   /* ------------------------------------------------------------------------ */
 private:
   InternalField<Real> Y;
   InternalField<Real> Ynl;
 };
 
 } // namespace akantu
 
 #endif /* __AKANTU_MATERIAL_MARIGO_NON_LOCAL_HH__ */
diff --git a/src/model/solid_mechanics/materials/material_damage/material_mazars.cc b/src/model/solid_mechanics/materials/material_damage/material_mazars.cc
index fdba78438..7ada50bc7 100644
--- a/src/model/solid_mechanics/materials/material_damage/material_mazars.cc
+++ b/src/model/solid_mechanics/materials/material_damage/material_mazars.cc
@@ -1,82 +1,81 @@
 /**
  * @file   material_mazars.cc
  *
  * @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
  * @author Marion Estelle Chambart <marion.chambart@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Fri Jun 18 2010
- * @date last modification: Tue Aug 18 2015
+ * @date last modification: Sun Jul 09 2017
  *
  * @brief  Specialization of the material class for the damage material
  *
  * @section LICENSE
  *
- * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
- * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
- * Solides)
+ * 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
+ * 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
+ * A PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 #include "material_mazars.hh"
 #include "solid_mechanics_model.hh"
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 template <UInt spatial_dimension>
 MaterialMazars<spatial_dimension>::MaterialMazars(SolidMechanicsModel & model,
                                                   const ID & id)
     : MaterialDamage<spatial_dimension>(model, id), K0("K0", *this),
       damage_in_compute_stress(true) {
   AKANTU_DEBUG_IN();
 
   this->registerParam("K0", K0, _pat_parsable, "K0");
   this->registerParam("At", At, Real(0.8), _pat_parsable, "At");
   this->registerParam("Ac", Ac, Real(1.4), _pat_parsable, "Ac");
   this->registerParam("Bc", Bc, Real(1900.), _pat_parsable, "Bc");
   this->registerParam("Bt", Bt, Real(12000.), _pat_parsable, "Bt");
   this->registerParam("beta", beta, Real(1.06), _pat_parsable, "beta");
 
   this->K0.initialize(1);
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <UInt spatial_dimension>
 void MaterialMazars<spatial_dimension>::computeStress(ElementType el_type,
                                                       GhostType ghost_type) {
   AKANTU_DEBUG_IN();
 
   Real * dam = this->damage(el_type, ghost_type).storage();
 
   MATERIAL_STRESS_QUADRATURE_POINT_LOOP_BEGIN(el_type, ghost_type);
 
   Real Ehat = 0;
   computeStressOnQuad(grad_u, sigma, *dam, Ehat);
   ++dam;
 
   MATERIAL_STRESS_QUADRATURE_POINT_LOOP_END;
 
   AKANTU_DEBUG_OUT();
 }
 /* -------------------------------------------------------------------------- */
 
 INSTANTIATE_MATERIAL(mazars, MaterialMazars);
 
 } // namespace akantu
diff --git a/src/model/solid_mechanics/materials/material_damage/material_mazars.hh b/src/model/solid_mechanics/materials/material_damage/material_mazars.hh
index 40d5d4358..01a4f7ab6 100644
--- a/src/model/solid_mechanics/materials/material_damage/material_mazars.hh
+++ b/src/model/solid_mechanics/materials/material_damage/material_mazars.hh
@@ -1,125 +1,125 @@
 /**
  * @file   material_mazars.hh
  *
  * @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
  * @author Marion Estelle Chambart <marion.chambart@epfl.ch>
+ * @author Marion Estelle Chambart <mchambart@stucky.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Fri Jun 18 2010
- * @date last modification: Sun Oct 19 2014
+ * @date last modification: Wed Nov 08 2017
  *
  * @brief  Material Following the Mazars law for damage evolution
  *
  * @section LICENSE
  *
- * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
- * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
- * Solides)
+ * 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
+ * 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
+ * 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 "material.hh"
 #include "material_damage.hh"
 /* -------------------------------------------------------------------------- */
 
 #ifndef __AKANTU_MATERIAL_MAZARS_HH__
 #define __AKANTU_MATERIAL_MAZARS_HH__
 
 namespace akantu {
 
 /**
  * Material Mazars
  *
  * parameters in the material files :
  *   - rho  : density (default: 0)
  *   - E    : Young's modulus (default: 0)
  *   - nu   : Poisson's ratio (default: 1/2)
  *   - K0   : Damage threshold
  *   - At   : Parameter damage traction 1
  *   - Bt   : Parameter damage traction 2
  *   - Ac   : Parameter damage compression 1
  *   - Bc   : Parameter damage compression 2
  *   - beta : Parameter for shear
  */
 template <UInt spatial_dimension>
 class MaterialMazars : public MaterialDamage<spatial_dimension> {
   /* ------------------------------------------------------------------------ */
   /* Constructors/Destructors                                                 */
   /* ------------------------------------------------------------------------ */
 public:
   MaterialMazars(SolidMechanicsModel & model, const ID & id = "");
   ~MaterialMazars() override = default;
 
   /* ------------------------------------------------------------------------ */
   /* Methods                                                                  */
   /* ------------------------------------------------------------------------ */
 public:
   /// constitutive law for all element of a type
   void computeStress(ElementType el_type,
                      GhostType ghost_type = _not_ghost) override;
 
 protected:
   /// constitutive law for a given quadrature point
   inline void computeStressOnQuad(const Matrix<Real> & grad_u,
                                   Matrix<Real> & sigma, Real & damage,
                                   Real & Ehat);
 
   inline void computeDamageAndStressOnQuad(const Matrix<Real> & grad_u,
                                            Matrix<Real> & sigma, Real & damage,
                                            Real & Ehat);
 
   inline void computeDamageOnQuad(const Real & epsilon_equ,
                                   const Matrix<Real> & sigma,
                                   const Vector<Real> & epsilon_princ,
                                   Real & dam);
 
   /* ------------------------------------------------------------------------ */
   /* Accessors                                                                */
   /* ------------------------------------------------------------------------ */
 public:
   /* ------------------------------------------------------------------------ */
   /* Class Members                                                            */
   /* ------------------------------------------------------------------------ */
 protected:
   /// damage threshold
   RandomInternalField<Real> K0;
   /// parameter damage traction 1
   Real At;
   /// parameter damage traction 2
   Real Bt;
   /// parameter damage compression 1
   Real Ac;
   /// parameter damage compression 2
   Real Bc;
   /// parameter for shear
   Real beta;
 
   /// specify the variable to average false = ehat, true = damage (only valid
   /// for non local version)
   bool damage_in_compute_stress;
 };
 
 /* -------------------------------------------------------------------------- */
 /* inline functions                                                           */
 /* -------------------------------------------------------------------------- */
 
 #include "material_mazars_inline_impl.cc"
 
 } // namespace akantu
 
 #endif /* __AKANTU_MATERIAL_MAZARS_HH__ */
diff --git a/src/model/solid_mechanics/materials/material_damage/material_mazars_inline_impl.cc b/src/model/solid_mechanics/materials/material_damage/material_mazars_inline_impl.cc
index 74150eb04..40eadf218 100644
--- a/src/model/solid_mechanics/materials/material_damage/material_mazars_inline_impl.cc
+++ b/src/model/solid_mechanics/materials/material_damage/material_mazars_inline_impl.cc
@@ -1,155 +1,155 @@
 /**
  * @file   material_mazars_inline_impl.cc
  *
+ * @author Marion Estelle Chambart <mchambart@stucky.ch>
  * @author Marion Estelle Chambart <marion.chambart@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Wed Apr 06 2011
- * @date last modification: Tue Aug 04 2015
+ * @date last modification: Wed Feb 03 2016
  *
  * @brief  Implementation of the inline functions of the material damage
  *
  * @section LICENSE
  *
- * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
- * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
- * Solides)
+ * 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
+ * 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
+ * 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/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 
 /* -------------------------------------------------------------------------- */
 template <UInt spatial_dimension>
 inline void MaterialMazars<spatial_dimension>::computeStressOnQuad(
     const Matrix<Real> & grad_u, Matrix<Real> & sigma, Real & dam,
     Real & Ehat) {
   Matrix<Real> epsilon(3, 3);
   epsilon.clear();
 
   for (UInt i = 0; i < spatial_dimension; ++i)
     for (UInt j = 0; j < spatial_dimension; ++j)
       epsilon(i, j) = .5 * (grad_u(i, j) + grad_u(j, i));
 
   Vector<Real> Fdiag(3);
   Math::matrixEig(3, epsilon.storage(), Fdiag.storage());
 
   Ehat = 0.;
   for (UInt i = 0; i < 3; ++i) {
     Real epsilon_p = std::max(Real(0.), Fdiag(i));
     Ehat += epsilon_p * epsilon_p;
   }
   Ehat = sqrt(Ehat);
 
   MaterialElastic<spatial_dimension>::computeStressOnQuad(grad_u, sigma);
 
   if (damage_in_compute_stress) {
     computeDamageOnQuad(Ehat, sigma, Fdiag, dam);
   }
 
   if (!this->is_non_local) {
     computeDamageAndStressOnQuad(grad_u, sigma, dam, Ehat);
   }
 }
 
 /* -------------------------------------------------------------------------- */
 template <UInt spatial_dimension>
 inline void MaterialMazars<spatial_dimension>::computeDamageAndStressOnQuad(
     const Matrix<Real> & grad_u, Matrix<Real> & sigma, Real & dam,
     Real & Ehat) {
   if (!damage_in_compute_stress) {
     Vector<Real> Fdiag(3);
     Fdiag.clear();
 
     Matrix<Real> epsilon(3, 3);
     epsilon.clear();
     for (UInt i = 0; i < spatial_dimension; ++i)
       for (UInt j = 0; j < spatial_dimension; ++j)
         epsilon(i, j) = .5 * (grad_u(i, j) + grad_u(j, i));
 
     Math::matrixEig(3, epsilon.storage(), Fdiag.storage());
 
     computeDamageOnQuad(Ehat, sigma, Fdiag, dam);
   }
 
   sigma *= 1 - dam;
 }
 
 /* -------------------------------------------------------------------------- */
 template <UInt spatial_dimension>
 inline void MaterialMazars<spatial_dimension>::computeDamageOnQuad(
     const Real & epsilon_equ,
     __attribute__((unused)) const Matrix<Real> & sigma,
     const Vector<Real> & epsilon_princ, Real & dam) {
   Real Fs = epsilon_equ - K0;
   if (Fs > 0.) {
     Real dam_t;
     Real dam_c;
     dam_t =
         1 - K0 * (1 - At) / epsilon_equ - At * (exp(-Bt * (epsilon_equ - K0)));
     dam_c =
         1 - K0 * (1 - Ac) / epsilon_equ - Ac * (exp(-Bc * (epsilon_equ - K0)));
 
     Real Cdiag;
     Cdiag = this->E * (1 - this->nu) / ((1 + this->nu) * (1 - 2 * this->nu));
 
     Vector<Real> sigma_princ(3);
     sigma_princ(0) = Cdiag * epsilon_princ(0) +
                      this->lambda * (epsilon_princ(1) + epsilon_princ(2));
     sigma_princ(1) = Cdiag * epsilon_princ(1) +
                      this->lambda * (epsilon_princ(0) + epsilon_princ(2));
     sigma_princ(2) = Cdiag * epsilon_princ(2) +
                      this->lambda * (epsilon_princ(1) + epsilon_princ(0));
 
     Vector<Real> sigma_p(3);
     for (UInt i = 0; i < 3; i++)
       sigma_p(i) = std::max(Real(0.), sigma_princ(i));
     sigma_p *= 1. - dam;
 
     Real trace_p = this->nu / this->E * (sigma_p(0) + sigma_p(1) + sigma_p(2));
 
     Real alpha_t = 0;
     for (UInt i = 0; i < 3; ++i) {
       Real epsilon_t = (1 + this->nu) / this->E * sigma_p(i) - trace_p;
       Real epsilon_p = std::max(Real(0.), epsilon_princ(i));
       alpha_t += epsilon_t * epsilon_p;
     }
 
     alpha_t /= epsilon_equ * epsilon_equ;
     alpha_t = std::min(alpha_t, Real(1.));
 
     Real alpha_c = 1. - alpha_t;
 
     alpha_t = std::pow(alpha_t, beta);
     alpha_c = std::pow(alpha_c, beta);
 
     Real damtemp;
     damtemp = alpha_t * dam_t + alpha_c * dam_c;
 
     dam = std::max(damtemp, dam);
     dam = std::min(dam, Real(1.));
   }
 }
 
 /* -------------------------------------------------------------------------- */
 // template<UInt spatial_dimension>
 // inline void
 // MaterialMazars<spatial_dimension>::computeTangentModuliOnQuad(Matrix<Real> &
 // tangent) {
 //   MaterialElastic<spatial_dimension>::computeTangentModuliOnQuad(tangent);
 
 //   tangent *= (1-dam);
 // }
diff --git a/src/model/solid_mechanics/materials/material_damage/material_mazars_non_local.cc b/src/model/solid_mechanics/materials/material_damage/material_mazars_non_local.cc
index a0df818db..950334fd3 100644
--- a/src/model/solid_mechanics/materials/material_damage/material_mazars_non_local.cc
+++ b/src/model/solid_mechanics/materials/material_damage/material_mazars_non_local.cc
@@ -1,124 +1,123 @@
 /**
  * @file   material_mazars_non_local.cc
  *
  * @author Marion Estelle Chambart <marion.chambart@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Fri Jun 18 2010
- * @date last modification: Thu Oct 15 2015
+ * @date last modification: Mon Sep 11 2017
  *
  * @brief  Specialization of the material class for the non-local mazars
  * material
  *
  * @section LICENSE
  *
- * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
- * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
- * Solides)
+ * 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
+ * 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
+ * A PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 #include "material_mazars_non_local.hh"
 #include "solid_mechanics_model.hh"
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 template <UInt spatial_dimension>
 MaterialMazarsNonLocal<spatial_dimension>::MaterialMazarsNonLocal(
     SolidMechanicsModel & model, const ID & id)
     : MaterialNonLocalParent(model, id), Ehat("epsilon_equ", *this),
       non_local_variable("mazars_non_local", *this) {
   AKANTU_DEBUG_IN();
 
   this->is_non_local = true;
   this->Ehat.initialize(1);
   this->non_local_variable.initialize(1);
 
   this->registerParam("average_on_damage", this->damage_in_compute_stress,
                       false, _pat_parsable | _pat_modifiable,
                       "Is D the non local variable");
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <UInt spatial_dimension>
 void MaterialMazarsNonLocal<spatial_dimension>::registerNonLocalVariables() {
   ID local;
   if (this->damage_in_compute_stress)
     local = this->damage.getName();
   else
     local = this->Ehat.getName();
 
   this->model.getNonLocalManager().registerNonLocalVariable(
       local, non_local_variable.getName(), 1);
   this->model.getNonLocalManager()
       .getNeighborhood(this->name)
       .registerNonLocalVariable(non_local_variable.getName());
 }
 
 /* -------------------------------------------------------------------------- */
 template <UInt spatial_dimension>
 void MaterialMazarsNonLocal<spatial_dimension>::computeStress(
     ElementType el_type, GhostType ghost_type) {
   AKANTU_DEBUG_IN();
 
   Real * damage = this->damage(el_type, ghost_type).storage();
   Real * epsilon_equ = this->Ehat(el_type, ghost_type).storage();
 
   MATERIAL_STRESS_QUADRATURE_POINT_LOOP_BEGIN(el_type, ghost_type);
 
   MaterialMazars<spatial_dimension>::computeStressOnQuad(grad_u, sigma, *damage,
                                                          *epsilon_equ);
   ++damage;
   ++epsilon_equ;
 
   MATERIAL_STRESS_QUADRATURE_POINT_LOOP_END;
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <UInt spatial_dimension>
 void MaterialMazarsNonLocal<spatial_dimension>::computeNonLocalStress(
     ElementType el_type, GhostType ghost_type) {
   AKANTU_DEBUG_IN();
   auto & non_loc_var = non_local_variable(el_type, ghost_type);
   Real * damage;
   Real * epsilon_equ;
   if (this->damage_in_compute_stress) {
     damage = non_loc_var.storage();
     epsilon_equ = this->Ehat(el_type, ghost_type).storage();
   } else {
     damage = this->damage(el_type, ghost_type).storage();
     epsilon_equ = non_loc_var.storage();
   }
 
   MATERIAL_STRESS_QUADRATURE_POINT_LOOP_BEGIN(el_type, ghost_type);
   this->computeDamageAndStressOnQuad(grad_u, sigma, *damage, *epsilon_equ);
 
   ++damage;
   ++epsilon_equ;
   MATERIAL_STRESS_QUADRATURE_POINT_LOOP_END;
 
   AKANTU_DEBUG_OUT();
 }
 
 INSTANTIATE_MATERIAL(mazars_non_local, MaterialMazarsNonLocal);
 
 } // namespace akantu
diff --git a/src/model/solid_mechanics/materials/material_damage/material_mazars_non_local.hh b/src/model/solid_mechanics/materials/material_damage/material_mazars_non_local.hh
index e7f28b042..1b5f0f810 100644
--- a/src/model/solid_mechanics/materials/material_damage/material_mazars_non_local.hh
+++ b/src/model/solid_mechanics/materials/material_damage/material_mazars_non_local.hh
@@ -1,92 +1,91 @@
 /**
  * @file   material_mazars_non_local.hh
  *
  * @author Marion Estelle Chambart <marion.chambart@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Fri Jun 18 2010
- * @date last modification: Thu Oct 08 2015
+ * @date last modification: Mon Sep 11 2017
  *
  * @brief  Mazars non-local description
  *
  * @section LICENSE
  *
- * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
- * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
- * Solides)
+ * 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
+ * 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
+ * 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 "material_damage_non_local.hh"
 #include "material_mazars.hh"
 /* -------------------------------------------------------------------------- */
 
 #ifndef __AKANTU_MATERIAL_MAZARS_NON_LOCAL_HH__
 #define __AKANTU_MATERIAL_MAZARS_NON_LOCAL_HH__
 
 namespace akantu {
 
 /**
  * Material Mazars Non local
  *
  * parameters in the material files :
  */
 template <UInt spatial_dimension>
 class MaterialMazarsNonLocal
     : public MaterialDamageNonLocal<spatial_dimension,
                                     MaterialMazars<spatial_dimension>> {
   /* ------------------------------------------------------------------------ */
   /* Constructors/Destructors                                                 */
   /* ------------------------------------------------------------------------ */
 public:
   using MaterialNonLocalParent =
       MaterialDamageNonLocal<spatial_dimension,
                              MaterialMazars<spatial_dimension>>;
 
   MaterialMazarsNonLocal(SolidMechanicsModel & model, const ID & id = "");
 
   /* ------------------------------------------------------------------------ */
   /* Methods                                                                  */
   /* ------------------------------------------------------------------------ */
 protected:
   /// constitutive law for all element of a type
   void computeStress(ElementType el_type,
                      GhostType ghost_type = _not_ghost) override;
 
   void computeNonLocalStress(ElementType el_type,
                              GhostType ghost_type = _not_ghost) override;
 
   void registerNonLocalVariables() override;
 
   /* ------------------------------------------------------------------------ */
   /* Accessors                                                                */
   /* ------------------------------------------------------------------------ */
 public:
   /* ------------------------------------------------------------------------ */
   /* Class Members                                                            */
   /* ------------------------------------------------------------------------ */
 private:
   /// the ehat per quadrature points to perform the averaging
   InternalField<Real> Ehat;
 
   InternalField<Real> non_local_variable;
 };
 
 } // namespace akantu
 
 #endif /* __AKANTU_MATERIAL_MAZARS_NON_LOCAL_HH__ */
diff --git a/src/model/solid_mechanics/materials/material_elastic.cc b/src/model/solid_mechanics/materials/material_elastic.cc
index 894d86e3c..f605cba65 100644
--- a/src/model/solid_mechanics/materials/material_elastic.cc
+++ b/src/model/solid_mechanics/materials/material_elastic.cc
@@ -1,264 +1,263 @@
 /**
  * @file   material_elastic.cc
  *
  * @author Lucas Frerot <lucas.frerot@epfl.ch>
  * @author Daniel Pino Muñoz <daniel.pinomunoz@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  * @author Marco Vocialta <marco.vocialta@epfl.ch>
  *
  * @date creation: Fri Jun 18 2010
- * @date last modification: Thu Oct 15 2015
+ * @date last modification: Mon Jan 29 2018
  *
  * @brief  Specialization of the material class for the elastic material
  *
  * @section LICENSE
  *
- * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
- * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
- * Solides)
+ * 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
+ * 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
+ * A PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 #include "material_elastic.hh"
 #include "solid_mechanics_model.hh"
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 template <UInt dim>
 MaterialElastic<dim>::MaterialElastic(SolidMechanicsModel & model,
                                       const ID & id)
     : Parent(model, id), was_stiffness_assembled(false) {
   AKANTU_DEBUG_IN();
   this->initialize();
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <UInt dim>
 MaterialElastic<dim>::MaterialElastic(SolidMechanicsModel & model,
                                       __attribute__((unused)) UInt a_dim,
                                       const Mesh & mesh, FEEngine & fe_engine,
                                       const ID & id)
     : Parent(model, dim, mesh, fe_engine, id), was_stiffness_assembled(false) {
   AKANTU_DEBUG_IN();
   this->initialize();
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <UInt dim> void MaterialElastic<dim>::initialize() {
   this->registerParam("lambda", lambda, _pat_readable,
                       "First Lamé coefficient");
   this->registerParam("mu", mu, _pat_readable, "Second Lamé coefficient");
   this->registerParam("kapa", kpa, _pat_readable, "Bulk coefficient");
 }
 
 /* -------------------------------------------------------------------------- */
 template <UInt dim> void MaterialElastic<dim>::initMaterial() {
   AKANTU_DEBUG_IN();
   Parent::initMaterial();
 
   if (dim == 1)
     this->nu = 0.;
 
   this->updateInternalParameters();
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <UInt dim> void MaterialElastic<dim>::updateInternalParameters() {
   MaterialThermal<dim>::updateInternalParameters();
 
   this->lambda = this->nu * this->E / ((1 + this->nu) * (1 - 2 * this->nu));
   this->mu = this->E / (2 * (1 + this->nu));
 
   this->kpa = this->lambda + 2. / 3. * this->mu;
 
   this->was_stiffness_assembled = false;
 }
 
 /* -------------------------------------------------------------------------- */
 template <> void MaterialElastic<2>::updateInternalParameters() {
   MaterialThermal<2>::updateInternalParameters();
 
   this->lambda = this->nu * this->E / ((1 + this->nu) * (1 - 2 * this->nu));
   this->mu = this->E / (2 * (1 + this->nu));
 
   if (this->plane_stress)
     this->lambda = this->nu * this->E / ((1 + this->nu) * (1 - this->nu));
 
   this->kpa = this->lambda + 2. / 3. * this->mu;
 
   this->was_stiffness_assembled = false;
 }
 
 /* -------------------------------------------------------------------------- */
 template <UInt spatial_dimension>
 void MaterialElastic<spatial_dimension>::computeStress(ElementType el_type,
                                                        GhostType ghost_type) {
   AKANTU_DEBUG_IN();
 
   Parent::computeStress(el_type, ghost_type);
 
   Array<Real>::const_scalar_iterator sigma_th_it =
       this->sigma_th(el_type, ghost_type).begin();
 
   if (!this->finite_deformation) {
     MATERIAL_STRESS_QUADRATURE_POINT_LOOP_BEGIN(el_type, ghost_type);
     const Real & sigma_th = *sigma_th_it;
     this->computeStressOnQuad(grad_u, sigma, sigma_th);
     ++sigma_th_it;
     MATERIAL_STRESS_QUADRATURE_POINT_LOOP_END;
   } else {
     /// finite gradus
     Matrix<Real> E(spatial_dimension, spatial_dimension);
 
     MATERIAL_STRESS_QUADRATURE_POINT_LOOP_BEGIN(el_type, ghost_type);
 
     /// compute E
     this->template gradUToGreenStrain<spatial_dimension>(grad_u, E);
 
     const Real & sigma_th = *sigma_th_it;
 
     /// compute second Piola-Kirchhoff stress tensor
     this->computeStressOnQuad(E, sigma, sigma_th);
 
     ++sigma_th_it;
     MATERIAL_STRESS_QUADRATURE_POINT_LOOP_END;
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <UInt spatial_dimension>
 void MaterialElastic<spatial_dimension>::computeTangentModuli(
     const ElementType & el_type, Array<Real> & tangent_matrix,
     GhostType ghost_type) {
   AKANTU_DEBUG_IN();
 
   MATERIAL_TANGENT_QUADRATURE_POINT_LOOP_BEGIN(tangent_matrix);
   this->computeTangentModuliOnQuad(tangent);
   MATERIAL_TANGENT_QUADRATURE_POINT_LOOP_END;
 
   this->was_stiffness_assembled = true;
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <UInt spatial_dimension>
 Real MaterialElastic<spatial_dimension>::getPushWaveSpeed(
     const Element &) const {
   return sqrt((lambda + 2 * mu) / this->rho);
 }
 
 /* -------------------------------------------------------------------------- */
 template <UInt spatial_dimension>
 Real MaterialElastic<spatial_dimension>::getShearWaveSpeed(
     const Element &) const {
   return sqrt(mu / this->rho);
 }
 
 /* -------------------------------------------------------------------------- */
 template <UInt spatial_dimension>
 void MaterialElastic<spatial_dimension>::computePotentialEnergy(
     ElementType el_type, GhostType ghost_type) {
   AKANTU_DEBUG_IN();
 
   MaterialThermal<spatial_dimension>::computePotentialEnergy(el_type,
                                                              ghost_type);
 
   if (ghost_type != _not_ghost)
     return;
 
   auto epot = this->potential_energy(el_type, ghost_type).begin();
 
   if (!this->finite_deformation) {
     MATERIAL_STRESS_QUADRATURE_POINT_LOOP_BEGIN(el_type, ghost_type);
 
     this->computePotentialEnergyOnQuad(grad_u, sigma, *epot);
     ++epot;
 
     MATERIAL_STRESS_QUADRATURE_POINT_LOOP_END;
   } else {
     Matrix<Real> E(spatial_dimension, spatial_dimension);
 
     MATERIAL_STRESS_QUADRATURE_POINT_LOOP_BEGIN(el_type, ghost_type);
     this->template gradUToGreenStrain<spatial_dimension>(grad_u, E);
 
     this->computePotentialEnergyOnQuad(E, sigma, *epot);
     ++epot;
 
     MATERIAL_STRESS_QUADRATURE_POINT_LOOP_END;
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <UInt spatial_dimension>
 void MaterialElastic<spatial_dimension>::computePotentialEnergyByElement(
     ElementType type, UInt index, Vector<Real> & epot_on_quad_points) {
   auto gradu_it = this->gradu(type).begin(spatial_dimension, spatial_dimension);
   auto gradu_end =
       this->gradu(type).begin(spatial_dimension, spatial_dimension);
   auto stress_it =
       this->stress(type).begin(spatial_dimension, spatial_dimension);
 
   if (this->finite_deformation)
     stress_it = this->piola_kirchhoff_2(type).begin(spatial_dimension,
                                                     spatial_dimension);
 
   UInt nb_quadrature_points = this->fem.getNbIntegrationPoints(type);
 
   gradu_it += index * nb_quadrature_points;
   gradu_end += (index + 1) * nb_quadrature_points;
   stress_it += index * nb_quadrature_points;
 
   Real * epot_quad = epot_on_quad_points.storage();
 
   Matrix<Real> grad_u(spatial_dimension, spatial_dimension);
 
   for (; gradu_it != gradu_end; ++gradu_it, ++stress_it, ++epot_quad) {
 
     if (this->finite_deformation)
       this->template gradUToGreenStrain<spatial_dimension>(*gradu_it, grad_u);
     else
       grad_u.copy(*gradu_it);
 
     this->computePotentialEnergyOnQuad(grad_u, *stress_it, *epot_quad);
   }
 }
 
 /* -------------------------------------------------------------------------- */
 template <>
 Real MaterialElastic<1>::getPushWaveSpeed(const Element & /*element*/) const {
   return std::sqrt(this->E / this->rho);
 }
 
 template <>
 Real MaterialElastic<1>::getShearWaveSpeed(const Element & /*element*/) const {
   AKANTU_EXCEPTION("There is no shear wave speed in 1D");
 }
 /* -------------------------------------------------------------------------- */
 
 INSTANTIATE_MATERIAL(elastic, MaterialElastic);
 
 } // akantu
diff --git a/src/model/solid_mechanics/materials/material_elastic.hh b/src/model/solid_mechanics/materials/material_elastic.hh
index 805a05107..e442831a7 100644
--- a/src/model/solid_mechanics/materials/material_elastic.hh
+++ b/src/model/solid_mechanics/materials/material_elastic.hh
@@ -1,157 +1,156 @@
 /**
  * @file   material_elastic.hh
  *
  * @author Lucas Frerot <lucas.frerot@epfl.ch>
  * @author Daniel Pino Muñoz <daniel.pinomunoz@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Fri Jun 18 2010
- * @date last modification: Sun Nov 15 2015
+ * @date last modification: Fri Nov 17 2017
  *
  * @brief  Material isotropic elastic
  *
  * @section LICENSE
  *
- * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
- * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
- * Solides)
+ * 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
+ * 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
+ * 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 "material_thermal.hh"
 #include "plane_stress_toolbox.hh"
 /* -------------------------------------------------------------------------- */
 
 #ifndef __AKANTU_MATERIAL_ELASTIC_HH__
 #define __AKANTU_MATERIAL_ELASTIC_HH__
 
 namespace akantu {
 
 /**
  * Material elastic isotropic
  *
  * parameters in the material files :
  *   - E   : Young's modulus (default: 0)
  *   - nu  : Poisson's ratio (default: 1/2)
  *   - Plane_Stress : if 0: plane strain, else: plane stress (default: 0)
  */
 template <UInt spatial_dimension>
 class MaterialElastic
     : public PlaneStressToolbox<spatial_dimension,
                                 MaterialThermal<spatial_dimension>> {
   /* ------------------------------------------------------------------------ */
   /* Constructors/Destructors                                                 */
   /* ------------------------------------------------------------------------ */
 private:
   using Parent =
       PlaneStressToolbox<spatial_dimension, MaterialThermal<spatial_dimension>>;
 
 public:
   MaterialElastic(SolidMechanicsModel & model, const ID & id = "");
   MaterialElastic(SolidMechanicsModel & model, UInt dim, const Mesh & mesh,
                   FEEngine & fe_engine, const ID & id = "");
 
   ~MaterialElastic() override = default;
 
 protected:
   void initialize();
 
   /* ------------------------------------------------------------------------ */
   /* Methods                                                                  */
   /* ------------------------------------------------------------------------ */
 public:
   void initMaterial() override;
 
   /// constitutive law for all element of a type
   void computeStress(ElementType el_type,
                      GhostType ghost_type = _not_ghost) override;
 
   /// compute the tangent stiffness matrix for an element type
   void computeTangentModuli(const ElementType & el_type,
                             Array<Real> & tangent_matrix,
                             GhostType ghost_type = _not_ghost) override;
 
   /// compute the elastic potential energy
   void computePotentialEnergy(ElementType el_type,
                               GhostType ghost_type = _not_ghost) override;
 
   void
   computePotentialEnergyByElement(ElementType type, UInt index,
                                   Vector<Real> & epot_on_quad_points) override;
 
   /// compute the p-wave speed in the material
   Real getPushWaveSpeed(const Element & element) const override;
 
   /// compute the s-wave speed in the material
   Real getShearWaveSpeed(const Element & element) const override;
 
 protected:
   /// constitutive law for a given quadrature point
   inline void computeStressOnQuad(const Matrix<Real> & grad_u,
                                   Matrix<Real> & sigma,
                                   const Real sigma_th = 0) const;
 
   /// compute the tangent stiffness matrix for an element
   inline void computeTangentModuliOnQuad(Matrix<Real> & tangent) const;
 
   /// recompute the lame coefficient if E or nu changes
   void updateInternalParameters() override;
 
   static inline void computePotentialEnergyOnQuad(const Matrix<Real> & grad_u,
                                                   const Matrix<Real> & sigma,
                                                   Real & epot);
 
   bool hasStiffnessMatrixChanged() override {
     return (!was_stiffness_assembled);
   }
 
   /* ------------------------------------------------------------------------ */
   /* Accessors                                                                */
   /* ------------------------------------------------------------------------ */
 public:
   /// get first Lame constant
   AKANTU_GET_MACRO(Lambda, lambda, Real);
 
   /// get second Lame constant
   AKANTU_GET_MACRO(Mu, mu, Real);
 
   /// get bulk modulus
   AKANTU_GET_MACRO(Kappa, kpa, Real);
 
   /* ------------------------------------------------------------------------ */
   /* Class Members                                                            */
   /* ------------------------------------------------------------------------ */
 protected:
   /// First Lamé coefficient
   Real lambda;
 
   /// Second Lamé coefficient (shear modulus)
   Real mu;
 
   /// Bulk modulus
   Real kpa;
 
   /// defines if the stiffness was computed
   bool was_stiffness_assembled;
 };
 
 } // akantu
 
 #include "material_elastic_inline_impl.cc"
 
 #endif /* __AKANTU_MATERIAL_ELASTIC_HH__ */
diff --git a/src/model/solid_mechanics/materials/material_elastic_inline_impl.cc b/src/model/solid_mechanics/materials/material_elastic_inline_impl.cc
index 6c7160500..606e7bb73 100644
--- a/src/model/solid_mechanics/materials/material_elastic_inline_impl.cc
+++ b/src/model/solid_mechanics/materials/material_elastic_inline_impl.cc
@@ -1,121 +1,120 @@
 /**
  * @file   material_elastic_inline_impl.cc
  *
  * @author Lucas Frerot <lucas.frerot@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Wed Aug 04 2010
- * @date last modification: Tue Aug 18 2015
+ * @date last modification: Fri Dec 16 2016
  *
  * @brief  Implementation of the inline functions of the material elastic
  *
  * @section LICENSE
  *
- * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
- * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
- * Solides)
+ * 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
+ * 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
+ * A PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 #include "material_elastic.hh"
 /* -------------------------------------------------------------------------- */
 
 #ifndef __AKANTU_MATERIAL_ELASTIC_INLINE_IMPL_CC__
 #define __AKANTU_MATERIAL_ELASTIC_INLINE_IMPL_CC__
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 template <UInt spatial_dimension>
 inline void MaterialElastic<spatial_dimension>::computeStressOnQuad(
     const Matrix<Real> & grad_u, Matrix<Real> & sigma,
     const Real sigma_th) const {
   Real trace = grad_u.trace(); // trace = (\nabla u)_{kk}
 
   // \sigma_{ij} = \lambda * (\nabla u)_{kk} * \delta_{ij} + \mu * (\nabla
   // u_{ij} + \nabla u_{ji})
   for (UInt i = 0; i < spatial_dimension; ++i) {
     for (UInt j = 0; j < spatial_dimension; ++j) {
       sigma(i, j) = (i == j) * lambda * trace +
                     mu * (grad_u(i, j) + grad_u(j, i)) + (i == j) * sigma_th;
     }
   }
 }
 
 /* -------------------------------------------------------------------------- */
 template <>
 inline void MaterialElastic<1>::computeStressOnQuad(const Matrix<Real> & grad_u,
                                                     Matrix<Real> & sigma,
                                                     Real sigma_th) const {
   sigma(0, 0) = this->E * grad_u(0, 0) + sigma_th;
 }
 
 /* -------------------------------------------------------------------------- */
 template <UInt spatial_dimension>
 inline void MaterialElastic<spatial_dimension>::computeTangentModuliOnQuad(
     Matrix<Real> & tangent) const {
   UInt n = tangent.cols();
 
   // Real Ep = E/((1+nu)*(1-2*nu));
   Real Miiii = lambda + 2 * mu;
   Real Miijj = lambda;
   Real Mijij = mu;
 
   if (spatial_dimension == 1)
     tangent(0, 0) = this->E;
   else
     tangent(0, 0) = Miiii;
 
   // test of dimension should by optimized out by the compiler due to the
   // template
   if (spatial_dimension >= 2) {
     tangent(1, 1) = Miiii;
     tangent(0, 1) = Miijj;
     tangent(1, 0) = Miijj;
 
     tangent(n - 1, n - 1) = Mijij;
   }
 
   if (spatial_dimension == 3) {
     tangent(2, 2) = Miiii;
     tangent(0, 2) = Miijj;
     tangent(1, 2) = Miijj;
     tangent(2, 0) = Miijj;
     tangent(2, 1) = Miijj;
 
     tangent(3, 3) = Mijij;
     tangent(4, 4) = Mijij;
   }
 }
 
 /* -------------------------------------------------------------------------- */
 template <UInt dim>
 inline void MaterialElastic<dim>::computePotentialEnergyOnQuad(
     const Matrix<Real> & grad_u, const Matrix<Real> & sigma, Real & epot) {
   epot = .5 * sigma.doubleDot(grad_u);
 }
 
 /* -------------------------------------------------------------------------- */
 template <>
 inline void
 MaterialElastic<1>::computeTangentModuliOnQuad(Matrix<Real> & tangent) const {
   tangent(0, 0) = E;
 }
 
 } // akantu
 
 #endif /* __AKANTU_MATERIAL_ELASTIC_INLINE_IMPL_CC__ */
diff --git a/src/model/solid_mechanics/materials/material_elastic_linear_anisotropic.cc b/src/model/solid_mechanics/materials/material_elastic_linear_anisotropic.cc
index 84c1608fa..0b8a34b78 100644
--- a/src/model/solid_mechanics/materials/material_elastic_linear_anisotropic.cc
+++ b/src/model/solid_mechanics/materials/material_elastic_linear_anisotropic.cc
@@ -1,263 +1,265 @@
 /**
  * @file   material_elastic_linear_anisotropic.cc
  *
+ * @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
  * @author Till Junge <till.junge@epfl.ch>
+ * @author Enrico Milanese <enrico.milanese@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Wed Sep 25 2013
- * @date last modification: Thu Oct 15 2015
+ * @date last modification: Tue Feb 20 2018
  *
  * @brief  Anisotropic elastic material
  *
  * @section LICENSE
  *
- * Copyright  (©)  2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de Lausanne)
+ * 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
+ * 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
+ * A PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 
 /* -------------------------------------------------------------------------- */
 #include "material_elastic_linear_anisotropic.hh"
 #include "solid_mechanics_model.hh"
 #include <algorithm>
 #include <sstream>
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 template <UInt dim>
 MaterialElasticLinearAnisotropic<dim>::MaterialElasticLinearAnisotropic(
     SolidMechanicsModel & model, const ID & id, bool symmetric)
     : Material(model, id), rot_mat(dim, dim), Cprime(dim * dim, dim * dim),
       C(voigt_h::size, voigt_h::size), eigC(voigt_h::size),
       symmetric(symmetric), alpha(0), was_stiffness_assembled(false) {
   AKANTU_DEBUG_IN();
 
   this->dir_vecs.push_back(std::make_unique<Vector<Real>>(dim));
   (*this->dir_vecs.back())[0] = 1.;
   this->registerParam("n1", *(this->dir_vecs.back()), _pat_parsmod,
                       "Direction of main material axis");
 
   if (dim > 1) {
     this->dir_vecs.push_back(std::make_unique<Vector<Real>>(dim));
     (*this->dir_vecs.back())[1] = 1.;
     this->registerParam("n2", *(this->dir_vecs.back()), _pat_parsmod,
                         "Direction of secondary material axis");
   }
 
   if (dim > 2) {
     this->dir_vecs.push_back(std::make_unique<Vector<Real>>(dim));
     (*this->dir_vecs.back())[2] = 1.;
     this->registerParam("n3", *(this->dir_vecs.back()), _pat_parsmod,
                         "Direction of tertiary material axis");
   }
 
   for (UInt i = 0; i < voigt_h::size; ++i) {
     UInt start = 0;
     if (this->symmetric) {
       start = i;
     }
     for (UInt j = start; j < voigt_h::size; ++j) {
       std::stringstream param("C");
       param << "C" << i + 1 << j + 1;
       this->registerParam(param.str(), this->Cprime(i, j), Real(0.),
                           _pat_parsmod, "Coefficient " + param.str());
     }
   }
 
   this->registerParam("alpha", this->alpha, _pat_parsmod,
                       "Proportion of viscous stress");
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <UInt dim> void MaterialElasticLinearAnisotropic<dim>::initMaterial() {
   AKANTU_DEBUG_IN();
   Material::initMaterial();
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <UInt dim>
 void MaterialElasticLinearAnisotropic<dim>::updateInternalParameters() {
   Material::updateInternalParameters();
   if (this->symmetric) {
     for (UInt i = 0; i < voigt_h::size; ++i) {
       for (UInt j = i + 1; j < voigt_h::size; ++j) {
         this->Cprime(j, i) = this->Cprime(i, j);
       }
     }
   }
   this->rotateCprime();
   this->C.eig(this->eigC);
 
   this->was_stiffness_assembled = false;
 }
 
 /* -------------------------------------------------------------------------- */
 template <UInt Dim> void MaterialElasticLinearAnisotropic<Dim>::rotateCprime() {
   // start by filling the empty parts fo Cprime
   UInt diff = Dim * Dim - voigt_h::size;
   for (UInt i = voigt_h::size; i < Dim * Dim; ++i) {
     for (UInt j = 0; j < Dim * Dim; ++j) {
       this->Cprime(i, j) = this->Cprime(i - diff, j);
     }
   }
   for (UInt i = 0; i < Dim * Dim; ++i) {
     for (UInt j = voigt_h::size; j < Dim * Dim; ++j) {
       this->Cprime(i, j) = this->Cprime(i, j - diff);
     }
   }
   // construction of rotator tensor
   // normalise rotation matrix
   for (UInt j = 0; j < Dim; ++j) {
     Vector<Real> rot_vec = this->rot_mat(j);
     rot_vec = *this->dir_vecs[j];
     rot_vec.normalize();
   }
 
   // make sure the vectors form a right-handed base
   Vector<Real> test_axis(3);
   Vector<Real> v1(3), v2(3), v3(3);
 
   if (Dim == 2) {
     for (UInt i = 0; i < Dim; ++i) {
       v1[i] = this->rot_mat(0, i);
       v2[i] = this->rot_mat(1, i);
       v3[i] = 0.;
     }
     v3[2] = 1.;
     v1[2] = 0.;
     v2[2] = 0.;
   } else if (Dim == 3) {
     v1 = this->rot_mat(0);
     v2 = this->rot_mat(1);
     v3 = this->rot_mat(2);
   }
 
   test_axis.crossProduct(v1, v2);
   test_axis -= v3;
   if (test_axis.norm() > 8 * std::numeric_limits<Real>::epsilon()) {
     AKANTU_ERROR("The axis vectors do not form a right-handed coordinate "
                  << "system. I. e., ||n1 x n2 - n3|| should be zero, but "
                  << "it is " << test_axis.norm() << ".");
   }
 
   // create the rotator and the reverse rotator
   Matrix<Real> rotator(Dim * Dim, Dim * Dim);
   Matrix<Real> revrotor(Dim * Dim, Dim * Dim);
   for (UInt i = 0; i < Dim; ++i) {
     for (UInt j = 0; j < Dim; ++j) {
       for (UInt k = 0; k < Dim; ++k) {
         for (UInt l = 0; l < Dim; ++l) {
           UInt I = voigt_h::mat[i][j];
           UInt J = voigt_h::mat[k][l];
           rotator(I, J) = this->rot_mat(k, i) * this->rot_mat(l, j);
           revrotor(I, J) = this->rot_mat(i, k) * this->rot_mat(j, l);
         }
       }
     }
   }
 
   // create the full rotated matrix
   Matrix<Real> Cfull(Dim * Dim, Dim * Dim);
   Cfull = rotator * Cprime * revrotor;
 
   for (UInt i = 0; i < voigt_h::size; ++i) {
     for (UInt j = 0; j < voigt_h::size; ++j) {
       this->C(i, j) = Cfull(i, j);
     }
   }
 }
 
 /* -------------------------------------------------------------------------- */
 template <UInt dim>
 void MaterialElasticLinearAnisotropic<dim>::computeStress(
     ElementType el_type, GhostType ghost_type) {
   // Wikipedia convention:
   // 2*eps_ij (i!=j) = voigt_eps_I
   // http://en.wikipedia.org/wiki/Voigt_notation
   AKANTU_DEBUG_IN();
 
   Matrix<Real> strain(dim, dim);
 
   MATERIAL_STRESS_QUADRATURE_POINT_LOOP_BEGIN(el_type, ghost_type);
 
   this->computeStressOnQuad(strain, sigma);
 
   MATERIAL_STRESS_QUADRATURE_POINT_LOOP_END;
 }
 
 /* -------------------------------------------------------------------------- */
 template <UInt dim>
 void MaterialElasticLinearAnisotropic<dim>::computeTangentModuli(
     const ElementType & el_type, Array<Real> & tangent_matrix,
     GhostType ghost_type) {
   AKANTU_DEBUG_IN();
 
   MATERIAL_TANGENT_QUADRATURE_POINT_LOOP_BEGIN(tangent_matrix);
 
   this->computeTangentModuliOnQuad(tangent);
 
   MATERIAL_TANGENT_QUADRATURE_POINT_LOOP_END;
 
   this->was_stiffness_assembled = true;
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <UInt dim>
 void MaterialElasticLinearAnisotropic<dim>::computePotentialEnergy(
     ElementType el_type, GhostType ghost_type) {
   AKANTU_DEBUG_IN();
 
   Material::computePotentialEnergy(el_type, ghost_type);
 
   AKANTU_DEBUG_ASSERT(!this->finite_deformation,
                       "finite deformation not possible in material anisotropic "
                       "(TO BE IMPLEMENTED)");
 
   if (ghost_type != _not_ghost)
     return;
   Array<Real>::scalar_iterator epot =
       this->potential_energy(el_type, ghost_type).begin();
 
   MATERIAL_STRESS_QUADRATURE_POINT_LOOP_BEGIN(el_type, ghost_type);
 
   computePotentialEnergyOnQuad(grad_u, sigma, *epot);
   ++epot;
 
   MATERIAL_STRESS_QUADRATURE_POINT_LOOP_END;
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <UInt dim>
 Real MaterialElasticLinearAnisotropic<dim>::getCelerity(
     __attribute__((unused)) const Element & element) const {
   return std::sqrt(this->eigC(0) / rho);
 }
 
 /* -------------------------------------------------------------------------- */
 
 INSTANTIATE_MATERIAL(elastic_anisotropic, MaterialElasticLinearAnisotropic);
 
 } // akantu
diff --git a/src/model/solid_mechanics/materials/material_elastic_linear_anisotropic.hh b/src/model/solid_mechanics/materials/material_elastic_linear_anisotropic.hh
index 2cfa119bb..363378550 100644
--- a/src/model/solid_mechanics/materials/material_elastic_linear_anisotropic.hh
+++ b/src/model/solid_mechanics/materials/material_elastic_linear_anisotropic.hh
@@ -1,139 +1,140 @@
 /**
  * @file   material_elastic_linear_anisotropic.hh
  *
  * @author Till Junge <till.junge@epfl.ch>
+ * @author Enrico Milanese <enrico.milanese@epfl.ch>
  *
  * @date creation: Fri Jun 18 2010
- * @date last modification: Tue Aug 18 2015
+ * @date last modification: Fri Feb 16 2018
  *
  * @brief  Orthotropic elastic material
  *
  * @section LICENSE
  *
- * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
- * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
- * Solides)
+ * 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
+ * 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
+ * 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 "material.hh"
 #include "material_elastic.hh"
 /* -------------------------------------------------------------------------- */
 #include <vector>
 /* -------------------------------------------------------------------------- */
 
 #ifndef __AKANTU_MATERIAL_ELASTIC_LINEAR_ANISOTROPIC_HH__
 #define __AKANTU_MATERIAL_ELASTIC_LINEAR_ANISOTROPIC_HH__
 
 namespace akantu {
 
 /**
  * General linear anisotropic elastic material
  * The only constraint on the elastic tensor is that it can be represented
  * as a symmetric 6x6 matrix (3D) or 3x3 (2D).
  *
  * parameters in the material files :
  *   - rho  : density (default: 0)
  *   - C_ij  : entry on the stiffness
  */
 template <UInt Dim> class MaterialElasticLinearAnisotropic : public Material {
   /* ------------------------------------------------------------------------ */
   /* Constructors/Destructors                                                 */
   /* ------------------------------------------------------------------------ */
 public:
   MaterialElasticLinearAnisotropic(SolidMechanicsModel & model,
                                    const ID & id = "", bool symmetric = true);
 
   /* ------------------------------------------------------------------------ */
   /* Methods                                                                  */
   /* ------------------------------------------------------------------------ */
 public:
   void initMaterial() override;
 
   /// constitutive law for all element of a type
   void computeStress(ElementType el_type,
                      GhostType ghost_type = _not_ghost) override;
 
   /// compute the tangent stiffness matrix for an element type
   void computeTangentModuli(const ElementType & el_type,
                             Array<Real> & tangent_matrix,
                             GhostType ghost_type = _not_ghost) override;
 
   /// compute the elastic potential energy
   void computePotentialEnergy(ElementType el_type,
                               GhostType ghost_type = _not_ghost) override;
 
   void updateInternalParameters() override;
 
   bool hasStiffnessMatrixChanged() override {
     return (!was_stiffness_assembled);
   }
 
 protected:
   // compute C from Cprime
   void rotateCprime();
 
   /// constitutive law for a given quadrature point
   inline void computeStressOnQuad(const Matrix<Real> & grad_u,
                                   Matrix<Real> & sigma) const;
 
   /// tangent matrix for a given quadrature point
   inline void computeTangentModuliOnQuad(Matrix<Real> & tangent) const;
 
   inline void computePotentialEnergyOnQuad(const Matrix<Real> & grad_u,
                                            const Matrix<Real> & sigma,
                                            Real & epot);
 
   /* ------------------------------------------------------------------------ */
   /* Accessors                                                                */
   /* ------------------------------------------------------------------------ */
 public:
   /// compute max wave celerity
   Real getCelerity(const Element & element) const override;
 
   AKANTU_GET_MACRO(VoigtStiffness, C, Matrix<Real>);
 
   /* ------------------------------------------------------------------------ */
   /* Class Members                                                            */
   /* ------------------------------------------------------------------------ */
 protected:
   using voigt_h = VoigtHelper<Dim>;
 
   /// direction matrix and vectors
   std::vector<std::unique_ptr<Vector<Real>>> dir_vecs;
 
   Matrix<Real> rot_mat;
   /// Elastic stiffness tensor in material frame and full vectorised notation
   Matrix<Real> Cprime;
   /// Elastic stiffness tensor in voigt notation
   Matrix<Real> C;
   /// eigenvalues of stiffness tensor
   Vector<Real> eigC;
 
   bool symmetric;
 
   /// viscous proportion
   Real alpha;
 
   /// defines if the stiffness was computed
   bool was_stiffness_assembled;
 };
 } // akantu
 
 #include "material_elastic_linear_anisotropic_inline_impl.cc"
 
 #endif /* __AKANTU_MATERIAL_ELASTIC_LINEAR_ANISOTROPIC_HH__ */
diff --git a/src/model/solid_mechanics/materials/material_elastic_linear_anisotropic_inline_impl.cc b/src/model/solid_mechanics/materials/material_elastic_linear_anisotropic_inline_impl.cc
index 1d608fe60..716978f67 100644
--- a/src/model/solid_mechanics/materials/material_elastic_linear_anisotropic_inline_impl.cc
+++ b/src/model/solid_mechanics/materials/material_elastic_linear_anisotropic_inline_impl.cc
@@ -1,93 +1,92 @@
 /**
  * @file   material_elastic_linear_anisotropic_inline_impl.cc
  *
  * @author Enrico Milanese <enrico.milanese@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
- * @date creation: Mon Feb 12 2018
- * @date last modification: Mon Feb 12 2018
+ * @date creation: Fri Feb 16 2018
+ * @date last modification: Fri Feb 16 2018
  *
- * @brief Implementation of the inline functions of the material elastic linear
+ * @brief  Implementation of the inline functions of the material elastic linear
  * anisotropic
  *
  * @section LICENSE
  *
- * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
- * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
- * Solides)
+ * 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
+ * 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
+ * A PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 #include "material_elastic_linear_anisotropic.hh"
 /* -------------------------------------------------------------------------- */
 
 #ifndef __AKANTU_MATERIAL_ELASTIC_LINEAR_ANISOTROPIC_INLINE_IMPL_CC__
 #define __AKANTU_MATERIAL_ELASTIC_LINEAR_ANISOTROPIC_INLINE_IMPL_CC__
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 template <UInt dim>
 inline void MaterialElasticLinearAnisotropic<dim>::computeStressOnQuad(
     const Matrix<Real> & grad_u, Matrix<Real> & sigma) const {
   // Wikipedia convention:
   // 2*eps_ij (i!=j) = voigt_eps_I
   // http://en.wikipedia.org/wiki/Voigt_notation
   Vector<Real> voigt_strain(voigt_h::size);
   Vector<Real> voigt_stress(voigt_h::size);
 
   for (UInt I = 0; I < voigt_h::size; ++I) {
     Real voigt_factor = voigt_h::factors[I];
     UInt i = voigt_h::vec[I][0];
     UInt j = voigt_h::vec[I][1];
 
     voigt_strain(I) = voigt_factor * (grad_u(i, j) + grad_u(j, i)) / 2.;
   }
 
   voigt_stress = this->C * voigt_strain;
 
   for (UInt I = 0; I < voigt_h::size; ++I) {
     UInt i = voigt_h::vec[I][0];
     UInt j = voigt_h::vec[I][1];
 
     sigma(i, j) = sigma(j, i) = voigt_stress(I);
   }
 }
 
 /* -------------------------------------------------------------------------- */
 template <UInt dim>
 inline void MaterialElasticLinearAnisotropic<dim>::computeTangentModuliOnQuad(
     Matrix<Real> & tangent) const {
 
   tangent.copy(this->C);
 }
 
 /* -------------------------------------------------------------------------- */
 template <UInt dim>
 inline void MaterialElasticLinearAnisotropic<dim>::computePotentialEnergyOnQuad(
     const Matrix<Real> & grad_u, const Matrix<Real> & sigma, Real & epot) {
 
   AKANTU_DEBUG_ASSERT(this->symmetric,
                       "The elastic constants matrix is not symmetric,"
                       "energy is not path independent.");
 
   epot = .5 * sigma.doubleDot(grad_u);
 }
 
 } // akantu
 
 #endif /* __AKANTU_MATERIAL_ELASTIC_LINEAR_ANISOTROPIC_INLINE_IMPL_CC__ */
diff --git a/src/model/solid_mechanics/materials/material_elastic_orthotropic.cc b/src/model/solid_mechanics/materials/material_elastic_orthotropic.cc
index 320f2bb44..d701bf394 100644
--- a/src/model/solid_mechanics/materials/material_elastic_orthotropic.cc
+++ b/src/model/solid_mechanics/materials/material_elastic_orthotropic.cc
@@ -1,168 +1,168 @@
 /**
  * @file   material_elastic_orthotropic.cc
  *
  * @author Till Junge <till.junge@epfl.ch>
+ * @author Enrico Milanese <enrico.milanese@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  * @author Marco Vocialta <marco.vocialta@epfl.ch>
  *
  * @date creation: Fri Jun 18 2010
- * @date last modification: Thu Oct 15 2015
+ * @date last modification: Tue Feb 20 2018
  *
  * @brief  Orthotropic elastic material
  *
  * @section LICENSE
  *
- * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
- * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
- * Solides)
+ * 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
+ * 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
+ * A PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 
 /* -------------------------------------------------------------------------- */
 #include "material_elastic_orthotropic.hh"
 #include "solid_mechanics_model.hh"
 #include <algorithm>
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 template <UInt Dim>
 MaterialElasticOrthotropic<Dim>::MaterialElasticOrthotropic(
     SolidMechanicsModel & model, const ID & id)
     : MaterialElasticLinearAnisotropic<Dim>(model, id) {
   AKANTU_DEBUG_IN();
   this->registerParam("E1", E1, Real(0.), _pat_parsmod, "Young's modulus (n1)");
   this->registerParam("E2", E2, Real(0.), _pat_parsmod, "Young's modulus (n2)");
   this->registerParam("nu12", nu12, Real(0.), _pat_parsmod,
                       "Poisson's ratio (12)");
   this->registerParam("G12", G12, Real(0.), _pat_parsmod, "Shear modulus (12)");
 
   if (Dim > 2) {
     this->registerParam("E3", E3, Real(0.), _pat_parsmod,
                         "Young's modulus (n3)");
     this->registerParam("nu13", nu13, Real(0.), _pat_parsmod,
                         "Poisson's ratio (13)");
     this->registerParam("nu23", nu23, Real(0.), _pat_parsmod,
                         "Poisson's ratio (23)");
     this->registerParam("G13", G13, Real(0.), _pat_parsmod,
                         "Shear modulus (13)");
     this->registerParam("G23", G23, Real(0.), _pat_parsmod,
                         "Shear modulus (23)");
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <UInt Dim> void MaterialElasticOrthotropic<Dim>::initMaterial() {
   AKANTU_DEBUG_IN();
   Material::initMaterial();
 
   updateInternalParameters();
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <UInt Dim>
 void MaterialElasticOrthotropic<Dim>::updateInternalParameters() {
   /* 1) construction of temporary material frame stiffness tensor------------ */
   // http://solidmechanics.org/Text/Chapter3_2/Chapter3_2.php#Sect3_2_13
   Real nu21 = nu12 * E2 / E1;
   Real nu31 = nu13 * E3 / E1;
   Real nu32 = nu23 * E3 / E2;
 
   // Full (i.e. dim^2 by dim^2) stiffness tensor in material frame
   if (Dim == 1) {
     AKANTU_ERROR("Dimensions 1 not implemented: makes no sense to have "
                  "orthotropy for 1D");
   }
 
   Real Gamma;
 
   if (Dim == 3)
     Gamma = 1 / (1 - nu12 * nu21 - nu23 * nu32 - nu31 * nu13 -
                  2 * nu21 * nu32 * nu13);
 
   if (Dim == 2)
     Gamma = 1 / (1 - nu12 * nu21);
 
   // Lamé's first parameters
   this->Cprime(0, 0) = E1 * (1 - nu23 * nu32) * Gamma;
   this->Cprime(1, 1) = E2 * (1 - nu13 * nu31) * Gamma;
   if (Dim == 3)
     this->Cprime(2, 2) = E3 * (1 - nu12 * nu21) * Gamma;
 
   // normalised poisson's ratio's
   this->Cprime(1, 0) = this->Cprime(0, 1) = E1 * (nu21 + nu31 * nu23) * Gamma;
   if (Dim == 3) {
     this->Cprime(2, 0) = this->Cprime(0, 2) = E1 * (nu31 + nu21 * nu32) * Gamma;
     this->Cprime(2, 1) = this->Cprime(1, 2) = E2 * (nu32 + nu12 * nu31) * Gamma;
   }
 
   // Lamé's second parameters (shear moduli)
   if (Dim == 3) {
     this->Cprime(3, 3) = G23;
     this->Cprime(4, 4) = G13;
     this->Cprime(5, 5) = G12;
   } else
     this->Cprime(2, 2) = G12;
 
   /* 1) rotation of C into the global frame */
   this->rotateCprime();
   this->C.eig(this->eigC);
 }
 
 /* -------------------------------------------------------------------------- */
 template <UInt spatial_dimension>
 void MaterialElasticOrthotropic<spatial_dimension>::
     computePotentialEnergyByElement(ElementType type, UInt index,
                                     Vector<Real> & epot_on_quad_points) {
 
   AKANTU_DEBUG_ASSERT(!this->finite_deformation,
                       "finite deformation not possible in material orthotropic "
                       "(TO BE IMPLEMENTED)");
 
   Array<Real>::matrix_iterator gradu_it =
       this->gradu(type).begin(spatial_dimension, spatial_dimension);
   Array<Real>::matrix_iterator gradu_end =
       this->gradu(type).begin(spatial_dimension, spatial_dimension);
   Array<Real>::matrix_iterator stress_it =
       this->stress(type).begin(spatial_dimension, spatial_dimension);
 
   UInt nb_quadrature_points = this->fem.getNbIntegrationPoints(type);
 
   gradu_it += index * nb_quadrature_points;
   gradu_end += (index + 1) * nb_quadrature_points;
   stress_it += index * nb_quadrature_points;
 
   Real * epot_quad = epot_on_quad_points.storage();
 
   Matrix<Real> grad_u(spatial_dimension, spatial_dimension);
 
   for (; gradu_it != gradu_end; ++gradu_it, ++stress_it, ++epot_quad) {
     grad_u.copy(*gradu_it);
 
     this->computePotentialEnergyOnQuad(grad_u, *stress_it, *epot_quad);
   }
 }
 
 /* -------------------------------------------------------------------------- */
 INSTANTIATE_MATERIAL(elastic_orthotropic, MaterialElasticOrthotropic);
 
 } // akantu
diff --git a/src/model/solid_mechanics/materials/material_elastic_orthotropic.hh b/src/model/solid_mechanics/materials/material_elastic_orthotropic.hh
index 60110342c..0cea87042 100644
--- a/src/model/solid_mechanics/materials/material_elastic_orthotropic.hh
+++ b/src/model/solid_mechanics/materials/material_elastic_orthotropic.hh
@@ -1,136 +1,136 @@
 /**
  * @file   material_elastic_orthotropic.hh
  *
  * @author Till Junge <till.junge@epfl.ch>
+ * @author Enrico Milanese <enrico.milanese@epfl.ch>
  * @author Marco Vocialta <marco.vocialta@epfl.ch>
  *
  * @date creation: Fri Jun 18 2010
- * @date last modification: Sun Oct 19 2014
+ * @date last modification: Fri Feb 16 2018
  *
  * @brief  Orthotropic elastic material
  *
  * @section LICENSE
  *
- * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
- * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
- * Solides)
+ * 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
+ * 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
+ * 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 "material_elastic_linear_anisotropic.hh"
 /* -------------------------------------------------------------------------- */
 
 #ifndef __AKANTU_MATERIAL_ELASTIC_ORTHOTROPIC_HH__
 #define __AKANTU_MATERIAL_ELASTIC_ORTHOTROPIC_HH__
 
 namespace akantu {
 
 /**
  * Orthotropic elastic material
  *
  * parameters in the material files :
  *   - n1   : direction of x-axis in material base, normalisation not necessary
  * (default: {1, 0, 0})
  *   - n2   : direction of y-axis in material base, normalisation not necessary
  * (default: {0, 1, 0})
  *   - n3   : direction of z-axis in material base, normalisation not necessary
  * (default: {0, 0, 1})
  *   - rho  : density (default: 0)
  *   - E1   : Young's modulus along n1 (default: 0)
  *   - E2   : Young's modulus along n2 (default: 0)
  *   - E3   : Young's modulus along n3 (default: 0)
  *   - nu12 : Poisson's ratio along 12 (default: 0)
  *   - nu13 : Poisson's ratio along 13 (default: 0)
  *   - nu23 : Poisson's ratio along 23 (default: 0)
  *   - G12  : Shear modulus along 12 (default: 0)
  *   - G13  : Shear modulus along 13 (default: 0)
  *   - G23  : Shear modulus along 23 (default: 0)
  */
 
 template <UInt Dim>
 class MaterialElasticOrthotropic
     : public MaterialElasticLinearAnisotropic<Dim> {
   /* ------------------------------------------------------------------------ */
   /* Constructors/Destructors                                                 */
   /* ------------------------------------------------------------------------ */
 public:
   MaterialElasticOrthotropic(SolidMechanicsModel & model, const ID & id = "");
 
   /* ------------------------------------------------------------------------ */
   /* Methods                                                                  */
   /* ------------------------------------------------------------------------ */
 public:
   void initMaterial() override;
 
   void updateInternalParameters() override;
 
   void
   computePotentialEnergyByElement(ElementType type, UInt index,
                                   Vector<Real> & epot_on_quad_points) override;
 
   /* ------------------------------------------------------------------------ */
   /* Accessors                                                                */
   /* ------------------------------------------------------------------------ */
 public:
   AKANTU_GET_MACRO(E1, E1, Real);
   AKANTU_GET_MACRO(E2, E2, Real);
   AKANTU_GET_MACRO(E3, E3, Real);
   AKANTU_GET_MACRO(Nu12, nu12, Real);
   AKANTU_GET_MACRO(Nu13, nu13, Real);
   AKANTU_GET_MACRO(Nu23, nu23, Real);
   AKANTU_GET_MACRO(G12, G12, Real);
   AKANTU_GET_MACRO(G13, G13, Real);
   AKANTU_GET_MACRO(G23, G23, Real);
 
   /* ------------------------------------------------------------------------ */
   /* Class Members                                                            */
   /* ------------------------------------------------------------------------ */
 protected:
   /// the n1 young modulus
   Real E1;
 
   /// the n2 young modulus
   Real E2;
 
   /// the n3 young modulus
   Real E3;
 
   /// 12 Poisson coefficient
   Real nu12;
 
   /// 13 Poisson coefficient
   Real nu13;
 
   /// 23 Poisson coefficient
   Real nu23;
 
   /// 12 shear modulus
   Real G12;
 
   /// 13 shear modulus
   Real G13;
 
   /// 23 shear modulus
   Real G23;
 };
 
 } // akantu
 
 #endif /* __AKANTU_MATERIAL_ELASTIC_ORTHOTROPIC_HH__ */
diff --git a/src/model/solid_mechanics/materials/material_embedded/material_embedded_includes.hh b/src/model/solid_mechanics/materials/material_embedded/material_embedded_includes.hh
index 29362ed2c..fa1a1f523 100644
--- a/src/model/solid_mechanics/materials/material_embedded/material_embedded_includes.hh
+++ b/src/model/solid_mechanics/materials/material_embedded/material_embedded_includes.hh
@@ -1,41 +1,41 @@
 /**
  * @file   material_embedded_includes.hh
  *
  * @author Lucas Frerot <lucas.frerot@epfl.ch>
  *
  * @date creation: Fri Jan 04 2013
- * @date last modification: Fri May 29 2015
+ * @date last modification: Fri Feb 09 2018
  *
  * @brief  List of includes for embedded elements
  *
  * @section LICENSE
  *
- * Copyright  (©)  2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de Lausanne)
+ * 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
+ * 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
+ * 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_CMAKE_LIST_MATERIALS
 #include "material_reinforcement.hh"
 #endif
 
 #define AKANTU_MATERIAL_REINFORCEMENT_LAW_TMPL_LIST                            \
   ((elastic, (MaterialElastic<1>)))(                                           \
       (plastic, (MaterialLinearIsotropicHardening<1>)))
 
 #define AKANTU_EMBEDDED_MATERIAL_LIST                                          \
   ((2, (reinforcement, MaterialReinforcement)))
diff --git a/src/model/solid_mechanics/materials/material_embedded/material_reinforcement.hh b/src/model/solid_mechanics/materials/material_embedded/material_reinforcement.hh
index 172508a2e..36a04ab7f 100644
--- a/src/model/solid_mechanics/materials/material_embedded/material_reinforcement.hh
+++ b/src/model/solid_mechanics/materials/material_embedded/material_reinforcement.hh
@@ -1,209 +1,209 @@
 /**
  * @file   material_reinforcement.hh
  *
  * @author Lucas Frerot <lucas.frerot@epfl.ch>
  *
  * @date creation: Fri Mar 13 2015
- * @date last modification: Tue Nov 24 2015
+ * @date last modification: Fri Feb 09 2018
  *
  * @brief  Reinforcement material
  *
  * @section LICENSE
  *
- * Copyright (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne) Laboratory
- * (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * Copyright (©) 2015-2018 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
- * terms  of the  GNU Lesser  General Public  License as  published by  the Free
+ * 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
+ * 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_MATERIAL_REINFORCEMENT_HH__
 #define __AKANTU_MATERIAL_REINFORCEMENT_HH__
 
 #include "aka_common.hh"
 
 #include "embedded_interface_model.hh"
 #include "material.hh"
 
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 
 /**
  * @brief Material used to represent embedded reinforcements
  *
  * This class is used for computing the reinforcement stiffness matrix
  * along with the reinforcement residual. Room is made for constitutive law,
  * but actual use of contitutive laws is made in MaterialReinforcementTemplate.
  *
  * Be careful with the dimensions in this class :
  *  -  this->spatial_dimension is always 1
  *  -  the template parameter dim is the dimension of the problem
  */
 
 template <class Mat, UInt dim> class MaterialReinforcement : public Mat {
 
   /* ------------------------------------------------------------------------ */
   /* Constructors/Destructors                                                 */
   /* ------------------------------------------------------------------------ */
 public:
   /// Constructor
   MaterialReinforcement(EmbeddedInterfaceModel & model, const ID & id = "");
 
   /// Destructor
   ~MaterialReinforcement() override;
 
 protected:
   void initialize();
 
   /* ------------------------------------------------------------------------ */
   /* Methods                                                                  */
   /* ------------------------------------------------------------------------ */
 public:
   /// Init the material
   void initMaterial() override;
 
   /// Init the filters for background elements
   void initFilters();
 
   /// Init the background shape derivatives
   void initBackgroundShapeDerivatives();
 
   /// Init the cosine matrices
   void initDirectingCosines();
 
   /// Assemble stiffness matrix
   void assembleStiffnessMatrix(GhostType ghost_type) override;
 
   /// Compute all the stresses !
   void computeAllStresses(GhostType ghost_type) override;
 
   /// Compute energy
   Real getEnergy(const std::string & id) override;
 
   /// Assemble the residual of one type of element (typically _segment_2)
   void assembleInternalForces(GhostType ghost_type) override;
 
   /* ------------------------------------------------------------------------ */
   /* Protected methods                                                        */
   /* ------------------------------------------------------------------------ */
 protected:
   /// Allocate the background shape derivatives
   void allocBackgroundShapeDerivatives();
 
   /// Compute the directing cosines matrix for one element type
   void computeDirectingCosines(const ElementType & type, GhostType ghost_type);
 
   /// Compute the directing cosines matrix on quadrature points.
   inline void computeDirectingCosinesOnQuad(const Matrix<Real> & nodes,
                                             Matrix<Real> & cosines);
 
   /// Add the prestress to the computed stress
   void addPrestress(const ElementType & type, GhostType ghost_type);
 
   /// Compute displacement gradient in reinforcement
   void computeGradU(const ElementType & interface_type, GhostType ghost_type);
 
   /// Assemble the stiffness matrix for an element type (typically _segment_2)
   void assembleStiffnessMatrix(const ElementType & type, GhostType ghost_type);
 
   /// Assemble the stiffness matrix for background & interface types
   void assembleStiffnessMatrixInterface(const ElementType & interface_type,
                                         const ElementType & background_type,
                                         GhostType ghost_type);
 
   /// Compute the background shape derivatives for a type
   void computeBackgroundShapeDerivatives(const ElementType & type,
                                          GhostType ghost_type);
 
   /// Compute the background shape derivatives for a type pair
   void computeBackgroundShapeDerivatives(const ElementType & interface_type,
                                          const ElementType & bg_type,
                                          GhostType ghost_type,
                                          const Array<UInt> & filter);
 
   /// Filter elements crossed by interface of a type
   void filterInterfaceBackgroundElements(Array<UInt> & foreground,
                                          Array<UInt> & background,
                                          const ElementType & type,
                                          const ElementType & interface_type,
                                          GhostType ghost_type);
 
   /// Assemble the residual of one type of element (typically _segment_2)
   void assembleInternalForces(const ElementType & type, GhostType ghost_type);
 
   /// Assemble the residual for a pair of elements
   void assembleInternalForcesInterface(const ElementType & interface_type,
                                        const ElementType & background_type,
                                        GhostType ghost_type);
 
   // TODO figure out why voigt size is 4 in 2D
   inline void stressTensorToVoigtVector(const Matrix<Real> & tensor,
                                         Vector<Real> & vector);
   inline void strainTensorToVoigtVector(const Matrix<Real> & tensor,
                                         Vector<Real> & vector);
 
   /// Get background filter
   Array<UInt> & getBackgroundFilter(const ElementType & fg_type,
                                     const ElementType & bg_type,
                                     GhostType ghost_type) {
     return (*background_filter(fg_type, ghost_type))(bg_type, ghost_type);
   }
 
   /// Get foreground filter
   Array<UInt> & getForegroundFilter(const ElementType & fg_type,
                                     const ElementType & bg_type,
                                     GhostType ghost_type) {
     return (*foreground_filter(fg_type, ghost_type))(bg_type, ghost_type);
   }
 
   /* ------------------------------------------------------------------------ */
   /* Class Members                                                            */
   /* ------------------------------------------------------------------------ */
 protected:
   /// Embedded model
   EmbeddedInterfaceModel & emodel;
 
   /// Gradu of concrete on reinforcement
   InternalField<Real> gradu_embedded;
 
   /// C matrix on quad
   InternalField<Real> directing_cosines;
 
   /// Prestress on quad
   InternalField<Real> pre_stress;
 
   /// Cross-sectional area
   Real area;
 
   template <typename T>
   using CrossMap = ElementTypeMap<std::unique_ptr<ElementTypeMapArray<T>>>;
 
   /// Background mesh shape derivatives
   CrossMap<Real> shape_derivatives;
 
   /// Foreground mesh filter (contains segment ids)
   CrossMap<UInt> foreground_filter;
 
   /// Background element filter (contains bg ids)
   CrossMap<UInt> background_filter;
 };
 
 } // akantu
 
 #include "material_reinforcement_tmpl.hh"
 
 #endif // __AKANTU_MATERIAL_REINFORCEMENT_HH__
diff --git a/src/model/solid_mechanics/materials/material_embedded/material_reinforcement_tmpl.hh b/src/model/solid_mechanics/materials/material_embedded/material_reinforcement_tmpl.hh
index e8f8c5ef9..dadf9e27e 100644
--- a/src/model/solid_mechanics/materials/material_embedded/material_reinforcement_tmpl.hh
+++ b/src/model/solid_mechanics/materials/material_embedded/material_reinforcement_tmpl.hh
@@ -1,800 +1,801 @@
 /**
  * @file   material_reinforcement_tmpl.hh
  *
  * @author Lucas Frerot <lucas.frerot@epfl.ch>
  *
- * @date creation: Thu Feb 1 2018
+ * @date creation: Wed Mar 25 2015
+ * @date last modification: Tue Feb 20 2018
  *
  * @brief  Reinforcement material
  *
  * @section LICENSE
  *
- * Copyright (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne) Laboratory
- * (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * Copyright (©) 2015-2018 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
- * terms  of the  GNU Lesser  General Public  License as  published by  the Free
+ * 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
+ * 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 "aka_voigthelper.hh"
 #include "material_reinforcement.hh"
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 template <class Mat, UInt dim>
 MaterialReinforcement<Mat, dim>::MaterialReinforcement(
     EmbeddedInterfaceModel & model, const ID & id)
     : Mat(model, 1, model.getInterfaceMesh(),
           model.getFEEngine("EmbeddedInterfaceFEEngine"), id),
       emodel(model),
       gradu_embedded("gradu_embedded", *this, 1,
                      model.getFEEngine("EmbeddedInterfaceFEEngine"),
                      this->element_filter),
       directing_cosines("directing_cosines", *this, 1,
                         model.getFEEngine("EmbeddedInterfaceFEEngine"),
                         this->element_filter),
       pre_stress("pre_stress", *this, 1,
                  model.getFEEngine("EmbeddedInterfaceFEEngine"),
                  this->element_filter),
       area(1.0), shape_derivatives() {
   AKANTU_DEBUG_IN();
   this->initialize();
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <class Mat, UInt dim>
 void MaterialReinforcement<Mat, dim>::initialize() {
   AKANTU_DEBUG_IN();
 
   this->registerParam("area", area, _pat_parsable | _pat_modifiable,
                       "Reinforcement cross-sectional area");
   this->registerParam("pre_stress", pre_stress, _pat_parsable | _pat_modifiable,
                       "Uniform pre-stress");
 
   // this->unregisterInternal(this->stress);
 
   // Fool the AvgHomogenizingFunctor
   // stress.initialize(dim * dim);
 
   // Reallocate the element filter
   this->element_filter.initialize(this->emodel.getInterfaceMesh(),
                                   _spatial_dimension = 1);
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 
 template <class Mat, UInt dim>
 MaterialReinforcement<Mat, dim>::~MaterialReinforcement() {
   AKANTU_DEBUG_IN();
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 
 template <class Mat, UInt dim>
 void MaterialReinforcement<Mat, dim>::initMaterial() {
   Mat::initMaterial();
 
   gradu_embedded.initialize(dim * dim);
   pre_stress.initialize(1);
 
   /// We initialise the stuff that is not going to change during the simulation
   this->initFilters();
   this->allocBackgroundShapeDerivatives();
   this->initBackgroundShapeDerivatives();
   this->initDirectingCosines();
 }
 
 /* -------------------------------------------------------------------------- */
 /// Initialize the filter for background elements
 template <class Mat, UInt dim>
 void MaterialReinforcement<Mat, dim>::initFilters() {
   for (auto gt : ghost_types) {
     for (auto && type : emodel.getInterfaceMesh().elementTypes(1, gt)) {
       std::string shaped_id = "filter";
       if (gt == _ghost)
         shaped_id += ":ghost";
 
       auto & background =
           background_filter(std::make_unique<ElementTypeMapArray<UInt>>(
                                 "bg_" + shaped_id, this->name),
                             type, gt);
       auto & foreground = foreground_filter(
           std::make_unique<ElementTypeMapArray<UInt>>(shaped_id, this->name),
           type, gt);
       foreground->initialize(emodel.getMesh(), _nb_component = 1,
                              _ghost_type = gt);
       background->initialize(emodel.getMesh(), _nb_component = 1,
                              _ghost_type = gt);
 
       // Computing filters
       for (auto && bg_type : background->elementTypes(dim, gt)) {
         filterInterfaceBackgroundElements(
             (*foreground)(bg_type), (*background)(bg_type), bg_type, type, gt);
       }
     }
   }
 }
 
 /* -------------------------------------------------------------------------- */
 /// Construct a filter for a (interface_type, background_type) pair
 template <class Mat, UInt dim>
 void MaterialReinforcement<Mat, dim>::filterInterfaceBackgroundElements(
     Array<UInt> & foreground, Array<UInt> & background,
     const ElementType & type, const ElementType & interface_type,
     GhostType ghost_type) {
   AKANTU_DEBUG_IN();
 
   foreground.resize(0);
   background.resize(0);
 
   Array<Element> & elements =
       emodel.getInterfaceAssociatedElements(interface_type, ghost_type);
   Array<UInt> & elem_filter = this->element_filter(interface_type, ghost_type);
 
   for (auto & elem_id : elem_filter) {
     Element & elem = elements(elem_id);
     if (elem.type == type) {
       background.push_back(elem.element);
       foreground.push_back(elem_id);
     }
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 
 namespace detail {
   class BackgroundShapeDInitializer : public ElementTypeMapArrayInitializer {
   public:
     BackgroundShapeDInitializer(UInt spatial_dimension, FEEngine & engine,
                                 const ElementType & foreground_type,
                                 const ElementTypeMapArray<UInt> & filter,
                                 const GhostType & ghost_type)
         : ElementTypeMapArrayInitializer(
               [](const ElementType & bgtype, const GhostType &) {
                 return ShapeFunctions::getShapeDerivativesSize(bgtype);
               },
               spatial_dimension, ghost_type, _ek_regular) {
       auto nb_quad = engine.getNbIntegrationPoints(foreground_type);
       // Counting how many background elements are affected by elements of
       // interface_type
       for (auto type : filter.elementTypes(this->spatial_dimension)) {
         // Inserting size
         array_size_per_bg_type(filter(type).size() * nb_quad, type,
                                this->ghost_type);
       }
     }
 
     auto elementTypes() const -> decltype(auto) {
       return array_size_per_bg_type.elementTypes();
     }
 
     UInt size(const ElementType & bgtype) const {
       return array_size_per_bg_type(bgtype, this->ghost_type);
     }
 
   protected:
     ElementTypeMap<UInt> array_size_per_bg_type;
   };
 }
 
 /**
  * Background shape derivatives need to be stored per background element
  * types but also per embedded element type, which is why they are stored
  * in an ElementTypeMap<ElementTypeMapArray<Real> *>. The outer ElementTypeMap
  * refers to the embedded types, and the inner refers to the background types.
  */
 template <class Mat, UInt dim>
 void MaterialReinforcement<Mat, dim>::allocBackgroundShapeDerivatives() {
   AKANTU_DEBUG_IN();
 
   for (auto gt : ghost_types) {
     for (auto && type : emodel.getInterfaceMesh().elementTypes(1, gt)) {
       std::string shaped_id = "embedded_shape_derivatives";
       if (gt == _ghost)
         shaped_id += ":ghost";
 
       auto & shaped_etma = shape_derivatives(
           std::make_unique<ElementTypeMapArray<Real>>(shaped_id, this->name),
           type, gt);
       shaped_etma->initialize(
           detail::BackgroundShapeDInitializer(
               emodel.getSpatialDimension(),
               emodel.getFEEngine("EmbeddedInterfaceFEEngine"), type,
               *background_filter(type, gt), gt),
           0, true);
     }
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 
 template <class Mat, UInt dim>
 void MaterialReinforcement<Mat, dim>::initBackgroundShapeDerivatives() {
   AKANTU_DEBUG_IN();
 
   for (auto interface_type :
        this->element_filter.elementTypes(this->spatial_dimension)) {
     for (auto type : background_filter(interface_type)->elementTypes(dim)) {
       computeBackgroundShapeDerivatives(interface_type, type, _not_ghost,
                                         this->element_filter(interface_type));
     }
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <class Mat, UInt dim>
 void MaterialReinforcement<Mat, dim>::computeBackgroundShapeDerivatives(
     const ElementType & interface_type, const ElementType & bg_type,
     GhostType ghost_type, const Array<UInt> & filter) {
   auto & interface_engine = emodel.getFEEngine("EmbeddedInterfaceFEEngine");
   auto & engine = emodel.getFEEngine();
   auto & interface_mesh = emodel.getInterfaceMesh();
 
   const auto nb_nodes_elem_bg = Mesh::getNbNodesPerElement(bg_type);
   // const auto nb_strss = VoigtHelper<dim>::size;
   const auto nb_quads_per_elem =
       interface_engine.getNbIntegrationPoints(interface_type);
 
   Array<Real> quad_pos(0, dim, "interface_quad_pos");
   interface_engine.interpolateOnIntegrationPoints(interface_mesh.getNodes(),
                                                   quad_pos, dim, interface_type,
                                                   ghost_type, filter);
   auto & background_shapesd =
       (*shape_derivatives(interface_type, ghost_type))(bg_type, ghost_type);
   auto & background_elements =
       (*background_filter(interface_type, ghost_type))(bg_type, ghost_type);
   auto & foreground_elements =
       (*foreground_filter(interface_type, ghost_type))(bg_type, ghost_type);
 
   auto shapesd_begin =
       background_shapesd.begin(dim, nb_nodes_elem_bg, nb_quads_per_elem);
   auto quad_begin = quad_pos.begin(dim, nb_quads_per_elem);
 
   for (auto && tuple : zip(background_elements, foreground_elements)) {
     UInt bg = std::get<0>(tuple), fg = std::get<1>(tuple);
     for (UInt i = 0; i < nb_quads_per_elem; ++i) {
       Matrix<Real> shapesd = Tensor3<Real>(shapesd_begin[fg])(i);
       Vector<Real> quads = Matrix<Real>(quad_begin[fg])(i);
 
       engine.computeShapeDerivatives(quads, bg, bg_type, shapesd, ghost_type);
     }
   }
 }
 
 /* -------------------------------------------------------------------------- */
 
 template <class Mat, UInt dim>
 void MaterialReinforcement<Mat, dim>::initDirectingCosines() {
   AKANTU_DEBUG_IN();
 
   Mesh & mesh = emodel.getInterfaceMesh();
 
   Mesh::type_iterator type_it = mesh.firstType(1, _not_ghost);
   Mesh::type_iterator type_end = mesh.lastType(1, _not_ghost);
 
   const UInt voigt_size = VoigtHelper<dim>::size;
   directing_cosines.initialize(voigt_size);
 
   for (; type_it != type_end; ++type_it) {
     computeDirectingCosines(*type_it, _not_ghost);
     // computeDirectingCosines(*type_it, _ghost);
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 
 template <class Mat, UInt dim>
 void MaterialReinforcement<Mat, dim>::assembleStiffnessMatrix(
     GhostType ghost_type) {
   AKANTU_DEBUG_IN();
 
   Mesh & interface_mesh = emodel.getInterfaceMesh();
 
   Mesh::type_iterator type_it = interface_mesh.firstType(1, _not_ghost);
   Mesh::type_iterator type_end = interface_mesh.lastType(1, _not_ghost);
 
   for (; type_it != type_end; ++type_it) {
     assembleStiffnessMatrix(*type_it, ghost_type);
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 
 template <class Mat, UInt dim>
 void MaterialReinforcement<Mat, dim>::assembleInternalForces(
     GhostType ghost_type) {
   AKANTU_DEBUG_IN();
 
   Mesh & interface_mesh = emodel.getInterfaceMesh();
 
   Mesh::type_iterator type_it = interface_mesh.firstType(1, _not_ghost);
   Mesh::type_iterator type_end = interface_mesh.lastType(1, _not_ghost);
 
   for (; type_it != type_end; ++type_it) {
     this->assembleInternalForces(*type_it, ghost_type);
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <class Mat, UInt dim>
 void MaterialReinforcement<Mat, dim>::computeAllStresses(GhostType ghost_type) {
   AKANTU_DEBUG_IN();
 
   Mesh::type_iterator it = emodel.getInterfaceMesh().firstType();
   Mesh::type_iterator last_type = emodel.getInterfaceMesh().lastType();
 
   for (; it != last_type; ++it) {
     computeGradU(*it, ghost_type);
     this->computeStress(*it, ghost_type);
     addPrestress(*it, ghost_type);
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <class Mat, UInt dim>
 void MaterialReinforcement<Mat, dim>::addPrestress(const ElementType & type,
                                                    GhostType ghost_type) {
   auto & stress = this->stress(type, ghost_type);
   auto & sigma_p = this->pre_stress(type, ghost_type);
 
   for (auto && tuple : zip(stress, sigma_p)) {
     std::get<0>(tuple) += std::get<1>(tuple);
   }
 }
 
 /* -------------------------------------------------------------------------- */
 template <class Mat, UInt dim>
 void MaterialReinforcement<Mat, dim>::assembleInternalForces(
     const ElementType & type, GhostType ghost_type) {
   AKANTU_DEBUG_IN();
 
   Mesh & mesh = emodel.getMesh();
 
   Mesh::type_iterator type_it = mesh.firstType(dim, ghost_type);
   Mesh::type_iterator type_end = mesh.lastType(dim, ghost_type);
 
   for (; type_it != type_end; ++type_it) {
     assembleInternalForcesInterface(type, *type_it, ghost_type);
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 
 /**
  * Computes and assemble the residual. Residual in reinforcement is computed as:
  *
  * \f[
  * \vec{r} = A_s \int_S{\mathbf{B}^T\mathbf{C}^T \vec{\sigma_s}\,\mathrm{d}s}
  * \f]
  */
 template <class Mat, UInt dim>
 void MaterialReinforcement<Mat, dim>::assembleInternalForcesInterface(
     const ElementType & interface_type, const ElementType & background_type,
     GhostType ghost_type) {
   AKANTU_DEBUG_IN();
 
   UInt voigt_size = VoigtHelper<dim>::size;
 
   FEEngine & interface_engine = emodel.getFEEngine("EmbeddedInterfaceFEEngine");
 
   Array<UInt> & elem_filter = this->element_filter(interface_type, ghost_type);
 
   UInt nodes_per_background_e = Mesh::getNbNodesPerElement(background_type);
   UInt nb_quadrature_points =
       interface_engine.getNbIntegrationPoints(interface_type, ghost_type);
   UInt nb_element = elem_filter.size();
 
   UInt back_dof = dim * nodes_per_background_e;
 
   Array<Real> & shapesd = (*shape_derivatives(interface_type, ghost_type))(
       background_type, ghost_type);
 
   Array<Real> integrant(nb_quadrature_points * nb_element, back_dof,
                         "integrant");
 
   auto integrant_it = integrant.begin(back_dof);
   auto integrant_end = integrant.end(back_dof);
 
   Array<Real>::matrix_iterator B_it =
       shapesd.begin(dim, nodes_per_background_e);
   auto C_it = directing_cosines(interface_type, ghost_type).begin(voigt_size);
 
   auto sigma_it = this->stress(interface_type, ghost_type).begin();
 
   Matrix<Real> Bvoigt(voigt_size, back_dof);
 
   for (; integrant_it != integrant_end;
        ++integrant_it, ++B_it, ++C_it, ++sigma_it) {
     VoigtHelper<dim>::transferBMatrixToSymVoigtBMatrix(*B_it, Bvoigt,
                                                        nodes_per_background_e);
     Vector<Real> & C = *C_it;
     Vector<Real> & BtCt_sigma = *integrant_it;
 
     BtCt_sigma.mul<true>(Bvoigt, C);
     BtCt_sigma *= *sigma_it * area;
   }
 
   Array<Real> residual_interface(nb_element, back_dof, "residual_interface");
   interface_engine.integrate(integrant, residual_interface, back_dof,
                              interface_type, ghost_type, elem_filter);
   integrant.resize(0);
 
   Array<UInt> background_filter(nb_element, 1, "background_filter");
 
   auto & filter =
       getBackgroundFilter(interface_type, background_type, ghost_type);
 
   emodel.getDOFManager().assembleElementalArrayLocalArray(
       residual_interface, emodel.getInternalForce(), background_type,
       ghost_type, -1., filter);
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 
 template <class Mat, UInt dim>
 void MaterialReinforcement<Mat, dim>::computeDirectingCosines(
     const ElementType & type, GhostType ghost_type) {
   AKANTU_DEBUG_IN();
 
   Mesh & interface_mesh = emodel.getInterfaceMesh();
 
   const UInt nb_nodes_per_element = Mesh::getNbNodesPerElement(type);
   const UInt steel_dof = dim * nb_nodes_per_element;
   const UInt voigt_size = VoigtHelper<dim>::size;
   const UInt nb_quad_points = emodel.getFEEngine("EmbeddedInterfaceFEEngine")
                                   .getNbIntegrationPoints(type, ghost_type);
 
   Array<Real> node_coordinates(this->element_filter(type, ghost_type).size(),
                                steel_dof);
 
   this->emodel.getFEEngine().template extractNodalToElementField<Real>(
       interface_mesh, interface_mesh.getNodes(), node_coordinates, type,
       ghost_type, this->element_filter(type, ghost_type));
 
   Array<Real>::matrix_iterator directing_cosines_it =
       directing_cosines(type, ghost_type).begin(1, voigt_size);
 
   Array<Real>::matrix_iterator node_coordinates_it =
       node_coordinates.begin(dim, nb_nodes_per_element);
   Array<Real>::matrix_iterator node_coordinates_end =
       node_coordinates.end(dim, nb_nodes_per_element);
 
   for (; node_coordinates_it != node_coordinates_end; ++node_coordinates_it) {
     for (UInt i = 0; i < nb_quad_points; i++, ++directing_cosines_it) {
       Matrix<Real> & nodes = *node_coordinates_it;
       Matrix<Real> & cosines = *directing_cosines_it;
 
       computeDirectingCosinesOnQuad(nodes, cosines);
     }
   }
 
   // Mauro: the directing_cosines internal is defined on the quadrature points
   // of each element
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 
 template <class Mat, UInt dim>
 void MaterialReinforcement<Mat, dim>::assembleStiffnessMatrix(
     const ElementType & type, GhostType ghost_type) {
   AKANTU_DEBUG_IN();
 
   Mesh & mesh = emodel.getMesh();
 
   Mesh::type_iterator type_it = mesh.firstType(dim, ghost_type);
   Mesh::type_iterator type_end = mesh.lastType(dim, ghost_type);
 
   for (; type_it != type_end; ++type_it) {
     assembleStiffnessMatrixInterface(type, *type_it, ghost_type);
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 /**
  * Computes the reinforcement stiffness matrix (Gomes & Awruch, 2001)
  * \f[
  * \mathbf{K}_e = \sum_{i=1}^R{A_i\int_{S_i}{\mathbf{B}^T
  * \mathbf{C}_i^T \mathbf{D}_{s, i} \mathbf{C}_i \mathbf{B}\,\mathrm{d}s}}
  * \f]
  */
 template <class Mat, UInt dim>
 void MaterialReinforcement<Mat, dim>::assembleStiffnessMatrixInterface(
     const ElementType & interface_type, const ElementType & background_type,
     GhostType ghost_type) {
   AKANTU_DEBUG_IN();
 
   UInt voigt_size = VoigtHelper<dim>::size;
 
   FEEngine & interface_engine = emodel.getFEEngine("EmbeddedInterfaceFEEngine");
 
   Array<UInt> & elem_filter = this->element_filter(interface_type, ghost_type);
   Array<Real> & grad_u = gradu_embedded(interface_type, ghost_type);
 
   UInt nb_element = elem_filter.size();
   UInt nodes_per_background_e = Mesh::getNbNodesPerElement(background_type);
   UInt nb_quadrature_points =
       interface_engine.getNbIntegrationPoints(interface_type, ghost_type);
 
   UInt back_dof = dim * nodes_per_background_e;
 
   UInt integrant_size = back_dof;
 
   grad_u.resize(nb_quadrature_points * nb_element);
 
   Array<Real> tangent_moduli(nb_element * nb_quadrature_points, 1,
                              "interface_tangent_moduli");
   this->computeTangentModuli(interface_type, tangent_moduli, ghost_type);
 
   Array<Real> & shapesd = (*shape_derivatives(interface_type, ghost_type))(
       background_type, ghost_type);
 
   Array<Real> integrant(nb_element * nb_quadrature_points,
                         integrant_size * integrant_size, "B^t*C^t*D*C*B");
 
   /// Temporary matrices for integrant product
   Matrix<Real> Bvoigt(voigt_size, back_dof);
   Matrix<Real> DCB(1, back_dof);
   Matrix<Real> CtDCB(voigt_size, back_dof);
 
   Array<Real>::scalar_iterator D_it = tangent_moduli.begin();
   Array<Real>::scalar_iterator D_end = tangent_moduli.end();
 
   Array<Real>::matrix_iterator C_it =
       directing_cosines(interface_type, ghost_type).begin(1, voigt_size);
   Array<Real>::matrix_iterator B_it =
       shapesd.begin(dim, nodes_per_background_e);
   Array<Real>::matrix_iterator integrant_it =
       integrant.begin(integrant_size, integrant_size);
 
   for (; D_it != D_end; ++D_it, ++C_it, ++B_it, ++integrant_it) {
     Real & D = *D_it;
     Matrix<Real> & C = *C_it;
     Matrix<Real> & B = *B_it;
     Matrix<Real> & BtCtDCB = *integrant_it;
 
     VoigtHelper<dim>::transferBMatrixToSymVoigtBMatrix(B, Bvoigt,
                                                        nodes_per_background_e);
 
     DCB.mul<false, false>(C, Bvoigt);
     DCB *= D * area;
     CtDCB.mul<true, false>(C, DCB);
     BtCtDCB.mul<true, false>(Bvoigt, CtDCB);
   }
 
   tangent_moduli.resize(0);
 
   Array<Real> K_interface(nb_element, integrant_size * integrant_size,
                           "K_interface");
   interface_engine.integrate(integrant, K_interface,
                              integrant_size * integrant_size, interface_type,
                              ghost_type, elem_filter);
 
   integrant.resize(0);
 
   // Mauro: Here K_interface contains the local stiffness matrices,
   // directing_cosines contains the information about the orientation
   // of the reinforcements, any rotation of the local stiffness matrix
   // can be done here
 
   auto & filter =
       getBackgroundFilter(interface_type, background_type, ghost_type);
 
   emodel.getDOFManager().assembleElementalMatricesToMatrix(
       "K", "displacement", K_interface, background_type, ghost_type, _symmetric,
       filter);
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <class Mat, UInt dim>
 Real MaterialReinforcement<Mat, dim>::getEnergy(const std::string & id) {
   AKANTU_DEBUG_IN();
   if (id == "potential") {
     Real epot = 0.;
 
     this->computePotentialEnergyByElements();
 
     Mesh::type_iterator it = this->element_filter.firstType(
                             this->spatial_dimension),
                         end = this->element_filter.lastType(
                             this->spatial_dimension);
 
     for (; it != end; ++it) {
       FEEngine & interface_engine =
           emodel.getFEEngine("EmbeddedInterfaceFEEngine");
       epot += interface_engine.integrate(
           this->potential_energy(*it, _not_ghost), *it, _not_ghost,
           this->element_filter(*it, _not_ghost));
       epot *= area;
     }
 
     return epot;
   }
 
   AKANTU_DEBUG_OUT();
   return 0;
 }
 
 /* -------------------------------------------------------------------------- */
 
 template <class Mat, UInt dim>
 void MaterialReinforcement<Mat, dim>::computeGradU(
     const ElementType & interface_type, GhostType ghost_type) {
   // Looping over background types
   for (auto && bg_type :
        background_filter(interface_type, ghost_type)->elementTypes(dim)) {
 
     const UInt nodes_per_background_e = Mesh::getNbNodesPerElement(bg_type);
     const UInt voigt_size = VoigtHelper<dim>::size;
 
     auto & bg_shapesd =
         (*shape_derivatives(interface_type, ghost_type))(bg_type, ghost_type);
 
     auto & filter = getBackgroundFilter(interface_type, bg_type, ghost_type);
 
     Array<Real> disp_per_element(0, dim * nodes_per_background_e, "disp_elem");
 
     FEEngine::extractNodalToElementField(
         emodel.getMesh(), emodel.getDisplacement(), disp_per_element, bg_type,
         ghost_type, filter);
 
     Matrix<Real> concrete_du(dim, dim);
     Matrix<Real> epsilon(dim, dim);
     Vector<Real> evoigt(voigt_size);
 
     for (auto && tuple :
          zip(make_view(disp_per_element, dim, nodes_per_background_e),
              make_view(bg_shapesd, dim, nodes_per_background_e),
              this->gradu(interface_type, ghost_type),
              make_view(this->directing_cosines(interface_type, ghost_type),
                        voigt_size))) {
       auto & u = std::get<0>(tuple);
       auto & B = std::get<1>(tuple);
       auto & du = std::get<2>(tuple);
       auto & C = std::get<3>(tuple);
 
       concrete_du.mul<false, true>(u, B);
       auto epsilon = 0.5 * (concrete_du + concrete_du.transpose());
       strainTensorToVoigtVector(epsilon, evoigt);
       du = C.dot(evoigt);
     }
   }
 }
 
 /* -------------------------------------------------------------------------- */
 
 /**
  * The structure of the directing cosines matrix is :
  * \f{eqnarray*}{
  *  C_{1,\cdot} & = & (l^2, m^2, n^2, mn, ln, lm) \\
  *  C_{i,j} & = & 0
  * \f}
  *
  * with :
  * \f[
  * (l, m, n) = \frac{1}{\|\frac{\mathrm{d}\vec{r}(s)}{\mathrm{d}s}\|} \cdot
  * \frac{\mathrm{d}\vec{r}(s)}{\mathrm{d}s}
  * \f]
  */
 template <class Mat, UInt dim>
 inline void MaterialReinforcement<Mat, dim>::computeDirectingCosinesOnQuad(
     const Matrix<Real> & nodes, Matrix<Real> & cosines) {
   AKANTU_DEBUG_IN();
 
   AKANTU_DEBUG_ASSERT(nodes.cols() == 2,
                       "Higher order reinforcement elements not implemented");
 
   const Vector<Real> a = nodes(0), b = nodes(1);
   Vector<Real> delta = b - a;
 
   Real sq_length = 0.;
   for (UInt i = 0; i < dim; i++) {
     sq_length += delta(i) * delta(i);
   }
 
   if (dim == 2) {
     cosines(0, 0) = delta(0) * delta(0); // l^2
     cosines(0, 1) = delta(1) * delta(1); // m^2
     cosines(0, 2) = delta(0) * delta(1); // lm
   } else if (dim == 3) {
     cosines(0, 0) = delta(0) * delta(0); // l^2
     cosines(0, 1) = delta(1) * delta(1); // m^2
     cosines(0, 2) = delta(2) * delta(2); // n^2
 
     cosines(0, 3) = delta(1) * delta(2); // mn
     cosines(0, 4) = delta(0) * delta(2); // ln
     cosines(0, 5) = delta(0) * delta(1); // lm
   }
 
   cosines /= sq_length;
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 
 template <class Mat, UInt dim>
 inline void MaterialReinforcement<Mat, dim>::stressTensorToVoigtVector(
     const Matrix<Real> & tensor, Vector<Real> & vector) {
   AKANTU_DEBUG_IN();
 
   for (UInt i = 0; i < dim; i++) {
     vector(i) = tensor(i, i);
   }
 
   if (dim == 2) {
     vector(2) = tensor(0, 1);
   } else if (dim == 3) {
     vector(3) = tensor(1, 2);
     vector(4) = tensor(0, 2);
     vector(5) = tensor(0, 1);
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 
 template <class Mat, UInt dim>
 inline void MaterialReinforcement<Mat, dim>::strainTensorToVoigtVector(
     const Matrix<Real> & tensor, Vector<Real> & vector) {
   AKANTU_DEBUG_IN();
 
   for (UInt i = 0; i < dim; i++) {
     vector(i) = tensor(i, i);
   }
 
   if (dim == 2) {
     vector(2) = 2 * tensor(0, 1);
   } else if (dim == 3) {
     vector(3) = 2 * tensor(1, 2);
     vector(4) = 2 * tensor(0, 2);
     vector(5) = 2 * tensor(0, 1);
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 } // akantu
diff --git a/src/model/solid_mechanics/materials/material_finite_deformation/material_neohookean.cc b/src/model/solid_mechanics/materials/material_finite_deformation/material_neohookean.cc
index 1f2e92ac8..bf8906b65 100644
--- a/src/model/solid_mechanics/materials/material_finite_deformation/material_neohookean.cc
+++ b/src/model/solid_mechanics/materials/material_finite_deformation/material_neohookean.cc
@@ -1,287 +1,287 @@
 /**
  * @file   material_neohookean.cc
  *
  * @author Daniel Pino Muñoz <daniel.pinomunoz@epfl.ch>
  *
  * @date creation: Mon Apr 08 2013
- * @date last modification: Tue Aug 04 2015
+ * @date last modification: Wed Nov 08 2017
  *
  * @brief  Specialization of the material class for finite deformation
  * neo-hookean material
  *
  * @section LICENSE
  *
- * Copyright  (©)  2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de Lausanne)
+ * 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
+ * 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
+ * A PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 #include "material_neohookean.hh"
 #include "solid_mechanics_model.hh"
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 template <UInt spatial_dimension>
 MaterialNeohookean<spatial_dimension>::MaterialNeohookean(
     SolidMechanicsModel & model, const ID & id)
     : PlaneStressToolbox<spatial_dimension>(model, id) {
   AKANTU_DEBUG_IN();
 
   this->registerParam("E", E, Real(0.), _pat_parsable | _pat_modifiable,
                       "Young's modulus");
   this->registerParam("nu", nu, Real(0.5), _pat_parsable | _pat_modifiable,
                       "Poisson's ratio");
   this->registerParam("lambda", lambda, _pat_readable,
                       "First Lamé coefficient");
   this->registerParam("mu", mu, _pat_readable, "Second Lamé coefficient");
   this->registerParam("kapa", kpa, _pat_readable, "Bulk coefficient");
 
   this->finite_deformation = true;
   this->initialize_third_axis_deformation = true;
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <UInt spatial_dimension>
 void MaterialNeohookean<spatial_dimension>::initMaterial() {
   AKANTU_DEBUG_IN();
   PlaneStressToolbox<spatial_dimension>::initMaterial();
   if (spatial_dimension == 1)
     nu = 0.;
   this->updateInternalParameters();
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <> void MaterialNeohookean<2>::initMaterial() {
   AKANTU_DEBUG_IN();
   PlaneStressToolbox<2>::initMaterial();
   this->updateInternalParameters();
 
   if (this->plane_stress)
     this->third_axis_deformation.setDefaultValue(1.);
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <UInt spatial_dimension>
 void MaterialNeohookean<spatial_dimension>::updateInternalParameters() {
   lambda = nu * E / ((1 + nu) * (1 - 2 * nu));
   mu = E / (2 * (1 + nu));
 
   kpa = lambda + 2. / 3. * mu;
 }
 
 /* -------------------------------------------------------------------------- */
 template <UInt dim>
 void MaterialNeohookean<dim>::computeCauchyStressPlaneStress(
     ElementType el_type, GhostType ghost_type) {
   AKANTU_DEBUG_IN();
 
   PlaneStressToolbox<dim>::computeCauchyStressPlaneStress(el_type, ghost_type);
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <>
 void MaterialNeohookean<2>::computeCauchyStressPlaneStress(
     ElementType el_type, GhostType ghost_type) {
   AKANTU_DEBUG_IN();
 
   Array<Real>::matrix_iterator gradu_it =
       this->gradu(el_type, ghost_type).begin(2, 2);
 
   Array<Real>::matrix_iterator gradu_end =
       this->gradu(el_type, ghost_type).end(2, 2);
 
   Array<Real>::matrix_iterator piola_it =
       this->piola_kirchhoff_2(el_type, ghost_type).begin(2, 2);
 
   Array<Real>::matrix_iterator stress_it =
       this->stress(el_type, ghost_type).begin(2, 2);
 
   Array<Real>::const_scalar_iterator c33_it =
       this->third_axis_deformation(el_type, ghost_type).begin();
 
   Matrix<Real> F_tensor(2, 2);
 
   for (; gradu_it != gradu_end; ++gradu_it, ++piola_it, ++stress_it, ++c33_it) {
     Matrix<Real> & grad_u = *gradu_it;
     Matrix<Real> & piola = *piola_it;
     Matrix<Real> & sigma = *stress_it;
 
     gradUToF<2>(grad_u, F_tensor);
     computeCauchyStressOnQuad<2>(F_tensor, piola, sigma, *c33_it);
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <UInt dim>
 void MaterialNeohookean<dim>::computeStress(ElementType el_type,
                                             GhostType ghost_type) {
   AKANTU_DEBUG_IN();
 
   MATERIAL_STRESS_QUADRATURE_POINT_LOOP_BEGIN(el_type, ghost_type);
   computeStressOnQuad(grad_u, sigma);
   MATERIAL_STRESS_QUADRATURE_POINT_LOOP_END;
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <>
 void MaterialNeohookean<2>::computeStress(ElementType el_type,
                                           GhostType ghost_type) {
   AKANTU_DEBUG_IN();
 
   if (this->plane_stress) {
     PlaneStressToolbox<2>::computeStress(el_type, ghost_type);
 
     Array<Real>::const_scalar_iterator c33_it =
         this->third_axis_deformation(el_type, ghost_type).begin();
 
     MATERIAL_STRESS_QUADRATURE_POINT_LOOP_BEGIN(el_type, ghost_type);
     computeStressOnQuad(grad_u, sigma, *c33_it);
     ++c33_it;
     MATERIAL_STRESS_QUADRATURE_POINT_LOOP_END;
   } else {
 
     MATERIAL_STRESS_QUADRATURE_POINT_LOOP_BEGIN(el_type, ghost_type);
     computeStressOnQuad(grad_u, sigma);
     MATERIAL_STRESS_QUADRATURE_POINT_LOOP_END;
   }
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <UInt dim>
 void MaterialNeohookean<dim>::computeThirdAxisDeformation(
     ElementType /*el_type*/, GhostType /*ghost_type*/) {}
 
 /* -------------------------------------------------------------------------- */
 template <>
 void MaterialNeohookean<2>::computeThirdAxisDeformation(ElementType el_type,
                                                         GhostType ghost_type) {
   AKANTU_DEBUG_IN();
 
   AKANTU_DEBUG_ASSERT(this->plane_stress, "The third component of the strain "
                                           "can only be computed for 2D "
                                           "problems in Plane Stress!!");
 
   Array<Real>::scalar_iterator c33_it =
       this->third_axis_deformation(el_type, ghost_type).begin();
 
   MATERIAL_STRESS_QUADRATURE_POINT_LOOP_BEGIN(el_type, ghost_type);
   computeThirdAxisDeformationOnQuad(grad_u, *c33_it);
   ++c33_it;
   MATERIAL_STRESS_QUADRATURE_POINT_LOOP_END;
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <UInt spatial_dimension>
 void MaterialNeohookean<spatial_dimension>::computePotentialEnergy(
     ElementType el_type, GhostType ghost_type) {
   AKANTU_DEBUG_IN();
 
   Material::computePotentialEnergy(el_type, ghost_type);
 
   if (ghost_type != _not_ghost)
     return;
   Array<Real>::scalar_iterator epot =
       this->potential_energy(el_type, ghost_type).begin();
 
   MATERIAL_STRESS_QUADRATURE_POINT_LOOP_BEGIN(el_type, ghost_type);
 
   computePotentialEnergyOnQuad(grad_u, *epot);
   ++epot;
 
   MATERIAL_STRESS_QUADRATURE_POINT_LOOP_END;
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <UInt spatial_dimension>
 void MaterialNeohookean<spatial_dimension>::computeTangentModuli(
     __attribute__((unused)) const ElementType & el_type,
     Array<Real> & tangent_matrix,
     __attribute__((unused)) GhostType ghost_type) {
   AKANTU_DEBUG_IN();
 
   MATERIAL_TANGENT_QUADRATURE_POINT_LOOP_BEGIN(tangent_matrix);
   computeTangentModuliOnQuad(tangent, grad_u);
   MATERIAL_TANGENT_QUADRATURE_POINT_LOOP_END;
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <>
 void MaterialNeohookean<2>::computeTangentModuli(__attribute__((unused))
                                                  const ElementType & el_type,
                                                  Array<Real> & tangent_matrix,
                                                  __attribute__((unused))
                                                  GhostType ghost_type) {
   AKANTU_DEBUG_IN();
 
   if (this->plane_stress) {
     PlaneStressToolbox<2>::computeStress(el_type, ghost_type);
 
     Array<Real>::const_scalar_iterator c33_it =
         this->third_axis_deformation(el_type, ghost_type).begin();
 
     MATERIAL_TANGENT_QUADRATURE_POINT_LOOP_BEGIN(tangent_matrix);
     computeTangentModuliOnQuad(tangent, grad_u, *c33_it);
     ++c33_it;
     MATERIAL_TANGENT_QUADRATURE_POINT_LOOP_END;
 
   } else {
 
     MATERIAL_TANGENT_QUADRATURE_POINT_LOOP_BEGIN(tangent_matrix);
     computeTangentModuliOnQuad(tangent, grad_u);
     MATERIAL_TANGENT_QUADRATURE_POINT_LOOP_END;
   }
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <UInt spatial_dimension>
 Real MaterialNeohookean<spatial_dimension>::getPushWaveSpeed(
     __attribute__((unused)) const Element & element) const {
   return sqrt((this->lambda + 2 * this->mu) / this->rho);
 }
 
 /* -------------------------------------------------------------------------- */
 template <UInt spatial_dimension>
 Real MaterialNeohookean<spatial_dimension>::getShearWaveSpeed(
     __attribute__((unused)) const Element & element) const {
   return sqrt(this->mu / this->rho);
 }
 
 /* -------------------------------------------------------------------------- */
 
 INSTANTIATE_MATERIAL(neohookean, MaterialNeohookean);
 
 } // namespace akantu
diff --git a/src/model/solid_mechanics/materials/material_finite_deformation/material_neohookean.hh b/src/model/solid_mechanics/materials/material_finite_deformation/material_neohookean.hh
index 96d6b1b7c..77a934ded 100644
--- a/src/model/solid_mechanics/materials/material_finite_deformation/material_neohookean.hh
+++ b/src/model/solid_mechanics/materials/material_finite_deformation/material_neohookean.hh
@@ -1,169 +1,168 @@
 /**
  * @file   material_neohookean.hh
  *
  * @author Daniel Pino Muñoz <daniel.pinomunoz@epfl.ch>
  *
  * @date creation: Fri Jun 18 2010
- * @date last modification: Thu Oct 08 2015
+ * @date last modification: Wed Nov 29 2017
  *
  * @brief  Material isotropic elastic
  *
  * @section LICENSE
  *
- * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
- * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
- * Solides)
+ * 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
+ * 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
+ * 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 "material.hh"
 #include "plane_stress_toolbox.hh"
 
 /* -------------------------------------------------------------------------- */
 
 #ifndef __AKANTU_MATERIAL_NEOHOOKEAN_HH__
 #define __AKANTU_MATERIAL_NEOHOOKEAN_HH__
 
 namespace akantu {
 
 /**
  * Material elastic isotropic
  *
  * parameters in the material files :
  *   - rho : density (default: 0)
  *   - E   : Young's modulus (default: 0)
  *   - nu  : Poisson's ratio (default: 1/2)
  *   - Plane_Stress : if 0: plane strain, else: plane stress (default: 0)
  */
 template <UInt spatial_dimension>
 class MaterialNeohookean : public PlaneStressToolbox<spatial_dimension> {
   /* ------------------------------------------------------------------------ */
   /* Constructors/Destructors                                                 */
   /* ------------------------------------------------------------------------ */
 public:
   MaterialNeohookean(SolidMechanicsModel & model, const ID & id = "");
 
   ~MaterialNeohookean() override = default;
 
   /* ------------------------------------------------------------------------ */
   /* Methods                                                                  */
   /* ------------------------------------------------------------------------ */
 public:
   /// initialize the material computed parameter
   void initMaterial() override;
 
   /// constitutive law for all element of a type
   void computeStress(ElementType el_type,
                      GhostType ghost_type = _not_ghost) override;
 
   /// Computation of the cauchy stress for plane strain materials
   void
   computeCauchyStressPlaneStress(ElementType el_type,
                                  GhostType ghost_type = _not_ghost) override;
 
   /// Non linear computation of the third direction strain in 2D plane stress
   /// case
   void computeThirdAxisDeformation(ElementType el_type,
                                    GhostType ghost_type = _not_ghost) override;
 
   /// compute the elastic potential energy
   void computePotentialEnergy(ElementType el_type,
                               GhostType ghost_type = _not_ghost) override;
 
   /// compute the tangent stiffness matrix for an element type
   void computeTangentModuli(const ElementType & el_type,
                             Array<Real> & tangent_matrix,
                             GhostType ghost_type = _not_ghost) override;
 
   /// compute the p-wave speed in the material
   Real getPushWaveSpeed(const Element & element) const override;
 
   /// compute the s-wave speed in the material
   Real getShearWaveSpeed(const Element & element) const override;
 
 protected:
   /// constitutive law for a given quadrature point
   inline void computePiolaKirchhoffOnQuad(const Matrix<Real> & E,
                                           Matrix<Real> & S);
 
   /// constitutive law for a given quadrature point (first piola)
   inline void computeFirstPiolaKirchhoffOnQuad(const Matrix<Real> & grad_u,
                                                const Matrix<Real> & S,
                                                Matrix<Real> & P);
 
   /// constitutive law for a given quadrature point
   inline void computeDeltaStressOnQuad(const Matrix<Real> & grad_u,
                                        const Matrix<Real> & grad_delta_u,
                                        Matrix<Real> & delta_S);
 
   /// constitutive law for a given quadrature point
   inline void computeStressOnQuad(Matrix<Real> & grad_u, Matrix<Real> & S,
                                   const Real & C33 = 1.0);
 
   /// constitutive law for a given quadrature point
   inline void computeThirdAxisDeformationOnQuad(Matrix<Real> & grad_u,
                                                 Real & c33_value);
 
   /// constitutive law for a given quadrature point
   // inline void updateStressOnQuad(const Matrix<Real> & sigma,
   //                              Matrix<Real> & cauchy_sigma);
 
   /// compute the potential energy for a quadrature point
   inline void computePotentialEnergyOnQuad(const Matrix<Real> & grad_u,
                                            Real & epot);
 
   /// compute the tangent stiffness matrix for an element
   void computeTangentModuliOnQuad(Matrix<Real> & tangent, Matrix<Real> & grad_u,
                                   const Real & C33 = 1.0);
 
   /// recompute the lame coefficient if E or nu changes
   void updateInternalParameters() override;
 
   /* ------------------------------------------------------------------------ */
   /* Accessors                                                                */
   /* ------------------------------------------------------------------------ */
 public:
   /* ------------------------------------------------------------------------ */
   /* Class Members                                                            */
   /* ------------------------------------------------------------------------ */
 protected:
   /// the young modulus
   Real E;
 
   /// Poisson coefficient
   Real nu;
 
   /// First Lamé coefficient
   Real lambda;
 
   /// Second Lamé coefficient (shear modulus)
   Real mu;
 
   /// Bulk modulus
   Real kpa;
 };
 
 /* -------------------------------------------------------------------------- */
 /* inline functions                                                           */
 /* -------------------------------------------------------------------------- */
 
 #include "material_neohookean_inline_impl.cc"
 
 } // akantu
 
 #endif /* __AKANTU_MATERIAL_NEOHOOKEAN_HH__ */
diff --git a/src/model/solid_mechanics/materials/material_finite_deformation/material_neohookean_inline_impl.cc b/src/model/solid_mechanics/materials/material_finite_deformation/material_neohookean_inline_impl.cc
index b99d4e14f..c46c352bb 100644
--- a/src/model/solid_mechanics/materials/material_finite_deformation/material_neohookean_inline_impl.cc
+++ b/src/model/solid_mechanics/materials/material_finite_deformation/material_neohookean_inline_impl.cc
@@ -1,191 +1,191 @@
 /**
  * @file   material_neohookean_inline_impl.cc
  *
  * @author Daniel Pino Muñoz <daniel.pinomunoz@epfl.ch>
  *
  * @date creation: Mon Apr 08 2013
- * @date last modification: Sun Oct 19 2014
+ * @date last modification: Wed Nov 08 2017
  *
  * @brief  Implementation of the inline functions of the material elastic
  *
  * @section LICENSE
  *
- * Copyright  (©)  2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de Lausanne)
+ * 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
+ * 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
+ * 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 <iostream>
 
 #include "material_neohookean.hh"
 #include <cmath>
 #include <utility>
 
 /* -------------------------------------------------------------------------- */
 template <UInt dim>
 inline void MaterialNeohookean<dim>::computeDeltaStressOnQuad(
     __attribute__((unused)) const Matrix<Real> & grad_u,
     __attribute__((unused)) const Matrix<Real> & grad_delta_u,
     __attribute__((unused)) Matrix<Real> & delta_S) {}
 
 //! computes the second piola kirchhoff stress, called S
 template <UInt dim>
 inline void MaterialNeohookean<dim>::computeStressOnQuad(Matrix<Real> & grad_u,
                                                          Matrix<Real> & S,
                                                          const Real & C33) {
   // Neo hookean book
   Matrix<Real> F(dim, dim);
   Matrix<Real> C(dim, dim);      // Right green
   Matrix<Real> Cminus(dim, dim); // Right green
 
   this->template gradUToF<dim>(grad_u, F);
   this->rightCauchy(F, C);
   Real J = F.det() * sqrt(C33); // the term  sqrt(C33) corresponds to the off
                                 // plane strain (2D plane stress)
   //  std::cout<<"det(F) -> "<<J<<std::endl;
   Cminus.inverse(C);
 
   for (UInt i = 0; i < dim; ++i)
     for (UInt j = 0; j < dim; ++j)
       S(i, j) = (i == j) * mu + (lambda * log(J) - mu) * Cminus(i, j);
 }
 
 /* -------------------------------------------------------------------------- */
 class C33_NR : public Math::NewtonRaphsonFunctor {
 public:
   C33_NR(std::string name, const Real & lambda, const Real & mu,
          const Matrix<Real> & C)
       : NewtonRaphsonFunctor(std::move(name)), lambda(lambda), mu(mu), C(C) {}
 
   inline Real f(Real x) const override {
     return (this->lambda / 2. *
                 (std::log(x) + std::log(this->C(0, 0) * this->C(1, 1) -
                                         Math::pow<2>(this->C(0, 1)))) +
             this->mu * (x - 1.));
   }
 
   inline Real f_prime(Real x) const override {
     AKANTU_DEBUG_ASSERT(std::abs(x) > Math::getTolerance(),
                         "x is zero (x should be the off plane right Cauchy"
                             << " measure in this function so you made a mistake"
                             << " somewhere else that lead to a zero here!!!");
     return (this->lambda / (2. * x) + this->mu);
   }
 
 private:
   const Real & lambda;
   const Real & mu;
   const Matrix<Real> & C;
 };
 
 /* -------------------------------------------------------------------------- */
 template <UInt dim>
 inline void MaterialNeohookean<dim>::computeThirdAxisDeformationOnQuad(
     Matrix<Real> & grad_u, Real & c33_value) {
   // Neo hookean book
   Matrix<Real> F(dim, dim);
   Matrix<Real> C(dim, dim); // Right green
 
   this->template gradUToF<dim>(grad_u, F);
   this->rightCauchy(F, C);
 
   Math::NewtonRaphson nr(1e-5, 100);
   c33_value = nr.solve(
       C33_NR("Neohookean_plan_stress", this->lambda, this->mu, C), c33_value);
 }
 
 /* -------------------------------------------------------------------------- */
 template <UInt dim>
 inline void
 MaterialNeohookean<dim>::computePiolaKirchhoffOnQuad(const Matrix<Real> & E,
                                                      Matrix<Real> & S) {
 
   Real trace = E.trace(); /// trace = (\nabla u)_{kk}
 
   /// \sigma_{ij} = \lambda * (\nabla u)_{kk} * \delta_{ij} + \mu * (\nabla
   /// u_{ij} + \nabla u_{ji})
   for (UInt i = 0; i < dim; ++i)
     for (UInt j = 0; j < dim; ++j)
       S(i, j) = (i == j) * lambda * trace + 2.0 * mu * E(i, j);
 }
 
 /* -------------------------------------------------------------------------- */
 template <UInt dim>
 inline void MaterialNeohookean<dim>::computeFirstPiolaKirchhoffOnQuad(
     const Matrix<Real> & grad_u, const Matrix<Real> & S, Matrix<Real> & P) {
 
   Matrix<Real> F(dim, dim);
   Matrix<Real> C(dim, dim); // Right green
 
   this->template gradUToF<dim>(grad_u, F);
 
   // first Piola-Kirchhoff is computed as the product of the deformation
   // gracient
   // tensor and the second Piola-Kirchhoff stress tensor
 
   P = F * S;
 }
 
 /**************************************************************************************/
 /*  Computation of the potential energy for a this neo hookean material */
 template <UInt dim>
 inline void MaterialNeohookean<dim>::computePotentialEnergyOnQuad(
     const Matrix<Real> & grad_u, Real & epot) {
   Matrix<Real> F(dim, dim);
   Matrix<Real> C(dim, dim); // Right green
 
   this->template gradUToF<dim>(grad_u, F);
   this->rightCauchy(F, C);
   Real J = F.det();
   //  std::cout<<"det(F) -> "<<J<<std::endl;
 
   epot =
       0.5 * lambda * pow(log(J), 2.) + mu * (-log(J) + 0.5 * (C.trace() - dim));
 }
 
 /* -------------------------------------------------------------------------- */
 template <UInt dim>
 inline void MaterialNeohookean<dim>::computeTangentModuliOnQuad(
     Matrix<Real> & tangent, Matrix<Real> & grad_u, const Real & C33) {
 
   // Neo hookean book
   UInt cols = tangent.cols();
   UInt rows = tangent.rows();
   Matrix<Real> F(dim, dim);
   Matrix<Real> C(dim, dim);
   Matrix<Real> Cminus(dim, dim);
   this->template gradUToF<dim>(grad_u, F);
   this->rightCauchy(F, C);
   Real J = F.det() * sqrt(C33);
   //  std::cout<<"det(F) -> "<<J<<std::endl;
   Cminus.inverse(C);
 
   for (UInt m = 0; m < rows; m++) {
     UInt i = VoigtHelper<dim>::vec[m][0];
     UInt j = VoigtHelper<dim>::vec[m][1];
     for (UInt n = 0; n < cols; n++) {
       UInt k = VoigtHelper<dim>::vec[n][0];
       UInt l = VoigtHelper<dim>::vec[n][1];
 
       // book belytchko
       tangent(m, n) = lambda * Cminus(i, j) * Cminus(k, l) +
                       (mu - lambda * log(J)) * (Cminus(i, k) * Cminus(j, l) +
                                                 Cminus(i, l) * Cminus(k, j));
     }
   }
 }
 
 /* -------------------------------------------------------------------------- */
diff --git a/src/model/solid_mechanics/materials/material_non_local.hh b/src/model/solid_mechanics/materials/material_non_local.hh
index acff2d771..763a06ae4 100644
--- a/src/model/solid_mechanics/materials/material_non_local.hh
+++ b/src/model/solid_mechanics/materials/material_non_local.hh
@@ -1,120 +1,119 @@
 /**
  * @file   material_non_local.hh
  *
  * @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Fri Jun 18 2010
- * @date last modification: Tue Dec 08 2015
+ * @date last modification: Mon Sep 11 2017
  *
  * @brief  Material class that handle the non locality of a law for example
  * damage.
  *
  * @section LICENSE
  *
- * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
- * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
- * Solides)
+ * 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
+ * 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
+ * A PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 #include "material.hh"
 /* -------------------------------------------------------------------------- */
 
 #ifndef __AKANTU_MATERIAL_NON_LOCAL_HH__
 #define __AKANTU_MATERIAL_NON_LOCAL_HH__
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 class MaterialNonLocalInterface {
   /* ------------------------------------------------------------------------ */
   /* Methods                                                                  */
   /* ------------------------------------------------------------------------ */
 public:
   /// initialize the material the non local parts of the material
   void initMaterialNonLocal() {
     this->registerNeighborhood();
     this->registerNonLocalVariables();
   };
 
   /// insert the quadrature points in the neighborhoods of the non-local manager
   virtual void insertIntegrationPointsInNeighborhoods(
       const GhostType & ghost_type,
       const ElementTypeMapReal & quadrature_points_coordinates) = 0;
 
   /// update the values in the non-local internal fields
   virtual void updateNonLocalInternals(ElementTypeMapReal & non_local_flattened,
                                        const ID & field_id,
                                        const GhostType & ghost_type,
                                        const ElementKind & kind) = 0;
   /// constitutive law
   virtual void computeNonLocalStresses(GhostType ghost_type = _not_ghost) = 0;
 
 protected:
   /// get the name of the neighborhood for this material
   virtual ID getNeighborhoodName() = 0;
 
   /// register the neighborhoods for the material
   virtual void registerNeighborhood() = 0;
 
   /// register the non local internal variable
   virtual void registerNonLocalVariables() = 0;
 
   virtual inline void onElementsAdded(const Array<Element> &,
                                       const NewElementsEvent &) {}
 };
 /* -------------------------------------------------------------------------- */
 
 /* -------------------------------------------------------------------------- */
 template <UInt dim, class LocalParent>
 class MaterialNonLocal : public MaterialNonLocalInterface, public LocalParent {
   /* ------------------------------------------------------------------------ */
   /* Constructors/Destructors                                                 */
   /* ------------------------------------------------------------------------ */
 public:
   explicit MaterialNonLocal(SolidMechanicsModel & model, const ID & id);
 
   /* ------------------------------------------------------------------------ */
   /* Methods                                                                  */
   /* ------------------------------------------------------------------------ */
 public:
   /// insert the quadrature points in the neighborhoods of the non-local manager
   void insertIntegrationPointsInNeighborhoods(
       const GhostType & ghost_type,
       const ElementTypeMapReal & quadrature_points_coordinates) override;
 
   /// update the values in the non-local internal fields
   void updateNonLocalInternals(ElementTypeMapReal & non_local_flattened,
                                const ID & field_id,
                                const GhostType & ghost_type,
                                const ElementKind & kind) override;
 
   /// register the neighborhoods for the material
   void registerNeighborhood() override;
 
 protected:
   /// get the name of the neighborhood for this material
   ID getNeighborhoodName() override { return this->name; }
 };
 
 } // namespace akantu
 
 /* -------------------------------------------------------------------------- */
 #include "material_non_local_tmpl.hh"
 
 #endif /* __AKANTU_MATERIAL_NON_LOCAL_HH__ */
diff --git a/src/model/solid_mechanics/materials/material_non_local_includes.hh b/src/model/solid_mechanics/materials/material_non_local_includes.hh
index d3b20179f..4a0c657be 100644
--- a/src/model/solid_mechanics/materials/material_non_local_includes.hh
+++ b/src/model/solid_mechanics/materials/material_non_local_includes.hh
@@ -1,40 +1,39 @@
 /**
  * @file   material_non_local_includes.hh
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Wed Oct 31 2012
- * @date last modification: Wed Nov 18 2015
+ * @date last modification: Thu Jul 06 2017
  *
  * @brief  Non local materials includes
  *
  * @section LICENSE
  *
- * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
- * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
- * Solides)
+ * 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
+ * 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
+ * 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_CMAKE_LIST_MATERIALS
 #include "material_marigo_non_local.hh"
 #include "material_mazars_non_local.hh"
 #endif
 
 #define AKANTU_DAMAGE_NON_LOCAL_MATERIAL_LIST                                  \
   ((2, (marigo_non_local, MaterialMarigoNonLocal)))(                           \
       (2, (mazars_non_local, MaterialMazarsNonLocal)))
diff --git a/src/model/solid_mechanics/materials/material_non_local_tmpl.hh b/src/model/solid_mechanics/materials/material_non_local_tmpl.hh
index ccfd93508..de6046f3c 100644
--- a/src/model/solid_mechanics/materials/material_non_local_tmpl.hh
+++ b/src/model/solid_mechanics/materials/material_non_local_tmpl.hh
@@ -1,128 +1,128 @@
 /**
- * @file   material_non_local.cc
+ * @file   material_non_local_tmpl.hh
  *
  * @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
- * @date creation: Sat Sep 26 2015
- * @date last modification: Tue Dec 08 2015
+ * @date creation: Thu Jul 06 2017
+ * @date last modification: Tue Nov 07 2017
  *
  * @brief  Implementation of material non-local
  *
  * @section LICENSE
  *
- * Copyright (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne) Laboratory
- * (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * 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
+ * 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
+ * A PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 #include "material.hh"
 #include "material_non_local.hh"
 #include "non_local_neighborhood.hh"
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 template <UInt dim, class LocalParent>
 MaterialNonLocal<dim, LocalParent>::MaterialNonLocal(
     SolidMechanicsModel & model, const ID & id)
     : LocalParent(model, id) {
   AKANTU_DEBUG_IN();
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <UInt dim, class LocalParent>
 void MaterialNonLocal<dim, LocalParent>::insertIntegrationPointsInNeighborhoods(
     const GhostType & ghost_type,
     const ElementTypeMapReal & quadrature_points_coordinates) {
 
   IntegrationPoint q;
   q.ghost_type = ghost_type;
 
   auto & neighborhood = this->model.getNonLocalManager().getNeighborhood(
       this->getNeighborhoodName());
 
   for (auto & type :
        this->element_filter.elementTypes(dim, ghost_type, _ek_regular)) {
     q.type = type;
     const auto & elem_filter = this->element_filter(type, ghost_type);
     UInt nb_element = elem_filter.size();
 
     if (nb_element) {
       UInt nb_quad =
           this->getFEEngine().getNbIntegrationPoints(type, ghost_type);
 
       const auto & quads = quadrature_points_coordinates(type, ghost_type);
 
       auto nb_total_element =
           this->model.getMesh().getNbElement(type, ghost_type);
       auto quads_it = quads.begin_reinterpret(dim, nb_quad, nb_total_element);
       for (auto & elem : elem_filter) {
         Matrix<Real> quads = quads_it[elem];
         q.element = elem;
         for (UInt nq = 0; nq < nb_quad; ++nq) {
           q.num_point = nq;
           q.global_num = q.element * nb_quad + nq;
           neighborhood.insertIntegrationPoint(q, quads(nq));
         }
       }
     }
   }
 }
 
 /* -------------------------------------------------------------------------- */
 template <UInt dim, class LocalParent>
 void MaterialNonLocal<dim, LocalParent>::updateNonLocalInternals(
     ElementTypeMapReal & non_local_flattened, const ID & field_id,
     const GhostType & ghost_type, const ElementKind & kind) {
 
   /// loop over all types in the material
   for (auto & el_type :
        this->element_filter.elementTypes(dim, ghost_type, kind)) {
     Array<Real> & internal =
         this->template getInternal<Real>(field_id)(el_type, ghost_type);
 
     auto & internal_flat = non_local_flattened(el_type, ghost_type);
     auto nb_component = internal_flat.getNbComponent();
 
     auto internal_it = internal.begin(nb_component);
     auto internal_flat_it = internal_flat.begin(nb_component);
 
     /// loop all elements for the given type
     const auto & filter = this->element_filter(el_type, ghost_type);
     UInt nb_quads =
         this->getFEEngine().getNbIntegrationPoints(el_type, ghost_type);
     for (auto & elem : filter) {
       for (UInt q = 0; q < nb_quads; ++q, ++internal_it) {
         UInt global_quad = elem * nb_quads + q;
         *internal_it = internal_flat_it[global_quad];
       }
     }
   }
 }
 
 /* -------------------------------------------------------------------------- */
 template <UInt dim, class LocalParent>
 void MaterialNonLocal<dim, LocalParent>::registerNeighborhood() {
   ID name = this->getNeighborhoodName();
   this->model.getNonLocalManager().registerNeighborhood(name, name);
 }
 
 } // namespace akantu
diff --git a/src/model/solid_mechanics/materials/material_plastic/material_linear_isotropic_hardening.cc b/src/model/solid_mechanics/materials/material_plastic/material_linear_isotropic_hardening.cc
index d5db9fa1a..0e287d59c 100644
--- a/src/model/solid_mechanics/materials/material_plastic/material_linear_isotropic_hardening.cc
+++ b/src/model/solid_mechanics/materials/material_plastic/material_linear_isotropic_hardening.cc
@@ -1,201 +1,202 @@
 /**
  * @file   material_linear_isotropic_hardening.cc
  *
  * @author Ramin Aghababaei <ramin.aghababaei@epfl.ch>
+ * @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
  * @author Lucas Frerot <lucas.frerot@epfl.ch>
  * @author Benjamin Paccaud <benjamin.paccaud@epfl.ch>
  * @author Daniel Pino Muñoz <daniel.pinomunoz@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Mon Apr 07 2014
- * @date last modification: Tue Aug 18 2015
+ * @date last modification: Sat Dec 02 2017
  *
  * @brief  Specialization of the material class for isotropic finite deformation
  * linear hardening plasticity
  *
  * @section LICENSE
  *
- * Copyright  (©)  2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de Lausanne)
+ * 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
+ * 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
+ * A PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 #include "material_linear_isotropic_hardening.hh"
 #include "solid_mechanics_model.hh"
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 template <UInt dim>
 MaterialLinearIsotropicHardening<dim>::MaterialLinearIsotropicHardening(
     SolidMechanicsModel & model, const ID & id)
     : MaterialPlastic<dim>(model, id) {
   AKANTU_DEBUG_IN();
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <UInt spatial_dimension>
 MaterialLinearIsotropicHardening<spatial_dimension>::
     MaterialLinearIsotropicHardening(SolidMechanicsModel & model, UInt dim,
                                      const Mesh & mesh, FEEngine & fe_engine,
                                      const ID & id)
     : MaterialPlastic<spatial_dimension>(model, dim, mesh, fe_engine, id) {}
 
 /* -------------------------------------------------------------------------- */
 template <UInt spatial_dimension>
 void MaterialLinearIsotropicHardening<spatial_dimension>::computeStress(
     ElementType el_type, GhostType ghost_type) {
   AKANTU_DEBUG_IN();
 
   MaterialThermal<spatial_dimension>::computeStress(el_type, ghost_type);
   // infinitesimal and finite deformation
   auto sigma_th_it = this->sigma_th(el_type, ghost_type).begin();
 
   auto previous_sigma_th_it =
       this->sigma_th.previous(el_type, ghost_type).begin();
 
   auto previous_gradu_it = this->gradu.previous(el_type, ghost_type)
                                .begin(spatial_dimension, spatial_dimension);
 
   auto previous_stress_it = this->stress.previous(el_type, ghost_type)
                                 .begin(spatial_dimension, spatial_dimension);
 
   auto inelastic_strain_it = this->inelastic_strain(el_type, ghost_type)
                                  .begin(spatial_dimension, spatial_dimension);
 
   auto previous_inelastic_strain_it =
       this->inelastic_strain.previous(el_type, ghost_type)
           .begin(spatial_dimension, spatial_dimension);
 
   auto iso_hardening_it = this->iso_hardening(el_type, ghost_type).begin();
 
   auto previous_iso_hardening_it =
       this->iso_hardening.previous(el_type, ghost_type).begin();
 
   //
   // Finite Deformations
   //
   if (this->finite_deformation) {
     auto previous_piola_kirchhoff_2_it =
         this->piola_kirchhoff_2.previous(el_type, ghost_type)
             .begin(spatial_dimension, spatial_dimension);
 
     auto green_strain_it = this->green_strain(el_type, ghost_type)
                                .begin(spatial_dimension, spatial_dimension);
 
     MATERIAL_STRESS_QUADRATURE_POINT_LOOP_BEGIN(el_type, ghost_type);
 
     auto & inelastic_strain_tensor = *inelastic_strain_it;
     auto & previous_inelastic_strain_tensor = *previous_inelastic_strain_it;
     auto & previous_grad_u = *previous_gradu_it;
     auto & previous_sigma = *previous_piola_kirchhoff_2_it;
 
     auto & green_strain = *green_strain_it;
     this->template gradUToGreenStrain<spatial_dimension>(grad_u, green_strain);
     Matrix<Real> previous_green_strain(spatial_dimension, spatial_dimension);
     this->template gradUToGreenStrain<spatial_dimension>(previous_grad_u,
                                                          previous_green_strain);
     Matrix<Real> F_tensor(spatial_dimension, spatial_dimension);
     this->template gradUToF<spatial_dimension>(grad_u, F_tensor);
 
     computeStressOnQuad(green_strain, previous_green_strain, sigma,
                         previous_sigma, inelastic_strain_tensor,
                         previous_inelastic_strain_tensor, *iso_hardening_it,
                         *previous_iso_hardening_it, *sigma_th_it,
                         *previous_sigma_th_it, F_tensor);
 
     ++sigma_th_it;
     ++inelastic_strain_it;
     ++iso_hardening_it;
     ++previous_sigma_th_it;
     //++previous_stress_it;
     ++previous_gradu_it;
     ++green_strain_it;
     ++previous_inelastic_strain_it;
     ++previous_iso_hardening_it;
     ++previous_piola_kirchhoff_2_it;
 
     MATERIAL_STRESS_QUADRATURE_POINT_LOOP_END;
 
   }
   // Infinitesimal deformations
   else {
     MATERIAL_STRESS_QUADRATURE_POINT_LOOP_BEGIN(el_type, ghost_type);
 
     auto & inelastic_strain_tensor = *inelastic_strain_it;
     auto & previous_inelastic_strain_tensor = *previous_inelastic_strain_it;
     auto & previous_grad_u = *previous_gradu_it;
     auto & previous_sigma = *previous_stress_it;
 
     computeStressOnQuad(
         grad_u, previous_grad_u, sigma, previous_sigma, inelastic_strain_tensor,
         previous_inelastic_strain_tensor, *iso_hardening_it,
         *previous_iso_hardening_it, *sigma_th_it, *previous_sigma_th_it);
     ++sigma_th_it;
     ++inelastic_strain_it;
     ++iso_hardening_it;
     ++previous_sigma_th_it;
     ++previous_stress_it;
     ++previous_gradu_it;
     ++previous_inelastic_strain_it;
     ++previous_iso_hardening_it;
 
     MATERIAL_STRESS_QUADRATURE_POINT_LOOP_END;
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <UInt spatial_dimension>
 void MaterialLinearIsotropicHardening<spatial_dimension>::computeTangentModuli(
     const ElementType & el_type, Array<Real> & tangent_matrix,
     GhostType ghost_type) {
   AKANTU_DEBUG_IN();
 
   auto previous_gradu_it = this->gradu.previous(el_type, ghost_type)
                                .begin(spatial_dimension, spatial_dimension);
 
   auto previous_stress_it = this->stress.previous(el_type, ghost_type)
                                 .begin(spatial_dimension, spatial_dimension);
 
   auto iso_hardening = this->iso_hardening(el_type, ghost_type).begin();
 
   MATERIAL_TANGENT_QUADRATURE_POINT_LOOP_BEGIN(tangent_matrix);
 
   computeTangentModuliOnQuad(tangent, grad_u, *previous_gradu_it, sigma_tensor,
                              *previous_stress_it, *iso_hardening);
 
   ++previous_gradu_it;
   ++previous_stress_it;
   ++iso_hardening;
 
   MATERIAL_TANGENT_QUADRATURE_POINT_LOOP_END;
 
   this->was_stiffness_assembled = true;
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 
 INSTANTIATE_MATERIAL(plastic_linear_isotropic_hardening,
                      MaterialLinearIsotropicHardening);
 
 } // akantu
diff --git a/src/model/solid_mechanics/materials/material_plastic/material_linear_isotropic_hardening.hh b/src/model/solid_mechanics/materials/material_plastic/material_linear_isotropic_hardening.hh
index 78aa000cd..dea48f6b9 100644
--- a/src/model/solid_mechanics/materials/material_plastic/material_linear_isotropic_hardening.hh
+++ b/src/model/solid_mechanics/materials/material_plastic/material_linear_isotropic_hardening.hh
@@ -1,113 +1,113 @@
 /**
  * @file   material_linear_isotropic_hardening.hh
  *
  * @author Ramin Aghababaei <ramin.aghababaei@epfl.ch>
+ * @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
  * @author Lucas Frerot <lucas.frerot@epfl.ch>
  * @author Benjamin Paccaud <benjamin.paccaud@epfl.ch>
  * @author Daniel Pino Muñoz <daniel.pinomunoz@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Fri Jun 18 2010
- * @date last modification: Mon Jun 01 2015
+ * @date last modification: Sat Dec 02 2017
  *
  * @brief  Specialization of the material class for isotropic finite deformation
  * linear hardening plasticity
  *
  * @section LICENSE
  *
- * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
- * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
- * Solides)
+ * 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
+ * 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
+ * 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 "aka_voigthelper.hh"
 #include "material_plastic.hh"
 /* -------------------------------------------------------------------------- */
 
 #ifndef __AKANTU_MATERIAL_LINEAR_ISOTROPIC_HARDENING_HH__
 #define __AKANTU_MATERIAL_LINEAR_ISOTROPIC_HARDENING_HH__
 
 namespace akantu {
 
 /**
  * Material plastic with a linear evolution of the yielding stress
  */
 template <UInt spatial_dimension>
 class MaterialLinearIsotropicHardening
     : public MaterialPlastic<spatial_dimension> {
   /* ------------------------------------------------------------------------ */
   /* Constructors/Destructors                                                 */
   /* ------------------------------------------------------------------------ */
 public:
   MaterialLinearIsotropicHardening(SolidMechanicsModel & model,
                                    const ID & id = "");
   MaterialLinearIsotropicHardening(SolidMechanicsModel & model, UInt dim,
                                    const Mesh & mesh, FEEngine & fe_engine,
                                    const ID & id = "");
 
   /* ------------------------------------------------------------------------ */
   /* Methods                                                                  */
   /* ------------------------------------------------------------------------ */
 public:
   /// constitutive law for all element of a type
   void computeStress(ElementType el_type,
                      GhostType ghost_type = _not_ghost) override;
 
   /// compute the tangent stiffness matrix for an element type
   void computeTangentModuli(const ElementType & el_type,
                             Array<Real> & tangent_matrix,
                             GhostType ghost_type = _not_ghost) override;
 
 protected:
   /// Infinitesimal deformations
   inline void computeStressOnQuad(
       const Matrix<Real> & grad_u, const Matrix<Real> & previous_grad_u,
       Matrix<Real> & sigma, const Matrix<Real> & previous_sigma,
       Matrix<Real> & inelas_strain, const Matrix<Real> & previous_inelas_strain,
       Real & iso_hardening, const Real & previous_iso_hardening,
       const Real & sigma_th, const Real & previous_sigma_th);
   /// Finite deformations
   inline void computeStressOnQuad(
       const Matrix<Real> & grad_u, const Matrix<Real> & previous_grad_u,
       Matrix<Real> & sigma, const Matrix<Real> & previous_sigma,
       Matrix<Real> & inelas_strain, const Matrix<Real> & previous_inelas_strain,
       Real & iso_hardening, const Real & previous_iso_hardening,
       const Real & sigma_th, const Real & previous_sigma_th,
       const Matrix<Real> & F_tensor);
 
   inline void computeTangentModuliOnQuad(
       Matrix<Real> & tangent, const Matrix<Real> & grad_u,
       const Matrix<Real> & previous_grad_u, const Matrix<Real> & sigma_tensor,
       const Matrix<Real> & previous_sigma_tensor,
       const Real & iso_hardening) const;
 
   /* ------------------------------------------------------------------------ */
   /* Class Members                                                            */
   /* ------------------------------------------------------------------------ */
 private:
 };
 /* -------------------------------------------------------------------------- */
 /* inline functions                                                           */
 /* -------------------------------------------------------------------------- */
 
 } // akantu
 
 #include "material_linear_isotropic_hardening_inline_impl.cc"
 
 #endif /* __AKANTU_MATERIAL_LINEAR_ISOTROPIC_HARDENING_HH__ */
diff --git a/src/model/solid_mechanics/materials/material_plastic/material_linear_isotropic_hardening_inline_impl.cc b/src/model/solid_mechanics/materials/material_plastic/material_linear_isotropic_hardening_inline_impl.cc
index 8fb7dbff4..06bb421f4 100644
--- a/src/model/solid_mechanics/materials/material_plastic/material_linear_isotropic_hardening_inline_impl.cc
+++ b/src/model/solid_mechanics/materials/material_plastic/material_linear_isotropic_hardening_inline_impl.cc
@@ -1,297 +1,298 @@
 /**
  * @file   material_linear_isotropic_hardening_inline_impl.cc
  *
  * @author Ramin Aghababaei <ramin.aghababaei@epfl.ch>
+ * @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
  * @author Lucas Frerot <lucas.frerot@epfl.ch>
  * @author Benjamin Paccaud <benjamin.paccaud@epfl.ch>
  * @author Daniel Pino Muñoz <daniel.pinomunoz@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Mon Apr 07 2014
- * @date last modification: Fri May 29 2015
+ * @date last modification: Thu Nov 30 2017
  *
  * @brief  Implementation of the inline functions of the material plasticity
  *
  * @section LICENSE
  *
- * Copyright  (©)  2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de Lausanne)
+ * 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
+ * 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
+ * A PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 #include "material_linear_isotropic_hardening.hh"
 
 namespace akantu {
 /* -------------------------------------------------------------------------- */
 
 /* -------------------------------------------------------------------------- */
 /// Infinitesimal deformations
 template <UInt dim>
 inline void MaterialLinearIsotropicHardening<dim>::computeStressOnQuad(
     const Matrix<Real> & grad_u, const Matrix<Real> & previous_grad_u,
     Matrix<Real> & sigma, const Matrix<Real> & previous_sigma,
     Matrix<Real> & inelastic_strain,
     const Matrix<Real> & previous_inelastic_strain, Real & iso_hardening,
     const Real & previous_iso_hardening, const Real & sigma_th,
     const Real & previous_sigma_th) {
 
   Real delta_sigma_th = sigma_th - previous_sigma_th;
 
   Matrix<Real> grad_delta_u(grad_u);
   grad_delta_u -= previous_grad_u;
 
   // Compute trial stress, sigma_tr
   Matrix<Real> sigma_tr(dim, dim);
   MaterialElastic<dim>::computeStressOnQuad(grad_delta_u, sigma_tr,
                                             delta_sigma_th);
   sigma_tr += previous_sigma;
 
   // We need a full stress tensor, otherwise the VM stress is messed up
   Matrix<Real> sigma_tr_dev(3, 3, 0);
   for (UInt i = 0; i < dim; ++i)
     for (UInt j = 0; j < dim; ++j)
       sigma_tr_dev(i, j) = sigma_tr(i, j);
 
   sigma_tr_dev -= Matrix<Real>::eye(3, sigma_tr.trace() / 3.0);
 
   // Compute effective deviatoric trial stress
   Real s = sigma_tr_dev.doubleDot(sigma_tr_dev);
   Real sigma_tr_dev_eff = std::sqrt(3. / 2. * s);
 
   bool initial_yielding =
       ((sigma_tr_dev_eff - iso_hardening - this->sigma_y) > 0);
 
   Real dp = (initial_yielding)
                 ? (sigma_tr_dev_eff - this->sigma_y - previous_iso_hardening) /
                       (3 * this->mu + this->h)
                 : 0;
 
   iso_hardening = previous_iso_hardening + this->h * dp;
 
   // Compute inelastic strain (ignore last components in 1-2D)
   Matrix<Real> delta_inelastic_strain(dim, dim, 0.);
   if (std::abs(sigma_tr_dev_eff) >
       sigma_tr_dev.norm<L_inf>() * Math::getTolerance()) {
     for (UInt i = 0; i < dim; ++i)
       for (UInt j = 0; j < dim; ++j)
         delta_inelastic_strain(i, j) = sigma_tr_dev(i, j);
     delta_inelastic_strain *= 3. / 2. * dp / sigma_tr_dev_eff;
   }
 
   MaterialPlastic<dim>::computeStressAndInelasticStrainOnQuad(
       grad_delta_u, sigma, previous_sigma, inelastic_strain,
       previous_inelastic_strain, delta_inelastic_strain);
 }
 
 /* -------------------------------------------------------------------------- */
 /// Finite deformations
 template <UInt dim>
 inline void MaterialLinearIsotropicHardening<dim>::computeStressOnQuad(
     const Matrix<Real> & grad_u, const Matrix<Real> & previous_grad_u,
     Matrix<Real> & sigma, const Matrix<Real> & previous_sigma,
     Matrix<Real> & inelastic_strain,
     const Matrix<Real> & previous_inelastic_strain, Real & iso_hardening,
     const Real & previous_iso_hardening, const Real & sigma_th,
     const Real & previous_sigma_th, const Matrix<Real> & F_tensor) {
   // Finite plasticity
   Real dp = 0.0;
   Real d_dp = 0.0;
   UInt n = 0;
 
   Real delta_sigma_th = sigma_th - previous_sigma_th;
 
   Matrix<Real> grad_delta_u(grad_u);
   grad_delta_u -= previous_grad_u;
 
   // Compute trial stress, sigma_tr
   Matrix<Real> sigma_tr(dim, dim);
   MaterialElastic<dim>::computeStressOnQuad(grad_delta_u, sigma_tr,
                                             delta_sigma_th);
   sigma_tr += previous_sigma;
 
   // Compute deviatoric trial stress,  sigma_tr_dev
   Matrix<Real> sigma_tr_dev(sigma_tr);
   sigma_tr_dev -= Matrix<Real>::eye(dim, sigma_tr.trace() / 3.0);
 
   // Compute effective deviatoric trial stress
   Real s = sigma_tr_dev.doubleDot(sigma_tr_dev);
   Real sigma_tr_dev_eff = std::sqrt(3. / 2. * s);
 
   // compute the cauchy stress to apply the Von-Mises criterion
   Matrix<Real> cauchy_stress(dim, dim);
   Material::computeCauchyStressOnQuad<dim>(F_tensor, sigma_tr, cauchy_stress);
   Matrix<Real> cauchy_stress_dev(cauchy_stress);
   cauchy_stress_dev -= Matrix<Real>::eye(dim, cauchy_stress.trace() / 3.0);
   Real c = cauchy_stress_dev.doubleDot(cauchy_stress_dev);
   Real cauchy_stress_dev_eff = std::sqrt(3. / 2. * c);
 
   const Real iso_hardening_t = previous_iso_hardening;
   iso_hardening = iso_hardening_t;
   // Loop for correcting stress based on yield function
 
   // F is written in terms of S
   // bool initial_yielding = ( (sigma_tr_dev_eff - iso_hardening -
   // this->sigma_y) > 0) ;
   // while ( initial_yielding && std::abs(sigma_tr_dev_eff - iso_hardening -
   // this->sigma_y) > Math::getTolerance() ) {
 
   //   d_dp = (sigma_tr_dev_eff - 3. * this->mu *dp -  iso_hardening -
   //   this->sigma_y)
   //     / (3. * this->mu + this->h);
 
   //   //r = r +  h * dp;
   //   dp = dp + d_dp;
   //   iso_hardening = iso_hardening_t + this->h * dp;
 
   //   ++n;
 
   //   /// TODO : explicit this criterion with an error message
   //   if ((std::abs(d_dp) < 1e-9) || (n>50)){
   //     AKANTU_DEBUG_INFO("convergence of increment of plastic strain. d_dp:"
   //     << d_dp << "\tNumber of iteration:"<<n);
   //     break;
   //   }
   // }
 
   // F is written in terms of cauchy stress
   bool initial_yielding =
       ((cauchy_stress_dev_eff - iso_hardening - this->sigma_y) > 0);
   while (initial_yielding &&
          std::abs(cauchy_stress_dev_eff - iso_hardening - this->sigma_y) >
              Math::getTolerance()) {
 
     d_dp = (cauchy_stress_dev_eff - 3. * this->mu * dp - iso_hardening -
             this->sigma_y) /
            (3. * this->mu + this->h);
 
     // r = r +  h * dp;
     dp = dp + d_dp;
     iso_hardening = iso_hardening_t + this->h * dp;
 
     ++n;
     /// TODO : explicit this criterion with an error message
     if ((d_dp < 1e-5) || (n > 50)) {
       AKANTU_DEBUG_INFO("convergence of increment of plastic strain. d_dp:"
                         << d_dp << "\tNumber of iteration:" << n);
       break;
     }
   }
 
   // Update internal variable
   Matrix<Real> delta_inelastic_strain(dim, dim, 0.);
   if (std::abs(sigma_tr_dev_eff) >
       sigma_tr_dev.norm<L_inf>() * Math::getTolerance()) {
 
     // /// compute the direction of the plastic strain as \frac{\partial
     // F}{\partial S} = \frac{3}{2J\sigma_{effective}}} Ft \sigma_{dev} F
     Matrix<Real> cauchy_dev_F(dim, dim);
     cauchy_dev_F.mul<false, false>(F_tensor, cauchy_stress_dev);
     Real J = F_tensor.det();
     Real constant = J ? 1. / J : 0;
     constant *= 3. * dp / (2. * cauchy_stress_dev_eff);
     delta_inelastic_strain.mul<true, false>(F_tensor, cauchy_dev_F, constant);
 
     // Direction given by the piola kirchhoff deviatoric tensor \frac{\partial
     // F}{\partial S} = \frac{3}{2\sigma_{effective}}}S_{dev}
     // delta_inelastic_strain.copy(sigma_tr_dev);
     // delta_inelastic_strain *= 3./2. * dp / sigma_tr_dev_eff;
   }
 
   MaterialPlastic<dim>::computeStressAndInelasticStrainOnQuad(
       grad_delta_u, sigma, previous_sigma, inelastic_strain,
       previous_inelastic_strain, delta_inelastic_strain);
 }
 
 /* -------------------------------------------------------------------------- */
 
 template <UInt dim>
 inline void MaterialLinearIsotropicHardening<dim>::computeTangentModuliOnQuad(
     Matrix<Real> & tangent, __attribute__((unused)) const Matrix<Real> & grad_u,
     __attribute__((unused)) const Matrix<Real> & previous_grad_u,
     __attribute__((unused)) const Matrix<Real> & sigma_tensor,
     __attribute__((unused)) const Matrix<Real> & previous_sigma_tensor,
     __attribute__((unused)) const Real & iso_hardening) const {
   // Real r=iso_hardening;
 
   // Matrix<Real> grad_delta_u(grad_u);
   // grad_delta_u -= previous_grad_u;
 
   // //Compute trial stress, sigma_tr
   // Matrix<Real> sigma_tr(dim, dim);
   // MaterialElastic<dim>::computeStressOnQuad(grad_delta_u, sigma_tr);
   // sigma_tr += previous_sigma_tensor;
 
   // // Compute deviatoric trial stress,  sigma_tr_dev
   // Matrix<Real> sigma_tr_dev(sigma_tr);
   // sigma_tr_dev -= Matrix<Real>::eye(dim, sigma_tr.trace() / 3.0);
 
   // // Compute effective deviatoric trial stress
   // Real s = sigma_tr_dev.doubleDot(sigma_tr_dev);
   // Real sigma_tr_dev_eff=std::sqrt(3./2. * s);
 
   // // Compute deviatoric stress,  sigma_dev
   // Matrix<Real> sigma_dev(sigma_tensor);
   // sigma_dev -= Matrix<Real>::eye(dim, sigma_tensor.trace() / 3.0);
 
   // // Compute effective deviatoric stress
   // s =  sigma_dev.doubleDot(sigma_dev);
   // Real sigma_dev_eff = std::sqrt(3./2. * s);
 
   // Real xr = 0.0;
   // if(sigma_tr_dev_eff > sigma_dev_eff * Math::getTolerance())
   //   xr = sigma_dev_eff / sigma_tr_dev_eff;
 
   // Real __attribute__((unused)) q = 1.5 * (1. / (1. +  3. * this->mu  /
   // this->h) - xr);
 
   /*
   UInt cols = tangent.cols();
   UInt rows = tangent.rows();
 
   for (UInt m = 0; m < rows; ++m) {
     UInt i = VoigtHelper<dim>::vec[m][0];
     UInt j = VoigtHelper<dim>::vec[m][1];
 
     for (UInt n = 0; n < cols; ++n) {
       UInt k = VoigtHelper<dim>::vec[n][0];
       UInt l = VoigtHelper<dim>::vec[n][1];
       */
 
   // This section of the code is commented
   // There were some problems with the convergence of plastic-coupled
   // simulations with thermal expansion
   // XXX: DO NOT REMOVE
   /*if (((sigma_tr_dev_eff-iso_hardening-sigmay) > 0) && (xr > 0)) {
     tangent(m,n) =
     2. * this->mu * q * (sigma_tr_dev (i,j) / sigma_tr_dev_eff) * (sigma_tr_dev
     (k,l) / sigma_tr_dev_eff) +
     (i==k) * (j==l) * 2. * this->mu * xr +
     (i==j) * (k==l) * (this->kpa - 2./3. * this->mu * xr);
     if ((m == n) && (m>=dim))
     tangent(m, n) = tangent(m, n) - this->mu * xr;
     } else {*/
   /*
   tangent(m,n) =  (i==k) * (j==l) * 2. * this->mu +
     (i==j) * (k==l) * this->lambda;
   tangent(m,n) -= (m==n) * (m>=dim) * this->mu;
   */
   //}
   // correct tangent stiffness for shear component
   //}
   //}
   MaterialElastic<dim>::computeTangentModuliOnQuad(tangent);
 }
 } // akantu
diff --git a/src/model/solid_mechanics/materials/material_plastic/material_plastic.cc b/src/model/solid_mechanics/materials/material_plastic/material_plastic.cc
index bfe07f012..1032eab13 100644
--- a/src/model/solid_mechanics/materials/material_plastic/material_plastic.cc
+++ b/src/model/solid_mechanics/materials/material_plastic/material_plastic.cc
@@ -1,209 +1,209 @@
 /**
  * @file   material_plastic.cc
  *
  * @author Lucas Frerot <lucas.frerot@epfl.ch>
  * @author Daniel Pino Muñoz <daniel.pinomunoz@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Mon Apr 07 2014
- * @date last modification: Tue Aug 18 2015
+ * @date last modification: Sun Dec 03 2017
  *
  * @brief  Implemantation of the akantu::MaterialPlastic class
  *
  * @section LICENSE
  *
- * Copyright  (©)  2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de Lausanne)
+ * 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
+ * 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
+ * A PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 #include "material_plastic.hh"
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 template <UInt spatial_dimension>
 MaterialPlastic<spatial_dimension>::MaterialPlastic(SolidMechanicsModel & model,
                                                     const ID & id)
     : MaterialElastic<spatial_dimension>(model, id),
       iso_hardening("iso_hardening", *this),
       inelastic_strain("inelastic_strain", *this),
       plastic_energy("plastic_energy", *this),
       d_plastic_energy("d_plastic_energy", *this) {
   AKANTU_DEBUG_IN();
   this->initialize();
   AKANTU_DEBUG_OUT();
 }
 
 template <UInt spatial_dimension>
 MaterialPlastic<spatial_dimension>::MaterialPlastic(SolidMechanicsModel & model,
                                                     UInt dim, const Mesh & mesh,
                                                     FEEngine & fe_engine,
                                                     const ID & id)
     : MaterialElastic<spatial_dimension>(model, dim, mesh, fe_engine, id),
       iso_hardening("iso_hardening", *this, dim, fe_engine,
                     this->element_filter),
       inelastic_strain("inelastic_strain", *this, dim, fe_engine,
                        this->element_filter),
       plastic_energy("plastic_energy", *this, dim, fe_engine,
                      this->element_filter),
       d_plastic_energy("d_plastic_energy", *this, dim, fe_engine,
                        this->element_filter) {
   AKANTU_DEBUG_IN();
   this->initialize();
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <UInt spatial_dimension>
 void MaterialPlastic<spatial_dimension>::initialize() {
   this->registerParam("h", h, Real(0.), _pat_parsable | _pat_modifiable,
                       "Hardening  modulus");
   this->registerParam("sigma_y", sigma_y, Real(0.),
                       _pat_parsable | _pat_modifiable, "Yield stress");
 
   this->iso_hardening.initialize(1);
   this->iso_hardening.initializeHistory();
 
   this->plastic_energy.initialize(1);
   this->d_plastic_energy.initialize(1);
 
   this->use_previous_stress = true;
   this->use_previous_gradu = true;
   this->use_previous_stress_thermal = true;
 
   this->inelastic_strain.initialize(spatial_dimension * spatial_dimension);
   this->inelastic_strain.initializeHistory();
 }
 
 /* -------------------------------------------------------------------------- */
 template <UInt spatial_dimension>
 Real MaterialPlastic<spatial_dimension>::getEnergy(const std::string & type) {
   if (type == "plastic")
     return getPlasticEnergy();
   else
     return MaterialElastic<spatial_dimension>::getEnergy(type);
 
   return 0.;
 }
 
 /* -------------------------------------------------------------------------- */
 template <UInt spatial_dimension>
 Real MaterialPlastic<spatial_dimension>::getPlasticEnergy() {
   AKANTU_DEBUG_IN();
 
   Real penergy = 0.;
 
   for (auto & type :
        this->element_filter.elementTypes(spatial_dimension, _not_ghost)) {
     penergy +=
         this->fem.integrate(plastic_energy(type, _not_ghost), type, _not_ghost,
                             this->element_filter(type, _not_ghost));
   }
 
   AKANTU_DEBUG_OUT();
   return penergy;
 }
 
 /* -------------------------------------------------------------------------- */
 template <UInt spatial_dimension>
 void MaterialPlastic<spatial_dimension>::computePotentialEnergy(
     ElementType el_type, GhostType ghost_type) {
   AKANTU_DEBUG_IN();
 
   if (ghost_type != _not_ghost)
     return;
 
   Array<Real>::scalar_iterator epot =
       this->potential_energy(el_type, ghost_type).begin();
 
   Array<Real>::const_iterator<Matrix<Real>> inelastic_strain_it =
       this->inelastic_strain(el_type, ghost_type)
           .begin(spatial_dimension, spatial_dimension);
 
   MATERIAL_STRESS_QUADRATURE_POINT_LOOP_BEGIN(el_type, ghost_type);
 
   Matrix<Real> elastic_strain(spatial_dimension, spatial_dimension);
   elastic_strain.copy(grad_u);
   elastic_strain -= *inelastic_strain_it;
 
   MaterialElastic<spatial_dimension>::computePotentialEnergyOnQuad(
       elastic_strain, sigma, *epot);
 
   ++epot;
   ++inelastic_strain_it;
 
   MATERIAL_STRESS_QUADRATURE_POINT_LOOP_END;
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <UInt spatial_dimension>
 void MaterialPlastic<spatial_dimension>::updateEnergies(ElementType el_type,
                                                         GhostType ghost_type) {
   AKANTU_DEBUG_IN();
 
   MaterialElastic<spatial_dimension>::updateEnergies(el_type, ghost_type);
 
   Array<Real>::iterator<> pe_it =
       this->plastic_energy(el_type, ghost_type).begin();
 
   Array<Real>::iterator<> wp_it =
       this->d_plastic_energy(el_type, ghost_type).begin();
 
   Array<Real>::iterator<Matrix<Real>> inelastic_strain_it =
       this->inelastic_strain(el_type, ghost_type)
           .begin(spatial_dimension, spatial_dimension);
 
   Array<Real>::iterator<Matrix<Real>> previous_inelastic_strain_it =
       this->inelastic_strain.previous(el_type, ghost_type)
           .begin(spatial_dimension, spatial_dimension);
 
   Array<Real>::matrix_iterator previous_sigma =
       this->stress.previous(el_type, ghost_type)
           .begin(spatial_dimension, spatial_dimension);
 
   MATERIAL_STRESS_QUADRATURE_POINT_LOOP_BEGIN(el_type, ghost_type);
 
   Matrix<Real> delta_strain_it(*inelastic_strain_it);
   delta_strain_it -= *previous_inelastic_strain_it;
 
   Matrix<Real> sigma_h(sigma);
   sigma_h += *previous_sigma;
 
   *wp_it = .5 * sigma_h.doubleDot(delta_strain_it);
 
   *pe_it += *wp_it;
 
   ++pe_it;
   ++wp_it;
   ++inelastic_strain_it;
   ++previous_inelastic_strain_it;
   ++previous_sigma;
 
   MATERIAL_STRESS_QUADRATURE_POINT_LOOP_END;
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 
 INSTANTIATE_MATERIAL_ONLY(MaterialPlastic);
 
 } // namespace akantu
diff --git a/src/model/solid_mechanics/materials/material_plastic/material_plastic.hh b/src/model/solid_mechanics/materials/material_plastic/material_plastic.hh
index 1b1b2749b..36ac049c8 100644
--- a/src/model/solid_mechanics/materials/material_plastic/material_plastic.hh
+++ b/src/model/solid_mechanics/materials/material_plastic/material_plastic.hh
@@ -1,130 +1,130 @@
 /**
  * @file   material_plastic.hh
  *
+ * @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
  * @author Daniel Pino Muñoz <daniel.pinomunoz@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Fri Jun 18 2010
- * @date last modification: Thu Oct 08 2015
+ * @date last modification: Thu Dec 07 2017
  *
  * @brief  Common interface for plastic materials
  *
  * @section LICENSE
  *
- * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
- * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
- * Solides)
+ * 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
+ * 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
+ * A PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 #include "material_elastic.hh"
 /* -------------------------------------------------------------------------- */
 
 #ifndef __AKANTU_MATERIAL_PLASTIC_HH__
 #define __AKANTU_MATERIAL_PLASTIC_HH__
 
 namespace akantu {
 
 /**
  * Parent class for the plastic constitutive laws
  * parameters in the material files :
  *   - h : Hardening parameter (default: 0)
  *   - sigmay : Yield stress
  */
 template <UInt dim> class MaterialPlastic : public MaterialElastic<dim> {
   /* ------------------------------------------------------------------------ */
   /* Constructors/Destructors                                                 */
   /* ------------------------------------------------------------------------ */
 public:
   MaterialPlastic(SolidMechanicsModel & model, const ID & id = "");
   MaterialPlastic(SolidMechanicsModel & model, UInt a_dim, const Mesh & mesh,
                   FEEngine & fe_engine, const ID & id = "");
 
 protected:
   void initialize();
 
   /* ------------------------------------------------------------------------ */
   /* Methods                                                                  */
   /* ------------------------------------------------------------------------ */
 public:
   /// get the energy specifying the type for the time step
   Real getEnergy(const std::string & type) override;
 
   /// Compute the plastic energy
   void updateEnergies(ElementType el_type,
                       GhostType ghost_type = _not_ghost) override;
 
   /// Compute the true potential energy
   void computePotentialEnergy(ElementType el_type,
                               GhostType ghost_type) override;
 
 protected:
   /// compute the stress and inelastic strain for the quadrature point
   inline void computeStressAndInelasticStrainOnQuad(
       const Matrix<Real> & grad_u, const Matrix<Real> & previous_grad_u,
       Matrix<Real> & sigma, const Matrix<Real> & previous_sigma,
       Matrix<Real> & inelas_strain, const Matrix<Real> & previous_inelas_strain,
       const Matrix<Real> & delta_inelastic_strain) const;
 
   inline void computeStressAndInelasticStrainOnQuad(
       const Matrix<Real> & delta_grad_u, Matrix<Real> & sigma,
       const Matrix<Real> & previous_sigma, Matrix<Real> & inelas_strain,
       const Matrix<Real> & previous_inelas_strain,
       const Matrix<Real> & delta_inelastic_strain) const;
 
   /// get the plastic energy for the time step
   Real getPlasticEnergy();
 
   /* ------------------------------------------------------------------------ */
   /* Accessors                                                                */
   /* ------------------------------------------------------------------------ */
 public:
   /* ------------------------------------------------------------------------ */
   /* Class Members                                                            */
   /* ------------------------------------------------------------------------ */
 protected:
   /// Yield stresss
   Real sigma_y;
 
   /// hardening modulus
   Real h;
 
   /// isotropic hardening, r
   InternalField<Real> iso_hardening;
 
   /// inelastic strain arrays ordered by element types (inelastic deformation)
   InternalField<Real> inelastic_strain;
 
   /// Plastic energy
   InternalField<Real> plastic_energy;
 
   /// @todo : add a coefficient beta that will multiply the plastic energy
   /// increment
   /// to compute the energy converted to heat
 
   /// Plastic energy increment
   InternalField<Real> d_plastic_energy;
 };
 
 /* -------------------------------------------------------------------------- */
 /* inline functions                                                           */
 /* -------------------------------------------------------------------------- */
 
 } // akantu
 
 #include "material_plastic_inline_impl.cc"
 #endif /* __AKANTU_MATERIAL_PLASTIC_HH__ */
diff --git a/src/model/solid_mechanics/materials/material_plastic/material_plastic_inline_impl.cc b/src/model/solid_mechanics/materials/material_plastic/material_plastic_inline_impl.cc
index 1c8172c80..f70afb3a2 100644
--- a/src/model/solid_mechanics/materials/material_plastic/material_plastic_inline_impl.cc
+++ b/src/model/solid_mechanics/materials/material_plastic/material_plastic_inline_impl.cc
@@ -1,75 +1,76 @@
 /**
  * @file   material_plastic_inline_impl.cc
  *
+ * @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
  * @author Daniel Pino Muñoz <daniel.pinomunoz@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Mon Apr 07 2014
- * @date last modification: Tue Aug 18 2015
+ * @date last modification: Wed Jan 24 2018
  *
  * @brief  Implementation of the inline functions of akantu::MaterialPlastic
  *
  * @section LICENSE
  *
- * Copyright  (©)  2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de Lausanne)
+ * 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
+ * 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
+ * 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 MATERIAL_PLASTIC_INLINE_IMPL_H
 #define MATERIAL_PLASTIC_INLINE_IMPL_H
 
 #include "material_plastic.hh"
 
 namespace akantu {
 
 template <UInt dim>
 inline void MaterialPlastic<dim>::computeStressAndInelasticStrainOnQuad(
     const Matrix<Real> & delta_grad_u, Matrix<Real> & sigma,
     const Matrix<Real> & previous_sigma, Matrix<Real> & inelastic_strain,
     const Matrix<Real> & previous_inelastic_strain,
     const Matrix<Real> & delta_inelastic_strain) const {
   Matrix<Real> grad_u_elastic(dim, dim);
   grad_u_elastic.copy(delta_grad_u);
   grad_u_elastic -= delta_inelastic_strain;
   Matrix<Real> sigma_elastic(dim, dim);
   MaterialElastic<dim>::computeStressOnQuad(grad_u_elastic, sigma_elastic);
   sigma.copy(previous_sigma);
   sigma += sigma_elastic;
   inelastic_strain.copy(previous_inelastic_strain);
   inelastic_strain += delta_inelastic_strain;
 }
 
 /* -------------------------------------------------------------------------- */
 template <UInt dim>
 inline void MaterialPlastic<dim>::computeStressAndInelasticStrainOnQuad(
     const Matrix<Real> & grad_u, const Matrix<Real> & previous_grad_u,
     Matrix<Real> & sigma, const Matrix<Real> & previous_sigma,
     Matrix<Real> & inelastic_strain,
     const Matrix<Real> & previous_inelastic_strain,
     const Matrix<Real> & delta_inelastic_strain) const {
   Matrix<Real> delta_grad_u(grad_u);
   delta_grad_u -= previous_grad_u;
 
   computeStressAndInelasticStrainOnQuad(
       delta_grad_u, sigma, previous_sigma, inelastic_strain,
       previous_inelastic_strain, delta_inelastic_strain);
 }
 
 } // Akantu
 
 #endif /* MATERIAL_PLASTIC_INLINE_IMPL_H */
diff --git a/src/model/solid_mechanics/materials/material_python/material_python.cc b/src/model/solid_mechanics/materials/material_python/material_python.cc
index 3c3087c87..c48b3ae85 100644
--- a/src/model/solid_mechanics/materials/material_python/material_python.cc
+++ b/src/model/solid_mechanics/materials/material_python/material_python.cc
@@ -1,214 +1,215 @@
 /**
  * @file   material_python.cc
  *
  * @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
+ * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Fri Nov 13 2015
- * @date last modification: Fri Nov 13 2015
+ * @date last modification: Wed Feb 07 2018
  *
  * @brief  Material python implementation
  *
  * @section LICENSE
  *
- * Copyright (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne) Laboratory
- * (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * Copyright (©) 2015-2018 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
- * terms  of the  GNU Lesser  General Public  License as  published by  the Free
+ * 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
+ * A PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 #include "material_python.hh"
 #include "solid_mechanics_model.hh"
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 MaterialPython::MaterialPython(SolidMechanicsModel & model, PyObject * obj,
                                const ID & id)
     : Material(model, id), PythonFunctor(obj) {
   AKANTU_DEBUG_IN();
 
   this->registerInternals();
 
   std::vector<std::string> param_names =
       this->callFunctor<std::vector<std::string>>("registerParam");
 
   for (UInt i = 0; i < param_names.size(); ++i) {
     std::stringstream sstr;
     sstr << "PythonParameter" << i;
     this->registerParam(param_names[i], local_params[param_names[i]], 0.,
                         _pat_parsable | _pat_readable, sstr.str());
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void MaterialPython::registerInternals() {
   std::vector<std::string> internal_names =
       this->callFunctor<std::vector<std::string>>("registerInternals");
 
   std::vector<UInt> internal_sizes;
 
   try {
     internal_sizes =
         this->callFunctor<std::vector<UInt>>("registerInternalSizes");
   } catch (...) {
     internal_sizes.assign(internal_names.size(), 1);
   }
 
   for (UInt i = 0; i < internal_names.size(); ++i) {
     std::stringstream sstr;
     sstr << "PythonInternal" << i;
     this->internals[internal_names[i]] =
         std::make_unique<InternalField<Real>>(internal_names[i], *this);
     AKANTU_DEBUG_INFO("alloc internal " << internal_names[i] << " "
                                         << &this->internals[internal_names[i]]);
 
     this->internals[internal_names[i]]->initialize(internal_sizes[i]);
   }
 
   // making an internal with the quadrature points coordinates
   this->internals["quad_coordinates"] =
       std::make_unique<InternalField<Real>>("quad_coordinates", *this);
   auto && coords = *this->internals["quad_coordinates"];
   coords.initialize(this->getSpatialDimension());
 }
 
 /* -------------------------------------------------------------------------- */
 
 void MaterialPython::initMaterial() {
   AKANTU_DEBUG_IN();
 
   Material::initMaterial();
 
   auto && coords = *this->internals["quad_coordinates"];
   this->model.getFEEngine().computeIntegrationPointsCoordinates(
       coords, &this->element_filter);
 
   auto params = local_params;
   params["rho"] = this->rho;
 
   try {
     this->callFunctor<void>("initMaterial", this->internals, params);
   } catch (...) {
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 
 void MaterialPython::computeStress(ElementType el_type, GhostType ghost_type) {
   AKANTU_DEBUG_IN();
 
   auto params = local_params;
   params["rho"] = this->rho;
 
   std::map<std::string, Array<Real> *> internal_arrays;
   for (auto & i : this->internals) {
     auto & array = (*i.second)(el_type, ghost_type);
     auto & name = i.first;
     internal_arrays[name] = &array;
   }
 
   this->callFunctor<void>("computeStress", this->gradu(el_type, ghost_type),
                           this->stress(el_type, ghost_type), internal_arrays,
                           params);
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void MaterialPython::computeTangentModuli(const ElementType & el_type,
                                           Array<Real> & tangent_matrix,
                                           GhostType ghost_type) {
   auto params = local_params;
   params["rho"] = this->rho;
 
   std::map<std::string, Array<Real> *> internal_arrays;
   for (auto & i : this->internals) {
     auto & array = (*i.second)(el_type, ghost_type);
     auto & name = i.first;
     internal_arrays[name] = &array;
   }
 
   this->callFunctor<void>("computeTangentModuli",
                           this->gradu(el_type, ghost_type), tangent_matrix,
                           internal_arrays, params);
 }
 
 /* -------------------------------------------------------------------------- */
 Real MaterialPython::getPushWaveSpeed(const Element &) const {
   auto params = local_params;
   params["rho"] = this->rho;
 
   return this->callFunctor<Real>("getPushWaveSpeed", params);
 }
 
 /* -------------------------------------------------------------------------- */
 
 Real MaterialPython::getEnergyForType(const std::string & type,
                                       ElementType el_type) {
   AKANTU_DEBUG_IN();
 
   std::map<std::string, Array<Real> *> internal_arrays;
   for (auto & i : this->internals) {
     auto & array = (*i.second)(el_type, _not_ghost);
     auto & name = i.first;
     internal_arrays[name] = &array;
   }
 
   auto params = local_params;
   params["rho"] = this->rho;
 
   auto & energy_density = *internal_arrays[type];
 
   this->callFunctor<void>("getEnergyDensity", type, energy_density,
                           this->gradu(el_type, _not_ghost),
                           this->stress(el_type, _not_ghost), internal_arrays,
                           params);
 
   Real energy = fem.integrate(energy_density, el_type, _not_ghost,
                               element_filter(el_type, _not_ghost));
 
   AKANTU_DEBUG_OUT();
   return energy;
 }
 
 /* -------------------------------------------------------------------------- */
 
 Real MaterialPython::getEnergy(const std::string & type) {
   AKANTU_DEBUG_IN();
 
   if (this->internals.find(type) == this->internals.end()) {
     AKANTU_EXCEPTION("unknown energy type: "
                      << type << " you must declare an internal named " << type);
   }
 
   Real energy = 0.;
   /// integrate the potential energy for each type of elements
   Mesh::type_iterator it = element_filter.firstType(spatial_dimension);
   Mesh::type_iterator last_type = element_filter.lastType(spatial_dimension);
   for (; it != last_type; ++it) {
     energy += this->getEnergyForType(type, *it);
   }
   AKANTU_DEBUG_OUT();
   return energy;
 }
 
 /* -------------------------------------------------------------------------- */
 
 } // akantu
diff --git a/src/model/solid_mechanics/materials/material_python/material_python.hh b/src/model/solid_mechanics/materials/material_python/material_python.hh
index e675b338b..a16c88b1e 100644
--- a/src/model/solid_mechanics/materials/material_python/material_python.hh
+++ b/src/model/solid_mechanics/materials/material_python/material_python.hh
@@ -1,97 +1,98 @@
 /**
  * @file   material_python.hh
  *
  * @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
+ * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
- * @date creation: Fri Nov 13 2015
- * @date last modification: Fri Nov 13 2015
+ * @date creation: Fri Jun 18 2010
+ * @date last modification: Tue Feb 06 2018
  *
  * @brief  Python material
  *
  * @section LICENSE
  *
- * Copyright (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne) Laboratory
- * (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * Copyright (©) 2015-2018 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
- * terms  of the  GNU Lesser  General Public  License as  published by  the Free
+ * 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
+ * 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/>.
  *
  */
 
 /**
  * @file   material_python.hh
  *
  * @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
  *
  */
 
 /* -------------------------------------------------------------------------- */
 #include "python_functor.hh"
 /* -------------------------------------------------------------------------- */
 #include "material.hh"
 /* -------------------------------------------------------------------------- */
 
 #ifndef __AKANTU_MATERIAL_PYTHON_HH__
 #define __AKANTU_MATERIAL_PYTHON_HH__
 
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 
 class MaterialPython : public Material, PythonFunctor {
   /* ------------------------------------------------------------------------ */
   /* Constructors/Destructors                                                 */
   /* ------------------------------------------------------------------------ */
 public:
   MaterialPython(SolidMechanicsModel & model, PyObject * obj,
                  const ID & id = "");
 
   ~MaterialPython() override = default;
 
   /* ------------------------------------------------------------------------ */
   /* Methods                                                                  */
   /* ------------------------------------------------------------------------ */
 public:
   void registerInternals();
 
   void initMaterial() override;
 
   /// constitutive law for all element of a type
   void computeStress(ElementType el_type,
                      GhostType ghost_type = _not_ghost) override;
 
   /// compute the tangent stiffness matrix for an element type
   void computeTangentModuli(const ElementType & el_type,
                             Array<Real> & tangent_matrix,
                             GhostType ghost_type = _not_ghost) override;
 
   /// compute the push wave speed of the material
   Real getPushWaveSpeed(const Element & element) const override;
 
   /// compute an energy of the material
   Real getEnergy(const std::string & type) override;
 
   /// compute an energy of the material
   Real getEnergyForType(const std::string & type, ElementType el_type);
 
   /* ------------------------------------------------------------------------ */
   /* Class Members                                                            */
   /* ------------------------------------------------------------------------ */
 protected:
   std::map<std::string, Real> local_params;
   std::map<std::string, std::unique_ptr<InternalField<Real>>> internals;
 };
 
 } // akantu
 
 #endif /* __AKANTU_MATERIAL_PYTHON_HH__ */
diff --git a/src/model/solid_mechanics/materials/material_thermal.cc b/src/model/solid_mechanics/materials/material_thermal.cc
index 70222c54f..22a29b48d 100644
--- a/src/model/solid_mechanics/materials/material_thermal.cc
+++ b/src/model/solid_mechanics/materials/material_thermal.cc
@@ -1,111 +1,110 @@
 /**
  * @file   material_thermal.cc
  *
  * @author Lucas Frerot <lucas.frerot@epfl.ch>
  *
  * @date creation: Fri Jun 18 2010
- * @date last modification: Tue Aug 04 2015
+ * @date last modification: Mon Jan 29 2018
  *
  * @brief  Specialization of the material class for the thermal material
  *
  * @section LICENSE
  *
- * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
- * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
- * Solides)
+ * 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
+ * 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
+ * A PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 #include "material_thermal.hh"
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 template <UInt spatial_dimension>
 MaterialThermal<spatial_dimension>::MaterialThermal(SolidMechanicsModel & model,
                                                     const ID & id)
     : Material(model, id), delta_T("delta_T", *this),
       sigma_th("sigma_th", *this), use_previous_stress_thermal(false) {
   AKANTU_DEBUG_IN();
   this->initialize();
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <UInt spatial_dimension>
 MaterialThermal<spatial_dimension>::MaterialThermal(SolidMechanicsModel & model,
                                                     UInt dim, const Mesh & mesh,
                                                     FEEngine & fe_engine,
                                                     const ID & id)
     : Material(model, dim, mesh, fe_engine, id),
       delta_T("delta_T", *this, dim, fe_engine, this->element_filter),
       sigma_th("sigma_th", *this, dim, fe_engine, this->element_filter),
       use_previous_stress_thermal(false) {
   AKANTU_DEBUG_IN();
   this->initialize();
   AKANTU_DEBUG_OUT();
 }
 
 template <UInt spatial_dimension>
 void MaterialThermal<spatial_dimension>::initialize() {
   this->registerParam("E", E, Real(0.), _pat_parsable | _pat_modifiable,
                       "Young's modulus");
   this->registerParam("nu", nu, Real(0.5), _pat_parsable | _pat_modifiable,
                       "Poisson's ratio");
   this->registerParam("alpha", alpha, Real(0.), _pat_parsable | _pat_modifiable,
                       "Thermal expansion coefficient");
   this->registerParam("delta_T", delta_T, _pat_parsable | _pat_modifiable,
                       "Uniform temperature field");
 
   delta_T.initialize(1);
 }
 
 /* -------------------------------------------------------------------------- */
 template <UInt spatial_dimension>
 void MaterialThermal<spatial_dimension>::initMaterial() {
   AKANTU_DEBUG_IN();
 
   sigma_th.initialize(1);
 
   if (use_previous_stress_thermal) {
     sigma_th.initializeHistory();
   }
 
   Material::initMaterial();
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <UInt dim>
 void MaterialThermal<dim>::computeStress(ElementType el_type,
                                          GhostType ghost_type) {
   AKANTU_DEBUG_IN();
 
   for (auto && tuple : zip(this->delta_T(el_type, ghost_type),
                            this->sigma_th(el_type, ghost_type))) {
     computeStressOnQuad(std::get<1>(tuple), std::get<0>(tuple));
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 
 INSTANTIATE_MATERIAL_ONLY(MaterialThermal);
 
 } // akantu
diff --git a/src/model/solid_mechanics/materials/material_thermal.hh b/src/model/solid_mechanics/materials/material_thermal.hh
index ee1a0fe94..d7e1d3555 100644
--- a/src/model/solid_mechanics/materials/material_thermal.hh
+++ b/src/model/solid_mechanics/materials/material_thermal.hh
@@ -1,108 +1,107 @@
 /**
  * @file   material_thermal.hh
  *
  * @author Lucas Frerot <lucas.frerot@epfl.ch>
  *
  * @date creation: Fri Jun 18 2010
- * @date last modification: Tue Aug 18 2015
+ * @date last modification: Mon Jan 29 2018
  *
  * @brief  Material isotropic thermo-elastic
  *
  * @section LICENSE
  *
- * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
- * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
- * Solides)
+ * 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
+ * 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
+ * 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 "material.hh"
 /* -------------------------------------------------------------------------- */
 
 #ifndef __AKANTU_MATERIAL_THERMAL_HH__
 #define __AKANTU_MATERIAL_THERMAL_HH__
 
 namespace akantu {
 template <UInt spatial_dimension> class MaterialThermal : public Material {
   /* ------------------------------------------------------------------------ */
   /* Constructors/Destructors                                                 */
   /* ------------------------------------------------------------------------ */
 public:
   MaterialThermal(SolidMechanicsModel & model, const ID & id = "");
   MaterialThermal(SolidMechanicsModel & model, UInt dim, const Mesh & mesh,
                   FEEngine & fe_engine, const ID & id = "");
 
   ~MaterialThermal() override = default;
 
 protected:
   void initialize();
 
   /* ------------------------------------------------------------------------ */
   /* Methods                                                                  */
   /* ------------------------------------------------------------------------ */
 public:
   void initMaterial() override;
 
   /// constitutive law for all element of a type
   void computeStress(ElementType el_type, GhostType ghost_type) override;
 
   /// local computation of thermal stress
   inline void computeStressOnQuad(Real & sigma, const Real & deltaT);
 
   /* ------------------------------------------------------------------------ */
   /* Class Members                                                            */
   /* ------------------------------------------------------------------------ */
 protected:
   /// Young modulus
   Real E;
 
   /// Poisson ratio
   Real nu;
 
   /// Thermal expansion coefficient
   /// TODO : implement alpha as a matrix
   Real alpha;
 
   /// Temperature field
   InternalField<Real> delta_T;
 
   /// Current thermal stress
   InternalField<Real> sigma_th;
 
   /// Tell if we need to use the previous thermal stress
   bool use_previous_stress_thermal;
 };
 
 /* ------------------------------------------------------------------------ */
 /* Inline impl                                                              */
 /* ------------------------------------------------------------------------ */
 template <UInt dim>
 inline void MaterialThermal<dim>::computeStressOnQuad(Real & sigma,
                                                       const Real & deltaT) {
   sigma = -this->E / (1. - 2. * this->nu) * this->alpha * deltaT;
 }
 
 template <>
 inline void MaterialThermal<1>::computeStressOnQuad(Real & sigma,
                                                     const Real & deltaT) {
   sigma = -this->E * this->alpha * deltaT;
 }
 
 } // akantu
 
 #endif /* __AKANTU_MATERIAL_THERMAL_HH__ */
diff --git a/src/model/solid_mechanics/materials/material_viscoelastic/material_standard_linear_solid_deviatoric.cc b/src/model/solid_mechanics/materials/material_viscoelastic/material_standard_linear_solid_deviatoric.cc
index f21887a1b..e103076ac 100644
--- a/src/model/solid_mechanics/materials/material_viscoelastic/material_standard_linear_solid_deviatoric.cc
+++ b/src/model/solid_mechanics/materials/material_viscoelastic/material_standard_linear_solid_deviatoric.cc
@@ -1,325 +1,324 @@
 /**
  * @file   material_standard_linear_solid_deviatoric.cc
  *
  * @author David Simon Kammer <david.kammer@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  * @author Vladislav Yastrebov <vladislav.yastrebov@epfl.ch>
  *
  * @date creation: Wed May 04 2011
- * @date last modification: Thu Oct 15 2015
+ * @date last modification: Tue Feb 20 2018
  *
  * @brief  Material Visco-elastic
  *
  * @section LICENSE
  *
- * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
- * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
- * Solides)
+ * 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
+ * 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
+ * A PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 #include "material_standard_linear_solid_deviatoric.hh"
 #include "solid_mechanics_model.hh"
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 template <UInt spatial_dimension>
 MaterialStandardLinearSolidDeviatoric<spatial_dimension>::
     MaterialStandardLinearSolidDeviatoric(SolidMechanicsModel & model,
                                           const ID & id)
     : MaterialElastic<spatial_dimension>(model, id),
       stress_dev("stress_dev", *this),
       history_integral("history_integral", *this),
       dissipated_energy("dissipated_energy", *this) {
 
   AKANTU_DEBUG_IN();
 
   this->registerParam("Eta", eta, Real(1.), _pat_parsable | _pat_modifiable,
                       "Viscosity");
   this->registerParam("Ev", Ev, Real(1.), _pat_parsable | _pat_modifiable,
                       "Stiffness of the viscous element");
   this->registerParam("Einf", E_inf, Real(1.), _pat_readable,
                       "Stiffness of the elastic element");
 
   UInt stress_size = spatial_dimension * spatial_dimension;
 
   this->stress_dev.initialize(stress_size);
   this->history_integral.initialize(stress_size);
   this->dissipated_energy.initialize(1);
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <UInt spatial_dimension>
 void MaterialStandardLinearSolidDeviatoric<spatial_dimension>::initMaterial() {
   AKANTU_DEBUG_IN();
 
   updateInternalParameters();
   MaterialElastic<spatial_dimension>::initMaterial();
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <UInt spatial_dimension>
 void MaterialStandardLinearSolidDeviatoric<
     spatial_dimension>::updateInternalParameters() {
   MaterialElastic<spatial_dimension>::updateInternalParameters();
   E_inf = this->E - this->Ev;
 }
 
 /* -------------------------------------------------------------------------- */
 template <UInt spatial_dimension>
 void MaterialStandardLinearSolidDeviatoric<spatial_dimension>::setToSteadyState(
     ElementType el_type, GhostType ghost_type) {
   AKANTU_DEBUG_IN();
 
   Array<Real> & stress_dev_vect = stress_dev(el_type, ghost_type);
   Array<Real> & history_int_vect = history_integral(el_type, ghost_type);
 
   Array<Real>::matrix_iterator stress_d =
       stress_dev_vect.begin(spatial_dimension, spatial_dimension);
   Array<Real>::matrix_iterator history_int =
       history_int_vect.begin(spatial_dimension, spatial_dimension);
 
   /// Loop on all quadrature points
   MATERIAL_STRESS_QUADRATURE_POINT_LOOP_BEGIN(el_type, ghost_type);
 
   Matrix<Real> & dev_s = *stress_d;
   Matrix<Real> & h = *history_int;
 
   /// Compute the first invariant of strain
   Real Theta = grad_u.trace();
 
   for (UInt i = 0; i < spatial_dimension; ++i)
     for (UInt j = 0; j < spatial_dimension; ++j) {
       dev_s(i, j) = 2 * this->mu * (.5 * (grad_u(i, j) + grad_u(j, i)) -
                                     1. / 3. * Theta * (i == j));
       h(i, j) = 0.;
     }
 
   /// Save the deviator of stress
   ++stress_d;
   ++history_int;
 
   MATERIAL_STRESS_QUADRATURE_POINT_LOOP_END;
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <UInt spatial_dimension>
 void MaterialStandardLinearSolidDeviatoric<spatial_dimension>::computeStress(
     ElementType el_type, GhostType ghost_type) {
   AKANTU_DEBUG_IN();
 
   Real tau = 0.;
   // if(std::abs(Ev) > std::numeric_limits<Real>::epsilon())
   tau = eta / Ev;
 
   Array<Real> & stress_dev_vect = stress_dev(el_type, ghost_type);
   Array<Real> & history_int_vect = history_integral(el_type, ghost_type);
 
   Array<Real>::matrix_iterator stress_d =
       stress_dev_vect.begin(spatial_dimension, spatial_dimension);
   Array<Real>::matrix_iterator history_int =
       history_int_vect.begin(spatial_dimension, spatial_dimension);
 
   Matrix<Real> s(spatial_dimension, spatial_dimension);
 
   Real dt = this->model.getTimeStep();
   Real exp_dt_tau = exp(-dt / tau);
   Real exp_dt_tau_2 = exp(-.5 * dt / tau);
 
   Matrix<Real> epsilon_d(spatial_dimension, spatial_dimension);
   Matrix<Real> epsilon_v(spatial_dimension, spatial_dimension);
 
   /// Loop on all quadrature points
   MATERIAL_STRESS_QUADRATURE_POINT_LOOP_BEGIN(el_type, ghost_type);
 
   Matrix<Real> & dev_s = *stress_d;
   Matrix<Real> & h = *history_int;
 
   s.clear();
   sigma.clear();
 
   /// Compute the first invariant of strain
   Real gamma_inf = E_inf / this->E;
   Real gamma_v = Ev / this->E;
 
   this->template gradUToEpsilon<spatial_dimension>(grad_u, epsilon_d);
   Real Theta = epsilon_d.trace();
   epsilon_v.eye(Theta / Real(3.));
   epsilon_d -= epsilon_v;
 
   Matrix<Real> U_rond_prim(spatial_dimension, spatial_dimension);
 
   U_rond_prim.eye(gamma_inf * this->kpa * Theta);
 
   for (UInt i = 0; i < spatial_dimension; ++i)
     for (UInt j = 0; j < spatial_dimension; ++j) {
       s(i, j) = 2 * this->mu * epsilon_d(i, j);
       h(i, j) = exp_dt_tau * h(i, j) + exp_dt_tau_2 * (s(i, j) - dev_s(i, j));
       dev_s(i, j) = s(i, j);
       sigma(i, j) = U_rond_prim(i, j) + gamma_inf * s(i, j) + gamma_v * h(i, j);
     }
 
   /// Save the deviator of stress
   ++stress_d;
   ++history_int;
 
   MATERIAL_STRESS_QUADRATURE_POINT_LOOP_END;
 
   this->updateDissipatedEnergy(el_type, ghost_type);
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <UInt spatial_dimension>
 void MaterialStandardLinearSolidDeviatoric<
     spatial_dimension>::updateDissipatedEnergy(ElementType el_type,
                                                GhostType ghost_type) {
   AKANTU_DEBUG_IN();
 
   // if(ghost_type == _ghost) return 0.;
 
   Real tau = 0.;
   tau = eta / Ev;
   Real * dis_energy = dissipated_energy(el_type, ghost_type).storage();
 
   Array<Real> & stress_dev_vect = stress_dev(el_type, ghost_type);
   Array<Real> & history_int_vect = history_integral(el_type, ghost_type);
 
   Array<Real>::matrix_iterator stress_d =
       stress_dev_vect.begin(spatial_dimension, spatial_dimension);
   Array<Real>::matrix_iterator history_int =
       history_int_vect.begin(spatial_dimension, spatial_dimension);
 
   Matrix<Real> q(spatial_dimension, spatial_dimension);
   Matrix<Real> q_rate(spatial_dimension, spatial_dimension);
   Matrix<Real> epsilon_d(spatial_dimension, spatial_dimension);
   Matrix<Real> epsilon_v(spatial_dimension, spatial_dimension);
 
   Real dt = this->model.getTimeStep();
 
   Real gamma_v = Ev / this->E;
   Real alpha = 1. / (2. * this->mu * gamma_v);
 
   /// Loop on all quadrature points
   MATERIAL_STRESS_QUADRATURE_POINT_LOOP_BEGIN(el_type, ghost_type);
 
   Matrix<Real> & dev_s = *stress_d;
   Matrix<Real> & h = *history_int;
 
   /// Compute the first invariant of strain
   this->template gradUToEpsilon<spatial_dimension>(grad_u, epsilon_d);
 
   Real Theta = epsilon_d.trace();
   epsilon_v.eye(Theta / Real(3.));
   epsilon_d -= epsilon_v;
 
   q.copy(dev_s);
   q -= h;
   q *= gamma_v;
 
   q_rate.copy(dev_s);
   q_rate *= gamma_v;
   q_rate -= q;
   q_rate /= tau;
 
   for (UInt i = 0; i < spatial_dimension; ++i)
     for (UInt j = 0; j < spatial_dimension; ++j)
       *dis_energy += (epsilon_d(i, j) - alpha * q(i, j)) * q_rate(i, j) * dt;
 
   /// Save the deviator of stress
   ++stress_d;
   ++history_int;
   ++dis_energy;
 
   MATERIAL_STRESS_QUADRATURE_POINT_LOOP_END;
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <UInt spatial_dimension>
 Real MaterialStandardLinearSolidDeviatoric<
     spatial_dimension>::getDissipatedEnergy() const {
   AKANTU_DEBUG_IN();
 
   Real de = 0.;
 
   /// integrate the dissipated energy for each type of elements
   for (auto & type :
        this->element_filter.elementTypes(spatial_dimension, _not_ghost)) {
     de +=
         this->fem.integrate(dissipated_energy(type, _not_ghost), type,
                             _not_ghost, this->element_filter(type, _not_ghost));
   }
 
   AKANTU_DEBUG_OUT();
   return de;
 }
 
 /* -------------------------------------------------------------------------- */
 template <UInt spatial_dimension>
 Real MaterialStandardLinearSolidDeviatoric<
     spatial_dimension>::getDissipatedEnergy(ElementType type,
                                             UInt index) const {
   AKANTU_DEBUG_IN();
 
   UInt nb_quadrature_points = this->fem.getNbIntegrationPoints(type);
   auto it =
       this->dissipated_energy(type, _not_ghost).begin(nb_quadrature_points);
   UInt gindex = (this->element_filter(type, _not_ghost))(index);
 
   AKANTU_DEBUG_OUT();
   return this->fem.integrate(it[index], type, gindex);
 }
 
 /* -------------------------------------------------------------------------- */
 template <UInt spatial_dimension>
 Real MaterialStandardLinearSolidDeviatoric<spatial_dimension>::getEnergy(
     const std::string & type) {
   if (type == "dissipated")
     return getDissipatedEnergy();
   else if (type == "dissipated_sls_deviatoric")
     return getDissipatedEnergy();
   else
     return MaterialElastic<spatial_dimension>::getEnergy(type);
 }
 
 /* -------------------------------------------------------------------------- */
 template <UInt spatial_dimension>
 Real MaterialStandardLinearSolidDeviatoric<spatial_dimension>::getEnergy(
     const std::string & energy_id, ElementType type, UInt index) {
   if (energy_id == "dissipated")
     return getDissipatedEnergy(type, index);
   else if (energy_id == "dissipated_sls_deviatoric")
     return getDissipatedEnergy(type, index);
   else
     return MaterialElastic<spatial_dimension>::getEnergy(energy_id, type,
                                                          index);
 }
 
 /* -------------------------------------------------------------------------- */
 
 INSTANTIATE_MATERIAL(sls_deviatoric, MaterialStandardLinearSolidDeviatoric);
 
 } // namespace akantu
diff --git a/src/model/solid_mechanics/materials/material_viscoelastic/material_standard_linear_solid_deviatoric.hh b/src/model/solid_mechanics/materials/material_viscoelastic/material_standard_linear_solid_deviatoric.hh
index a5a70a7ff..6b39c6d49 100644
--- a/src/model/solid_mechanics/materials/material_viscoelastic/material_standard_linear_solid_deviatoric.hh
+++ b/src/model/solid_mechanics/materials/material_viscoelastic/material_standard_linear_solid_deviatoric.hh
@@ -1,136 +1,135 @@
 /**
  * @file   material_standard_linear_solid_deviatoric.hh
  *
  * @author David Simon Kammer <david.kammer@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  * @author Vladislav Yastrebov <vladislav.yastrebov@epfl.ch>
  *
  * @date creation: Fri Jun 18 2010
- * @date last modification: Thu Oct 08 2015
+ * @date last modification: Sun Dec 03 2017
  *
  * @brief  Material Visco-elastic, based on Standard Solid rheological model,
  * see
  * [] J.C.  Simo, T.J.R. Hughes, "Computational  Inelasticity", Springer (1998),
  * see Sections 10.2 and 10.3
  *
  * @section LICENSE
  *
- * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
- * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
- * Solides)
+ * 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
+ * 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
+ * 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 "material_elastic.hh"
 /* -------------------------------------------------------------------------- */
 
 #ifndef __AKANTU_MATERIAL_STANDARD_LINEAR_SOLID_DEVIATORIC_HH__
 #define __AKANTU_MATERIAL_STANDARD_LINEAR_SOLID_DEVIATORIC_HH__
 
 namespace akantu {
 
 /**
  * Material standard linear solid deviatoric
  *
  *
  * @verbatim
 
              E_\inf
       ------|\/\/\|------
       |                 |
    ---|                 |---
       |                 |
       ----|\/\/\|--[|----
             E_v   \eta
 
  @endverbatim
  *
  * keyword : sls_deviatoric
  *
  * parameters in the material files :
  *   - E   : Initial Young's modulus @f$ E = E_i + E_v @f$
  *   - eta : viscosity
  *   - Ev  : stiffness of the viscous element
  */
 
 template <UInt spatial_dimension>
 class MaterialStandardLinearSolidDeviatoric
     : public MaterialElastic<spatial_dimension> {
   /* ------------------------------------------------------------------------ */
   /* Constructors/Destructors                                                 */
   /* ------------------------------------------------------------------------ */
 public:
   MaterialStandardLinearSolidDeviatoric(SolidMechanicsModel & model,
                                         const ID & id = "");
   ~MaterialStandardLinearSolidDeviatoric() override = default;
 
   /* ------------------------------------------------------------------------ */
   /* Methods                                                                  */
   /* ------------------------------------------------------------------------ */
 public:
   /// initialize the material computed parameter
   void initMaterial() override;
 
   /// update the internal parameters (for modifiable parameters)
   void updateInternalParameters() override;
 
   /// set material to steady state
   void setToSteadyState(ElementType el_type,
                         GhostType ghost_type = _not_ghost) override;
 
   /// constitutive law for all element of a type
   void computeStress(ElementType el_type,
                      GhostType ghost_type = _not_ghost) override;
 
 protected:
   /// update the dissipated energy, is called after the stress have been
   /// computed
   void updateDissipatedEnergy(ElementType el_type, GhostType ghost_type);
 
   /* ------------------------------------------------------------------------ */
   /* Accessors                                                                */
   /* ------------------------------------------------------------------------ */
 public:
   /// give the dissipated energy for the time step
   Real getDissipatedEnergy() const;
   Real getDissipatedEnergy(ElementType type, UInt index) const;
 
   /// get the energy using an energy type string for the time step
   Real getEnergy(const std::string & type) override;
   Real getEnergy(const std::string & energy_id, ElementType type,
                  UInt index) override;
   /* ------------------------------------------------------------------------ */
   /* Class Members                                                            */
   /* ------------------------------------------------------------------------ */
 private:
   /// viscosity, viscous elastic modulus
   Real eta, Ev, E_inf;
 
   /// history of deviatoric stress
   InternalField<Real> stress_dev;
 
   /// Internal variable: history integral
   InternalField<Real> history_integral;
 
   /// Dissipated energy
   InternalField<Real> dissipated_energy;
 };
 
 } // namespace akantu
 
 #endif /* __AKANTU_MATERIAL_STANDARD_LINEAR_SOLID_DEVIATORIC_HH__ */
diff --git a/src/model/solid_mechanics/materials/plane_stress_toolbox.hh b/src/model/solid_mechanics/materials/plane_stress_toolbox.hh
index 1387b8f97..00c017adc 100644
--- a/src/model/solid_mechanics/materials/plane_stress_toolbox.hh
+++ b/src/model/solid_mechanics/materials/plane_stress_toolbox.hh
@@ -1,102 +1,103 @@
 /**
  * @file   plane_stress_toolbox.hh
  *
  * @author Daniel Pino Muñoz <daniel.pinomunoz@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Tue Sep 16 2014
- * @date last modification: Tue Aug 18 2015
+ * @date last modification: Tue Feb 20 2018
  *
  * @brief  Tools to implement the plane stress behavior in a material
  *
  * @section LICENSE
  *
- * Copyright  (©)  2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de Lausanne)
+ * 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
+ * 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
+ * A PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
+
 /* -------------------------------------------------------------------------- */
 #include "material.hh"
 /* -------------------------------------------------------------------------- */
 
 #ifndef __AKANTU_PLANE_STRESS_TOOLBOX_HH__
 #define __AKANTU_PLANE_STRESS_TOOLBOX_HH__
 
 namespace akantu {
 class SolidMechanicsModel;
 class FEEngine;
 } // akantu
 
 namespace akantu {
 
 /**
  * Empty class in dimensions different from 2
  * This class is only specialized for 2D in the tmpl file
  */
 template <UInt dim, class ParentMaterial = Material>
 class PlaneStressToolbox : public ParentMaterial {
   /* ------------------------------------------------------------------------ */
   /* Constructors/Destructors                                                 */
   /* ------------------------------------------------------------------------ */
 public:
   PlaneStressToolbox(SolidMechanicsModel & model, const ID & id = "")
       : ParentMaterial(model, id) {}
   PlaneStressToolbox(SolidMechanicsModel & model, UInt spatial_dimension,
                      const Mesh & mesh, FEEngine & fe_engine,
                      const ID & id = "")
       : ParentMaterial(model, spatial_dimension, mesh, fe_engine, id) {}
 
   ~PlaneStressToolbox() override = default;
 
 protected:
   void initialize();
 
 public:
   void computeAllCauchyStresses(GhostType ghost_type = _not_ghost) override {
     ParentMaterial::computeAllCauchyStresses(ghost_type);
   }
 
   virtual void computeCauchyStressPlaneStress(ElementType /*el_type*/,
                                               GhostType /*ghost_type*/) {
     AKANTU_DEBUG_IN();
 
     AKANTU_ERROR("The function \"computeCauchyStressPlaneStress\" can "
                  "only be used in 2D Plane stress problems, which means "
                  "that you made a mistake somewhere!! ");
 
     AKANTU_DEBUG_OUT();
   }
 
   virtual void computeThirdAxisDeformation(ElementType, GhostType) {}
 
 protected:
   bool initialize_third_axis_deformation{false};
 };
 
 #define AKANTU_PLANE_STRESS_TOOL_SPEC(dim)                                     \
   template <>                                                                  \
   inline PlaneStressToolbox<dim, Material>::PlaneStressToolbox(                \
       SolidMechanicsModel & model, const ID & id)                              \
       : Material(model, id) {}
 
 AKANTU_PLANE_STRESS_TOOL_SPEC(1)
 AKANTU_PLANE_STRESS_TOOL_SPEC(3)
 
 } // namespace akantu
 
 #include "plane_stress_toolbox_tmpl.hh"
 
 #endif /* __AKANTU_PLANE_STRESS_TOOLBOX_HH__ */
diff --git a/src/model/solid_mechanics/materials/plane_stress_toolbox_tmpl.hh b/src/model/solid_mechanics/materials/plane_stress_toolbox_tmpl.hh
index 9ef31be49..5cfdcdf1e 100644
--- a/src/model/solid_mechanics/materials/plane_stress_toolbox_tmpl.hh
+++ b/src/model/solid_mechanics/materials/plane_stress_toolbox_tmpl.hh
@@ -1,169 +1,169 @@
 /**
  * @file   plane_stress_toolbox_tmpl.hh
  *
  * @author Daniel Pino Muñoz <daniel.pinomunoz@epfl.ch>
  *
  * @date creation: Tue Sep 16 2014
- * @date last modification: Tue Aug 18 2015
+ * @date last modification: Wed Nov 08 2017
  *
  * @brief  2D specialization of the akantu::PlaneStressToolbox class
  *
  * @section LICENSE
  *
- * Copyright  (©)  2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de Lausanne)
+ * 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
+ * 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
+ * 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_PLANE_STRESS_TOOLBOX_TMPL_HH__
 #define __AKANTU_PLANE_STRESS_TOOLBOX_TMPL_HH__
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 template <class ParentMaterial>
 class PlaneStressToolbox<2, ParentMaterial> : public ParentMaterial {
   /* ------------------------------------------------------------------------ */
   /* Constructors/Destructors                                                 */
   /* ------------------------------------------------------------------------ */
 public:
   PlaneStressToolbox(SolidMechanicsModel & model, const ID & id = "");
   PlaneStressToolbox(SolidMechanicsModel & model, UInt dim, const Mesh & mesh,
                      FEEngine & fe_engine, const ID & id = "");
 
   ~PlaneStressToolbox() override = default;
 
   AKANTU_GET_MACRO_BY_ELEMENT_TYPE_CONST(ThirdAxisDeformation,
                                          third_axis_deformation, Real);
 
 protected:
   void initialize() {
     this->registerParam("Plane_Stress", plane_stress, false, _pat_parsmod,
                         "Is plane stress");
   }
 
   /* ------------------------------------------------------------------------ */
   /* Methods                                                                  */
   /* ------------------------------------------------------------------------ */
 public:
   /* ------------------------------------------------------------------------ */
   void initMaterial() override {
 
     ParentMaterial::initMaterial();
     if (this->plane_stress && this->initialize_third_axis_deformation) {
       this->third_axis_deformation.initialize(1);
       this->third_axis_deformation.resize();
     }
   }
 
   /* ------------------------------------------------------------------------ */
   void computeStress(ElementType el_type, GhostType ghost_type) override {
     ParentMaterial::computeStress(el_type, ghost_type);
     if (this->plane_stress)
       computeThirdAxisDeformation(el_type, ghost_type);
   }
 
   /* ------------------------------------------------------------------------ */
   virtual void computeThirdAxisDeformation(ElementType, GhostType) {}
 
   /// Computation of Cauchy stress tensor in the case of finite deformation
   void computeAllCauchyStresses(GhostType ghost_type = _not_ghost) override {
     AKANTU_DEBUG_IN();
 
     if (this->plane_stress) {
 
       AKANTU_DEBUG_ASSERT(this->finite_deformation,
                           "The Cauchy stress can only be computed if you are "
                           "working in finite deformation.");
 
       // resizeInternalArray(stress);
 
       Mesh::type_iterator it = this->fem.getMesh().firstType(2, ghost_type);
       Mesh::type_iterator last_type =
           this->fem.getMesh().lastType(2, ghost_type);
 
       for (; it != last_type; ++it)
         this->computeCauchyStressPlaneStress(*it, ghost_type);
     } else
       ParentMaterial::computeAllCauchyStresses(ghost_type);
 
     AKANTU_DEBUG_OUT();
   }
 
   virtual void
   computeCauchyStressPlaneStress(__attribute__((unused)) ElementType el_type,
                                  __attribute__((unused))
                                  GhostType ghost_type = _not_ghost){};
 
   /* ------------------------------------------------------------------------ */
   /* Accessors                                                                */
   /* ------------------------------------------------------------------------ */
 public:
   /* ------------------------------------------------------------------------ */
   /* Class Members                                                            */
   /* ------------------------------------------------------------------------ */
 protected:
   /// third axis strain measure value
   InternalField<Real> third_axis_deformation;
 
   /// Plane stress or plane strain
   bool plane_stress;
 
   /// For non linear materials, the \epsilon_{zz} might be required
   bool initialize_third_axis_deformation;
 };
 
 template <class ParentMaterial>
 inline PlaneStressToolbox<2, ParentMaterial>::PlaneStressToolbox(
     SolidMechanicsModel & model, const ID & id)
     : ParentMaterial(model, id),
       third_axis_deformation("third_axis_deformation", *this),
       plane_stress(false), initialize_third_axis_deformation(false) {
 
   /// @todo Plane_Stress should not be possible to be modified after
   /// initMaterial (but before)
   this->initialize();
 }
 
 template <class ParentMaterial>
 inline PlaneStressToolbox<2, ParentMaterial>::PlaneStressToolbox(
     SolidMechanicsModel & model, UInt dim, const Mesh & mesh,
     FEEngine & fe_engine, const ID & id)
     : ParentMaterial(model, dim, mesh, fe_engine, id),
       third_axis_deformation("third_axis_deformation", *this, dim, fe_engine,
                              this->element_filter),
       plane_stress(false), initialize_third_axis_deformation(false) {
   this->initialize();
 }
 
 template <>
 inline PlaneStressToolbox<2, Material>::PlaneStressToolbox(
     SolidMechanicsModel & model, const ID & id)
     : Material(model, id),
       third_axis_deformation("third_axis_deformation", *this),
       plane_stress(false), initialize_third_axis_deformation(false) {
 
   /// @todo Plane_Stress should not be possible to be modified after
   /// initMaterial (but before)
   this->registerParam("Plane_Stress", plane_stress, false, _pat_parsmod,
                       "Is plane stress");
 }
 
 } // namespace akantu
 
 #endif /* __AKANTU_PLANE_STRESS_TOOLBOX_TMPL_HH__ */
diff --git a/src/model/solid_mechanics/materials/random_internal_field.hh b/src/model/solid_mechanics/materials/random_internal_field.hh
index ebb9c03c6..a6511b6c9 100644
--- a/src/model/solid_mechanics/materials/random_internal_field.hh
+++ b/src/model/solid_mechanics/materials/random_internal_field.hh
@@ -1,105 +1,104 @@
 /**
  * @file   random_internal_field.hh
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Fri Jun 18 2010
- * @date last modification: Tue Dec 08 2015
+ * @date last modification: Wed Nov 08 2017
  *
  * @brief  Random internal material parameter
  *
  * @section LICENSE
  *
- * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
- * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
- * Solides)
+ * 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
+ * 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
+ * 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 "aka_random_generator.hh"
 #include "internal_field.hh"
 /* -------------------------------------------------------------------------- */
 
 #ifndef __AKANTU_RANDOM_INTERNAL_FIELD_HH__
 #define __AKANTU_RANDOM_INTERNAL_FIELD_HH__
 
 namespace akantu {
 
 /**
  * class for the internal fields of materials with a random
  * distribution
  */
 template <typename T, template <typename> class BaseField = InternalField,
           template <typename> class Generator = RandomGenerator>
 class RandomInternalField : public BaseField<T> {
   /* ------------------------------------------------------------------------ */
   /* Constructors/Destructors                                                 */
   /* ------------------------------------------------------------------------ */
 public:
   RandomInternalField(const ID & id, Material & material);
 
   ~RandomInternalField() override;
 
   /* ------------------------------------------------------------------------ */
   /* Methods                                                                  */
   /* ------------------------------------------------------------------------ */
   RandomInternalField operator=(const RandomInternalField &) = delete;
 
 public:
   AKANTU_GET_MACRO(RandomParameter, random_parameter, const RandomParameter<T>);
 
   /// initialize the field to a given number of component
   void initialize(UInt nb_component) override;
 
   /// set the field to a given value
   void setDefaultValue(const T & value) override;
 
   /// set the specified random distribution to a given parameter
   void setRandomDistribution(const RandomParameter<T> & param);
 
   /// print the content
   void printself(std::ostream & stream, int indent = 0) const override;
 
 protected:
   void setArrayValues(T * begin, T * end) override;
 
   /* ------------------------------------------------------------------------ */
   /* Accessors                                                                */
   /* ------------------------------------------------------------------------ */
 public:
   inline operator Real() const;
 
   /* ------------------------------------------------------------------------ */
   /* Class Members                                                            */
   /* ------------------------------------------------------------------------ */
 private:
   /// random parameter containing the distribution and base value
   RandomParameter<T> random_parameter;
 };
 
 /// standard output stream operator
 template <typename T>
 inline std::ostream & operator<<(std::ostream & stream,
                                  const RandomInternalField<T> & _this) {
   _this.printself(stream);
   return stream;
 }
 
 } // akantu
 
 #endif /* __AKANTU_RANDOM_INTERNAL_FIELD_HH__ */
diff --git a/src/model/solid_mechanics/materials/random_internal_field_tmpl.hh b/src/model/solid_mechanics/materials/random_internal_field_tmpl.hh
index ed64c4371..4f2769960 100644
--- a/src/model/solid_mechanics/materials/random_internal_field_tmpl.hh
+++ b/src/model/solid_mechanics/materials/random_internal_field_tmpl.hh
@@ -1,125 +1,125 @@
 /**
  * @file   random_internal_field_tmpl.hh
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Wed Nov 13 2013
- * @date last modification: Tue Dec 08 2015
+ * @date last modification: Thu Feb 08 2018
  *
  * @brief  Random internal material parameter implementation
  *
  * @section LICENSE
  *
- * Copyright  (©)  2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de Lausanne)
+ * 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
+ * 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
+ * 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 "aka_random_generator.hh"
 #include "internal_field_tmpl.hh"
 
 /* -------------------------------------------------------------------------- */
 
 #ifndef __AKANTU_RANDOM_INTERNAL_FIELD_TMPL_HH__
 #define __AKANTU_RANDOM_INTERNAL_FIELD_TMPL_HH__
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 template <typename T, template <typename> class BaseField,
           template <typename> class Generator>
 RandomInternalField<T, BaseField, Generator>::RandomInternalField(
     const ID & id, Material & material)
     : BaseField<T>(id, material), random_parameter(T()) {}
 
 /* -------------------------------------------------------------------------- */
 template <typename T, template <typename> class BaseField,
           template <typename> class Generator>
 RandomInternalField<T, BaseField, Generator>::~RandomInternalField() = default;
 
 /* -------------------------------------------------------------------------- */
 template <typename T, template <typename> class BaseField,
           template <typename> class Generator>
 void RandomInternalField<T, BaseField, Generator>::initialize(
     UInt nb_component) {
   this->internalInitialize(nb_component);
 }
 
 /* ------------------------------------------------------------------------ */
 template <typename T, template <typename> class BaseField,
           template <typename> class Generator>
 void RandomInternalField<T, BaseField, Generator>::setDefaultValue(
     const T & value) {
   random_parameter.setBaseValue(value);
   this->reset();
 }
 
 /* ------------------------------------------------------------------------ */
 template <typename T, template <typename> class BaseField,
           template <typename> class Generator>
 void RandomInternalField<T, BaseField, Generator>::setRandomDistribution(
     const RandomParameter<T> & param) {
   random_parameter = param;
   this->reset();
 }
 
 /* ------------------------------------------------------------------------ */
 template <typename T, template <typename> class BaseField,
           template <typename> class Generator>
 void RandomInternalField<T, BaseField, Generator>::printself(
     std::ostream & stream, int indent[[gnu::unused]]) const {
   stream << "RandomInternalField [ ";
   random_parameter.printself(stream);
   stream << " ]";
 #if !defined(AKANTU_NDEBUG)
   if (AKANTU_DEBUG_TEST(dblDump)) {
     stream << std::endl;
     InternalField<T>::printself(stream, indent);
   }
 #endif
 }
 
 /* -------------------------------------------------------------------------- */
 template <typename T, template <typename> class BaseField,
           template <typename> class Generator>
 void RandomInternalField<T, BaseField, Generator>::setArrayValues(T * begin,
                                                                   T * end) {
   random_parameter.template setValues<Generator>(begin, end);
 }
 
 /* -------------------------------------------------------------------------- */
 template <typename T, template <typename> class BaseField,
           template <typename> class Generator>
 inline RandomInternalField<T, BaseField, Generator>::operator Real() const {
   return random_parameter.getBaseValue();
 }
 
 /* -------------------------------------------------------------------------- */
 template <>
 inline void ParameterTyped<RandomInternalField<Real>>::setAuto(
     const ParserParameter & in_param) {
   Parameter::setAuto(in_param);
   RandomParameter<Real> r = in_param;
   param.setRandomDistribution(r);
 }
 
 /* -------------------------------------------------------------------------- */
 
 } // akantu
 
 #endif /* __AKANTU_RANDOM_INTERNAL_FIELD_TMPL_HH__ */
diff --git a/src/model/solid_mechanics/materials/weight_functions/damaged_weight_function.hh b/src/model/solid_mechanics/materials/weight_functions/damaged_weight_function.hh
index 7ffbfdbf3..95d494d05 100644
--- a/src/model/solid_mechanics/materials/weight_functions/damaged_weight_function.hh
+++ b/src/model/solid_mechanics/materials/weight_functions/damaged_weight_function.hh
@@ -1,82 +1,82 @@
 /**
  * @file   damaged_weight_function.hh
  *
+ * @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  * @author Cyprien Wolff <cyprien.wolff@epfl.ch>
  *
  * @date creation: Fri Jun 18 2010
- * @date last modification: Thu Oct 15 2015
+ * @date last modification: Wed Nov 08 2017
  *
  * @brief  Damaged weight function for non local materials
  *
  * @section LICENSE
  *
- * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
- * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
- * Solides)
+ * 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
+ * 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
+ * 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 "base_weight_function.hh"
 /* -------------------------------------------------------------------------- */
 #ifndef __AKANTU_DAMAGED_WEIGHT_FUNCTION_HH__
 #define __AKANTU_DAMAGED_WEIGHT_FUNCTION_HH__
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 /*  Damage weight function                                                    */
 /* -------------------------------------------------------------------------- */
 class DamagedWeightFunction : public BaseWeightFunction {
 public:
   /* ------------------------------------------------------------------------ */
   /* Constructors/Destructors                                                 */
   /* ------------------------------------------------------------------------ */
   DamagedWeightFunction(NonLocalManager & manager)
       : BaseWeightFunction(manager, "damaged"), damage(nullptr) {
     this->init();
   }
 
   /* --------------------------------------------------------------------------
    */
   /* Base Weight Function inherited methods */
   /* --------------------------------------------------------------------------
    */
 
   /// set the pointers of internals to the right flattend version
   void init() override;
 
   inline Real operator()(Real r,
                          const __attribute__((unused)) IntegrationPoint & q1,
                          const IntegrationPoint & q2);
 
 private:
   /* ------------------------------------------------------------------------ */
   /* Class Members                                                            */
   /* ------------------------------------------------------------------------ */
 
   /// internal pointer to the current damage vector
   ElementTypeMapReal * damage;
 };
 
 #if defined(AKANTU_INCLUDE_INLINE_IMPL)
 #include "damaged_weight_function_inline_impl.cc"
 #endif
 
 } // namespace akantu
 
 #endif /* __AKANTU_DAMAGED_WEIGHT_FUNCTION_HH__ */
diff --git a/src/model/solid_mechanics/materials/weight_functions/damaged_weight_function_inline_impl.cc b/src/model/solid_mechanics/materials/weight_functions/damaged_weight_function_inline_impl.cc
index 8752fe003..c6595d2a9 100644
--- a/src/model/solid_mechanics/materials/weight_functions/damaged_weight_function_inline_impl.cc
+++ b/src/model/solid_mechanics/materials/weight_functions/damaged_weight_function_inline_impl.cc
@@ -1,75 +1,75 @@
 /**
  * @file   damaged_weight_function_inline_impl.cc
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  * @author Cyprien Wolff <cyprien.wolff@epfl.ch>
  *
  * @date creation: Mon Aug 24 2015
- * @date last modification: Thu Oct 15 2015
+ * @date last modification: Wed Feb 03 2016
  *
  * @brief  Implementation of inline function of damaged weight function
  *
  * @section LICENSE
  *
- * Copyright (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne) Laboratory
- * (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * Copyright (©) 2015-2018 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
- * terms  of the  GNU Lesser  General Public  License as  published by  the Free
+ * 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
+ * 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/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 inline Real DamagedWeightFunction::operator()(Real r,
                                               const __attribute__((unused))
                                               IntegrationPoint & q1,
                                               const IntegrationPoint & q2) {
   /// compute the weight
   UInt quad = q2.global_num;
   Array<Real> & dam_array = (*this->damage)(q2.type, q2.ghost_type);
   Real D = dam_array(quad);
   Real Radius_t = 0;
   Real Radius_init = this->R2;
 
   //    if(D <= 0.5)
   //      {
   //	Radius_t = 2*D*Radius_init;
   //      }
   //    else
   //      {
   //	Radius_t = 2*Radius_init*(1-D);
   //      }
   //
 
   Radius_t = Radius_init * (1 - D);
 
   Radius_init *= Radius_init;
   Radius_t *= Radius_t;
 
   if (Radius_t < Math::getTolerance()) {
     Radius_t = 0.001 * Radius_init;
   }
 
   Real expb =
       (2 * std::log(0.51)) / (std::log(1.0 - 0.49 * Radius_t / Radius_init));
   Int expb_floor = std::floor(expb);
   Real b = expb_floor + expb_floor % 2;
   Real alpha = std::max(0., 1. - r * r / Radius_init);
   Real w = std::pow(alpha, b);
   return w;
 }
 
 /* -------------------------------------------------------------------------- */
 inline void DamagedWeightFunction::init() {
   this->damage = &(this->manager.registerWeightFunctionInternal("damage"));
 }
diff --git a/src/model/solid_mechanics/materials/weight_functions/remove_damaged_weight_function.hh b/src/model/solid_mechanics/materials/weight_functions/remove_damaged_weight_function.hh
index 3a5ca0524..b79e308bf 100644
--- a/src/model/solid_mechanics/materials/weight_functions/remove_damaged_weight_function.hh
+++ b/src/model/solid_mechanics/materials/weight_functions/remove_damaged_weight_function.hh
@@ -1,96 +1,96 @@
 /**
  * @file   remove_damaged_weight_function.hh
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  * @author Cyprien Wolff <cyprien.wolff@epfl.ch>
  *
  * @date creation: Mon Aug 24 2015
- * @date last modification: Thu Oct 15 2015
+ * @date last modification: Wed Nov 08 2017
  *
  * @brief  Removed damaged weight function for non local materials
  *
  * @section LICENSE
  *
- * Copyright (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne) Laboratory
- * (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * Copyright (©) 2015-2018 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
- * terms  of the  GNU Lesser  General Public  License as  published by  the Free
+ * 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
+ * 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 "base_weight_function.hh"
 /* -------------------------------------------------------------------------- */
 #ifndef __AKANTU_REMOVE_DAMAGED_WEIGHT_FUNCTION_HH__
 #define __AKANTU_REMOVE_DAMAGED_WEIGHT_FUNCTION_HH__
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 /*  Remove damaged weight function                                            */
 /* -------------------------------------------------------------------------- */
 class RemoveDamagedWeightFunction : public BaseWeightFunction {
 public:
   /* ------------------------------------------------------------------------ */
   /* Constructors/Destructors                                                 */
   /* ------------------------------------------------------------------------ */
   RemoveDamagedWeightFunction(NonLocalManager & manager)
       : BaseWeightFunction(manager, "remove_damaged"), damage(nullptr) {
     this->registerParam("damage_limit", this->damage_limit, 1., _pat_parsable,
                         "Damage Threshold");
     this->init();
   }
 
   /* --------------------------------------------------------------------------
    */
   /* Base Weight Function inherited methods */
   /* --------------------------------------------------------------------------
    */
 
   inline void init() override;
 
   inline Real operator()(Real r, const IntegrationPoint & q1,
                          const IntegrationPoint & q2);
 
   /* ------------------------------------------------------------------------ */
   /* Data Accessor inherited members                                          */
   /* ------------------------------------------------------------------------ */
 
   inline UInt getNbData(const Array<Element> & elements,
                         const SynchronizationTag & tag) const override;
 
   inline void packData(CommunicationBuffer & buffer,
                        const Array<Element> & elements,
                        const SynchronizationTag & tag) const override;
 
   inline void unpackData(CommunicationBuffer & buffer,
                          const Array<Element> & elements,
                          const SynchronizationTag & tag) override;
 
 private:
   /* ------------------------------------------------------------------------ */
   /* Class Members                                                            */
   /* ------------------------------------------------------------------------ */
   /// limit at which a point is considered as complitely broken
   Real damage_limit;
 
   /// internal pointer to the current damage vector
   ElementTypeMapReal * damage;
 };
 
 } // namespace akantu
 
 #include "remove_damaged_weight_function_inline_impl.cc"
 
 #endif /* __AKANTU_REMOVE_DAMAGED_WEIGHT_FUNCTION_HH__ */
diff --git a/src/model/solid_mechanics/materials/weight_functions/remove_damaged_weight_function_inline_impl.cc b/src/model/solid_mechanics/materials/weight_functions/remove_damaged_weight_function_inline_impl.cc
index 326454778..ea10a3db2 100644
--- a/src/model/solid_mechanics/materials/weight_functions/remove_damaged_weight_function_inline_impl.cc
+++ b/src/model/solid_mechanics/materials/weight_functions/remove_damaged_weight_function_inline_impl.cc
@@ -1,103 +1,104 @@
 /**
  * @file   remove_damaged_weight_function_inline_impl.cc
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  * @author Cyprien Wolff <cyprien.wolff@epfl.ch>
  *
  * @date creation: Mon Aug 24 2015
- * @date last modification: Wed Oct 21 2015
+ * @date last modification: Thu Jul 06 2017
  *
  * @brief  Implementation of inline function of remove damaged weight function
  *
  * @section LICENSE
  *
- * Copyright (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne) Laboratory
- * (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * Copyright (©) 2015-2018 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
- * terms  of the  GNU Lesser  General Public  License as  published by  the Free
+ * 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
+ * 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 "remove_damaged_weight_function.hh"
 /* -------------------------------------------------------------------------- */
 
 #ifndef __AKANTU_REMOVE_DAMAGED_WEIGHT_FUNCTION_INLINE_IMPL_CC__
 #define __AKANTU_REMOVE_DAMAGED_WEIGHT_FUNCTION_INLINE_IMPL_CC__
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 inline Real RemoveDamagedWeightFunction::
 operator()(Real r, const __attribute__((unused)) IntegrationPoint & q1,
            const IntegrationPoint & q2) {
   /// compute the weight
   UInt quad = q2.global_num;
 
   if (q1 == q2)
     return 1.;
 
   Array<Real> & dam_array = (*this->damage)(q2.type, q2.ghost_type);
   Real D = dam_array(quad);
   Real w = 0.;
   if (D < damage_limit * (1 - Math::getTolerance())) {
     Real alpha = std::max(0., 1. - r * r / this->R2);
     w = alpha * alpha;
   }
   return w;
 }
 
 /* -------------------------------------------------------------------------- */
 inline void RemoveDamagedWeightFunction::init() {
   this->damage = &(this->manager.registerWeightFunctionInternal("damage"));
 }
 
 /* -------------------------------------------------------------------------- */
 inline UInt
 RemoveDamagedWeightFunction::getNbData(const Array<Element> & elements,
                                        const SynchronizationTag & tag) const {
 
   if (tag == _gst_mnl_weight)
     return this->manager.getModel().getNbIntegrationPoints(elements) *
            sizeof(Real);
 
   return 0;
 }
 
 /* -------------------------------------------------------------------------- */
 inline void
 RemoveDamagedWeightFunction::packData(CommunicationBuffer & buffer,
                                       const Array<Element> & elements,
                                       const SynchronizationTag & tag) const {
   if (tag == _gst_mnl_weight) {
     DataAccessor<Element>::packElementalDataHelper<Real>(
         *damage, buffer, elements, true,
         this->manager.getModel().getFEEngine());
   }
 }
 
 /* -------------------------------------------------------------------------- */
 inline void
 RemoveDamagedWeightFunction::unpackData(CommunicationBuffer & buffer,
                                         const Array<Element> & elements,
                                         const SynchronizationTag & tag) {
   if (tag == _gst_mnl_weight) {
     DataAccessor<Element>::unpackElementalDataHelper<Real>(
         *damage, buffer, elements, true,
         this->manager.getModel().getFEEngine());
   }
 }
 
 } // namespace akantu
 
 #endif /* __AKANTU_REMOVE_DAMAGED_WEIGHT_FUNCTION_INLINE_IMPL_CC__ */
diff --git a/src/model/solid_mechanics/materials/weight_functions/remove_damaged_with_damage_rate_weight_function.hh b/src/model/solid_mechanics/materials/weight_functions/remove_damaged_with_damage_rate_weight_function.hh
index e4664c861..fc956fa1a 100644
--- a/src/model/solid_mechanics/materials/weight_functions/remove_damaged_with_damage_rate_weight_function.hh
+++ b/src/model/solid_mechanics/materials/weight_functions/remove_damaged_with_damage_rate_weight_function.hh
@@ -1,86 +1,85 @@
 /**
  * @file   remove_damaged_with_damage_rate_weight_function.hh
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  * @author Cyprien Wolff <cyprien.wolff@epfl.ch>
  *
  * @date creation: Fri Jun 18 2010
- * @date last modification: Thu Oct 15 2015
+ * @date last modification: Wed Nov 08 2017
  *
  * @brief  Removed damaged weight function for non local materials
  *
  * @section LICENSE
  *
- * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
- * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
- * Solides)
+ * 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
+ * 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
+ * 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 "base_weight_function.hh"
 /* -------------------------------------------------------------------------- */
 #ifndef __AKANTU_REMOVE_DAMAGED_WITH_DAMAGE_RATE_WEIGHT_FUNCTION_HH__
 #define __AKANTU_REMOVE_DAMAGED_WITH_DAMAGE_RATE_WEIGHT_FUNCTION_HH__
 
 namespace akantu {
 /* -------------------------------------------------------------------------- */
 /* Remove damaged with damage rate weight function */
 /* -------------------------------------------------------------------------- */
 
 class RemoveDamagedWithDamageRateWeightFunction : public BaseWeightFunction {
 public:
   /* ------------------------------------------------------------------------ */
   /* Constructors/Destructors                                                 */
   /* ------------------------------------------------------------------------ */
   RemoveDamagedWithDamageRateWeightFunction(NonLocalManager & manager)
       : BaseWeightFunction(manager, "remove_damage_with_damage_rate"),
         damage_with_damage_rate(nullptr) {
     this->registerParam<Real>("damage_limit",
                               this->damage_limit_with_damage_rate, 1,
                               _pat_parsable, "Damage Threshold");
     this->init();
   }
 
   /* --------------------------------------------------------------------------
    */
   /* Base Weight Function inherited methods */
   /* --------------------------------------------------------------------------
    */
   inline Real operator()(Real r,
                          const __attribute__((unused)) IntegrationPoint & q1,
                          const IntegrationPoint & q2);
 
   inline void init() override;
 
   /* ------------------------------------------------------------------------ */
   /* Class Members                                                            */
   /* ------------------------------------------------------------------------ */
 private:
   /// limit at which a point is considered as complitely broken
   Real damage_limit_with_damage_rate;
 
   /// internal pointer to the current damage vector
   ElementTypeMapReal * damage_with_damage_rate;
 };
 
 #if defined(AKANTU_INCLUDE_INLINE_IMPL)
 #include "remove_damaged_with_damage_rate_weight_function_inline_impl.cc"
 #endif
 
 } // akantu
 
 #endif /* __AKANTU_REMOVE_DAMAGED_WITH_DAMAGE_WEIGHT_FUNCTION_HH__ */
diff --git a/src/model/solid_mechanics/materials/weight_functions/remove_damaged_with_damage_rate_weight_function_inline_impl.cc b/src/model/solid_mechanics/materials/weight_functions/remove_damaged_with_damage_rate_weight_function_inline_impl.cc
index 2c9b3d939..f36ed8b8b 100644
--- a/src/model/solid_mechanics/materials/weight_functions/remove_damaged_with_damage_rate_weight_function_inline_impl.cc
+++ b/src/model/solid_mechanics/materials/weight_functions/remove_damaged_with_damage_rate_weight_function_inline_impl.cc
@@ -1,62 +1,62 @@
 /**
  * @file   remove_damaged_with_damage_rate_weight_function_inline_impl.cc
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  * @author Cyprien Wolff <cyprien.wolff@epfl.ch>
  *
  * @date creation: Mon Aug 24 2015
- * @date last modification: Thu Oct 15 2015
+ * @date last modification: Wed Feb 03 2016
  *
  * @brief  Implementation of inline function of remove damaged with
  * damage rate weight function
  *
  * @section LICENSE
  *
- * Copyright (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne) Laboratory
- * (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * Copyright (©) 2015-2018 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
- * terms  of the  GNU Lesser  General Public  License as  published by  the Free
+ * 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
+ * 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/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 inline void RemoveDamagedWithDamageRateWeightFunction::init() {
   this->damage_with_damage_rate =
       &(this->manager.registerWeightFunctionInternal("damage-rate"));
 }
 
 /* -------------------------------------------------------------------------- */
 inline Real RemoveDamagedWithDamageRateWeightFunction::
 operator()(Real r, const __attribute__((unused)) IntegrationPoint & q1,
 
            const IntegrationPoint & q2) {
   /// compute the weight
   UInt quad = q2.global_num;
 
   if (q1.global_num == quad)
     return 1.;
 
   Array<Real> & dam_array =
       (*this->damage_with_damage_rate)(q2.type, q2.ghost_type);
   Real D = dam_array(quad);
   Real w = 0.;
   Real alphaexp = 1.;
   Real betaexp = 2.;
   if (D < damage_limit_with_damage_rate) {
     Real alpha = std::max(0., 1. - pow((r * r / this->R2), alphaexp));
     w = pow(alpha, betaexp);
   }
 
   return w;
 }
diff --git a/src/model/solid_mechanics/materials/weight_functions/stress_based_weight_function.cc b/src/model/solid_mechanics/materials/weight_functions/stress_based_weight_function.cc
index 992297710..e3913c320 100644
--- a/src/model/solid_mechanics/materials/weight_functions/stress_based_weight_function.cc
+++ b/src/model/solid_mechanics/materials/weight_functions/stress_based_weight_function.cc
@@ -1,123 +1,123 @@
 /**
  * @file   stress_based_weight_function.cc
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Mon Aug 24 2015
- * @date last modification: Wed Oct 07 2015
+ * @date last modification: Tue Feb 20 2018
  *
  * @brief  implementation of the stres based weight function classes
  *
  * @section LICENSE
  *
- * Copyright (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne) Laboratory
- * (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * Copyright (©) 2015-2018 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
- * terms  of the  GNU Lesser  General Public  License as  published by  the Free
+ * 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
+ * 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 "stress_based_weight_function.hh"
 namespace akantu {
 /* -------------------------------------------------------------------------- */
 StressBasedWeightFunction::StressBasedWeightFunction(NonLocalManager & manager)
     : BaseWeightFunction(manager, "stress_based")
 // stress_diag("stress_diag", material), selected_stress_diag(NULL),
 // stress_base("stress_base", material), selected_stress_base(NULL),
 // characteristic_size("lc", material),  selected_characteristic_size(NULL)
 {
 
   // this->registerParam("ft", this->ft, 0., _pat_parsable, "Tensile strength");
   // stress_diag.initialize(spatial_dimension);
   // stress_base.initialize(spatial_dimension * spatial_dimension);
   // characteristic_size.initialize(1);
 }
 
 /* -------------------------------------------------------------------------- */
 /// During intialization the characteristic sizes for all quadrature
 /// points are computed
 void StressBasedWeightFunction::init() {
   // const Mesh & mesh = this->material.getModel().getFEEngine().getMesh();
   // for (UInt g = _not_ghost; g <= _ghost; ++g) {
   //   GhostType gt = GhostType(g);
   //   Mesh::type_iterator it = mesh.firstType(spatial_dimension, gt);
   //   Mesh::type_iterator last_type = mesh.lastType(spatial_dimension, gt);
   //   for(; it != last_type; ++it) {
   //     UInt nb_quadrature_points =
   // 	this->material.getModel().getFEEngine().getNbQuadraturePoints(*it, gt);
   //     const Array<UInt> & element_filter =
   //     this->material.getElementFilter(*it, gt);
   //     UInt nb_element = element_filter.size();
 
   //     Array<Real> ones(nb_element*nb_quadrature_points, 1, 1.);
   //     Array<Real> & lc = characteristic_size(*it, gt);
   //     this->material.getModel().getFEEngine().integrateOnQuadraturePoints(ones,
   // 								     lc,
   // 								     1,
   // 								     *it,
   // 								     gt,
   // 								     element_filter);
 
   //     for (UInt q = 0;  q < nb_quadrature_points * nb_element; q++) {
   // 	lc(q) = pow(lc(q), 1./ Real(spatial_dimension));
   //     }
   //   }
   // }
 }
 
 /* -------------------------------------------------------------------------- */
 /// computation of principals stresses and principal directions
 void StressBasedWeightFunction::updatePrincipalStress(__attribute__((unused))
                                                       GhostType ghost_type) {
   //   AKANTU_DEBUG_IN();
 
   //   const Mesh & mesh = this->material.getModel().getFEEngine().getMesh();
 
   //   Mesh::type_iterator it = mesh.firstType(spatial_dimension, ghost_type);
   //   Mesh::type_iterator last_type = mesh.lastType(spatial_dimension,
   //   ghost_type);
   //   for(; it != last_type; ++it) {
   //     Array<Real>::const_matrix_iterator sigma =
   //       this->material.getStress(*it, ghost_type).begin(spatial_dimension,
   //       spatial_dimension);
   //     auto eigenvalues =
   //       stress_diag(*it, ghost_type).begin(spatial_dimension);
   //     auto eigenvalues_end =
   //       stress_diag(*it, ghost_type).end(spatial_dimension);
   //     Array<Real>::matrix_iterator eigenvector =
   //       stress_base(*it, ghost_type).begin(spatial_dimension,
   //       spatial_dimension);
 
   // #ifndef __trick__
   //     auto cl = characteristic_size(*it, ghost_type).begin();
   // #endif
   //     UInt q = 0;
   //     for(;eigenvalues != eigenvalues_end; ++sigma, ++eigenvalues,
   //     ++eigenvector, ++cl, ++q) {
   //       sigma->eig(*eigenvalues, *eigenvector);
   //       *eigenvalues /= ft;
   // #ifndef __trick__
   //       // specify a lower bound for principal stress based on the size of
   //       the element
   //       for (UInt i = 0; i < spatial_dimension; ++i) {
   //         (*eigenvalues)(i) = std::max(*cl / this->R, (*eigenvalues)(i));
   //       }
   // #endif
   //     }
   //   }
   //   AKANTU_DEBUG_OUT();
 }
 
 } // akantu
diff --git a/src/model/solid_mechanics/materials/weight_functions/stress_based_weight_function.hh b/src/model/solid_mechanics/materials/weight_functions/stress_based_weight_function.hh
index a2e1debd7..60897da5c 100644
--- a/src/model/solid_mechanics/materials/weight_functions/stress_based_weight_function.hh
+++ b/src/model/solid_mechanics/materials/weight_functions/stress_based_weight_function.hh
@@ -1,101 +1,101 @@
 /**
  * @file   stress_based_weight_function.hh
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  * @author Cyprien Wolff <cyprien.wolff@epfl.ch>
  *
  * @date creation: Mon Aug 24 2015
- * @date last modification: Thu Oct 15 2015
+ * @date last modification: Wed Nov 08 2017
  *
  * @brief  Removed damaged weight function for non local materials
  *
  * @section LICENSE
  *
- * Copyright (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne) Laboratory
- * (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * Copyright (©) 2015-2018 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
- * terms  of the  GNU Lesser  General Public  License as  published by  the Free
+ * 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
+ * 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 "base_weight_function.hh"
 /* -------------------------------------------------------------------------- */
 #ifndef __AKANTU_STRESS_BASED_WEIGHT_FUNCTION_HH__
 #define __AKANTU_STRESS_BASED_WEIGHT_FUNCTION_HH__
 
 namespace akantu {
 /* -------------------------------------------------------------------------- */
 /* Stress Based Weight */
 /* -------------------------------------------------------------------------- */
 /// based on based on Giry et al.: Stress-based nonlocal damage model,
 /// IJSS, 48, 2011
 class StressBasedWeightFunction : public BaseWeightFunction {
 public:
   /* ------------------------------------------------------------------------ */
   /* Class Members                                                            */
   /* ------------------------------------------------------------------------ */
   StressBasedWeightFunction(NonLocalManager & manager);
 
   /* --------------------------------------------------------------------------
    */
   /* Base Weight Function inherited methods */
   /* --------------------------------------------------------------------------
    */
   void init() override;
 
   inline void updateInternals() override;
 
   void updatePrincipalStress(GhostType ghost_type);
 
   inline void updateQuadraturePointsCoordinates(
       ElementTypeMapArray<Real> & quadrature_points_coordinates);
 
   inline Real operator()(Real r, const IntegrationPoint & q1,
                          const IntegrationPoint & q2);
 
   /// computation of ellipsoid
   inline Real computeRhoSquare(Real r, Vector<Real> & eigs,
                                Matrix<Real> & eigenvects, Vector<Real> & x_s);
 
 protected:
   inline void setInternal();
 
 private:
   /* ------------------------------------------------------------------------ */
   /* Class Members                                                            */
   /* ------------------------------------------------------------------------ */
   /// tensile strength
   Real ft;
 
   /// prinicipal stresses
   ElementTypeMapReal * stress_diag;
 
   /// for preselection of types (optimization)
   ElementTypeMapReal * selected_stress_diag;
 
   /// principal directions
   ElementTypeMapReal * stress_base;
 
   /// lenght intrinisic to the material
   ElementTypeMapReal * characteristic_size;
 };
 
 #if defined(AKANTU_INCLUDE_INLINE_IMPL)
 #include "stress_based_weight_function_inline_impl.cc"
 #endif
 
 } // akantu
 
 #endif /* __AKANTU_STRESS_BASED_WEIGHT_FUNCTION_HH__ */
diff --git a/src/model/solid_mechanics/materials/weight_functions/stress_based_weight_function_inline_impl.cc b/src/model/solid_mechanics/materials/weight_functions/stress_based_weight_function_inline_impl.cc
index 2990dd1d4..3ac8d4cb9 100644
--- a/src/model/solid_mechanics/materials/weight_functions/stress_based_weight_function_inline_impl.cc
+++ b/src/model/solid_mechanics/materials/weight_functions/stress_based_weight_function_inline_impl.cc
@@ -1,191 +1,190 @@
 /**
  * @file   stress_based_weight_function_inline_impl.cc
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  * @author Cyprien Wolff <cyprien.wolff@epfl.ch>
  *
  * @date creation: Fri Apr 13 2012
- * @date last modification: Thu Oct 15 2015
+ * @date last modification: Wed Feb 03 2016
  *
  * @brief  Implementation of inline function of remove damaged with
  * damage rate weight function
  *
  * @section LICENSE
  *
- * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
- * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
- * Solides)
+ * 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
+ * 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
+ * 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/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 inline void StressBasedWeightFunction::updateInternals() {
   // updatePrincipalStress(_not_ghost);
   // updatePrincipalStress(_ghost);
 }
 
 /* -------------------------------------------------------------------------- */
 // inline void StressBasedWeightFunction::selectType(ElementType type1,
 // 						  GhostType ghost_type1,
 // 						  ElementType type2,
 // 						  GhostType ghost_type2) {
 //   selected_stress_diag = &stress_diag(type2, ghost_type2);
 //   selected_stress_base = &stress_base(type2, ghost_type2);
 
 //   selected_characteristic_size = &characteristic_size(type1, ghost_type1);
 // }
 
 /* -------------------------------------------------------------------------- */
 inline Real StressBasedWeightFunction::computeRhoSquare(
     __attribute__((unused)) Real r, __attribute__((unused)) Vector<Real> & eigs,
     __attribute__((unused)) Matrix<Real> & eigenvects,
     __attribute__((unused)) Vector<Real> & x_s) {
   //   if (spatial_dimension == 1)
   //     return eigs[0];
   //   else if (spatial_dimension == 2) {
   //     Vector<Real> u1(eigenvects.storage(), 2);
   //     Real cos_t = x_s.dot(u1) / (x_s.norm() * u1.norm());
 
   //     Real cos_t_2;
   //     Real sin_t_2;
 
   //     Real sigma1_2 = eigs[0]*eigs[0];
   //     Real sigma2_2 = eigs[1]*eigs[1];
 
   // #ifdef __trick__
   //     Real zero = std::numeric_limits<Real>::epsilon();
   //     if(std::abs(cos_t) < zero) {
   //       cos_t_2 = 0;
   //       sin_t_2 = 1;
   //     } else {
   //       cos_t_2 = cos_t * cos_t;
   //       sin_t_2 = (1 - cos_t_2);
   //     }
 
   //     Real rhop1 = std::max(0., cos_t_2 / sigma1_2);
   //     Real rhop2 = std::max(0., sin_t_2 / sigma2_2);
   // #else
   //     cos_t_2 = cos_t * cos_t;
   //     sin_t_2 = (1 - cos_t_2);
 
   //     Real rhop1 = cos_t_2 / sigma1_2;
   //     Real rhop2 = sin_t_2 / sigma2_2;
   // #endif
 
   //     return 1./ (rhop1 + rhop2);
   //   } else if (spatial_dimension == 3) {
   //     Vector<Real> u1(eigenvects.storage() + 0*3, 3);
   //     //Vector<Real> u2(eigenvects.storage() + 1*3, 3);
   //     Vector<Real> u3(eigenvects.storage() + 2*3, 3);
 
   //     Real zero = std::numeric_limits<Real>::epsilon();
 
   //     Vector<Real> tmp(3);
   //     tmp.crossProduct(x_s, u3);
 
   //     Vector<Real> u3_C_x_s_C_u3(3);
   //     u3_C_x_s_C_u3.crossProduct(u3, tmp);
 
   //     Real norm_u3_C_x_s_C_u3 = u3_C_x_s_C_u3.norm();
   //     Real cos_t = 0.;
   //     if(std::abs(norm_u3_C_x_s_C_u3) > zero) {
   //       Real inv_norm_u3_C_x_s_C_u3 = 1. / norm_u3_C_x_s_C_u3;
   //       cos_t = u1.dot(u3_C_x_s_C_u3) * inv_norm_u3_C_x_s_C_u3;
   //     }
 
   //     Real cos_p = u3.dot(x_s) / r;
 
   //     Real cos_t_2;
   //     Real sin_t_2;
   //     Real cos_p_2;
   //     Real sin_p_2;
 
   //     Real sigma1_2 = eigs[0]*eigs[0];
   //     Real sigma2_2 = eigs[1]*eigs[1];
   //     Real sigma3_2 = eigs[2]*eigs[2];
 
   // #ifdef __trick__
   //     if(std::abs(cos_t) < zero) {
   //       cos_t_2 = 0;
   //       sin_t_2 = 1;
   //     } else {
   //       cos_t_2 = cos_t * cos_t;
   //       sin_t_2 = (1 - cos_t_2);
   //     }
 
   //     if(std::abs(cos_p) < zero) {
   //       cos_p_2 = 0;
   //       sin_p_2 = 1;
   //     } else {
   //       cos_p_2 = cos_p * cos_p;
   //       sin_p_2 = (1 - cos_p_2);
   //     }
 
   //     Real rhop1 = std::max(0., sin_p_2 * cos_t_2 / sigma1_2);
   //     Real rhop2 = std::max(0., sin_p_2 * sin_t_2 / sigma2_2);
   //     Real rhop3 = std::max(0., cos_p_2 / sigma3_2);
   // #else
   //     cos_t_2 = cos_t * cos_t;
   //     sin_t_2 = (1 - cos_t_2);
 
   //     cos_p_2 = cos_p * cos_p;
   //     sin_p_2 = (1 - cos_p_2);
 
   //     Real rhop1 = sin_p_2 * cos_t_2 / sigma1_2;
   //     Real rhop2 = sin_p_2 * sin_t_2 / sigma2_2;
   //     Real rhop3 = cos_p_2 / sigma3_2;
   // #endif
 
   //     return 1./ (rhop1 + rhop2 + rhop3);
   //   }
   return 0.;
 }
 
 /* -------------------------------------------------------------------------- */
 inline Real StressBasedWeightFunction::
 operator()(__attribute__((unused)) Real r,
            __attribute__((unused)) const IntegrationPoint & q1,
            __attribute__((unused)) const IntegrationPoint & q2) {
   // Real zero = std::numeric_limits<Real>::epsilon();
 
   // if(r < zero) return 1.; // means x and s are the same points
 
   // const Vector<Real> & x = q1.getPosition();
   // const Vector<Real> & s = q2.getPosition();
 
   // Vector<Real> eigs =
   //   selected_stress_diag->begin(spatial_dimension)[q2.global_num];
 
   // Matrix<Real> eigenvects =
   //   selected_stress_base->begin(spatial_dimension,
   //   spatial_dimension)[q2.global_num];
 
   // Real min_rho_lc = selected_characteristic_size->begin()[q1.global_num];
 
   // Vector<Real> x_s(spatial_dimension);
   // x_s  = x;
   // x_s -= s;
 
   // Real rho_2 = computeRhoSquare(r, eigs, eigenvects, x_s);
 
   // Real rho_lc_2 = std::max(this->R2 * rho_2, min_rho_lc*min_rho_lc);
 
   // // Real w = std::max(0., 1. - r*r / rho_lc_2);
   // // w = w*w;
   // Real w = exp(- 2*2*r*r / rho_lc_2);
   // return w;
   return 0.;
 }
diff --git a/src/model/solid_mechanics/solid_mechanics_model.cc b/src/model/solid_mechanics/solid_mechanics_model.cc
index ba8c9bcd2..61b9662de 100644
--- a/src/model/solid_mechanics/solid_mechanics_model.cc
+++ b/src/model/solid_mechanics/solid_mechanics_model.cc
@@ -1,1212 +1,1211 @@
 /**
  * @file   solid_mechanics_model.cc
  *
  * @author Ramin Aghababaei <ramin.aghababaei@epfl.ch>
  * @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
  * @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@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 Clement Roux <clement.roux@epfl.ch>
  * @author Marco Vocialta <marco.vocialta@epfl.ch>
  *
  * @date creation: Tue Jul 27 2010
- * @date last modification: Tue Jan 19 2016
+ * @date last modification: Wed Feb 21 2018
  *
  * @brief  Implementation of the SolidMechanicsModel class
  *
  * @section LICENSE
  *
- * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
- * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
- * Solides)
+ * 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
+ * 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
+ * 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 "integrator_gauss.hh"
 #include "shape_lagrange.hh"
 #include "solid_mechanics_model_tmpl.hh"
 
 #include "communicator.hh"
 #include "element_synchronizer.hh"
 #include "sparse_matrix.hh"
 #include "synchronizer_registry.hh"
 
 #include "dumpable_inline_impl.hh"
 #ifdef AKANTU_USE_IOHELPER
 #include "dumper_iohelper_paraview.hh"
 #endif
 
 #include "material_non_local.hh"
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 /**
  * A solid mechanics model need a mesh  and a dimension to be created. the model
  * by it  self can not  do a lot,  the good init  functions should be  called in
  * order to configure the model depending on what we want to do.
  *
  * @param  mesh mesh  representing  the model  we  want to  simulate
  * @param dim spatial  dimension of the problem, if dim =  0 (default value) the
  * dimension of the problem is assumed to be the on of the mesh
  * @param id an id to identify the model
  */
 SolidMechanicsModel::SolidMechanicsModel(Mesh & mesh, UInt dim, const ID & id,
                                          const MemoryID & memory_id,
                                          const ModelType model_type)
     : Model(mesh, model_type, dim, id, memory_id),
       BoundaryCondition<SolidMechanicsModel>(), f_m2a(1.0),
       displacement(nullptr), previous_displacement(nullptr),
       displacement_increment(nullptr), mass(nullptr), velocity(nullptr),
       acceleration(nullptr), external_force(nullptr), internal_force(nullptr),
       blocked_dofs(nullptr), current_position(nullptr),
       material_index("material index", id, memory_id),
       material_local_numbering("material local numbering", id, memory_id),
       increment_flag(false), are_materials_instantiated(false) {
   AKANTU_DEBUG_IN();
 
   this->registerFEEngineObject<MyFEEngineType>("SolidMechanicsFEEngine", mesh,
                                                Model::spatial_dimension);
 
 #if defined(AKANTU_USE_IOHELPER)
   this->mesh.registerDumper<DumperParaview>("paraview_all", id, true);
   this->mesh.addDumpMesh(mesh, Model::spatial_dimension, _not_ghost,
                          _ek_regular);
 #endif
 
   material_selector = std::make_shared<DefaultMaterialSelector>(material_index),
 
   this->initDOFManager();
 
   this->registerDataAccessor(*this);
 
   if (this->mesh.isDistributed()) {
     auto & synchronizer = this->mesh.getElementSynchronizer();
     this->registerSynchronizer(synchronizer, _gst_material_id);
     this->registerSynchronizer(synchronizer, _gst_smm_mass);
     this->registerSynchronizer(synchronizer, _gst_smm_stress);
     this->registerSynchronizer(synchronizer, _gst_smm_boundary);
     this->registerSynchronizer(synchronizer, _gst_for_dump);
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 SolidMechanicsModel::~SolidMechanicsModel() {
   AKANTU_DEBUG_IN();
 
   for (auto & internal : this->registered_internals) {
     delete internal.second;
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void SolidMechanicsModel::setTimeStep(Real time_step, const ID & solver_id) {
   Model::setTimeStep(time_step, solver_id);
 
 #if defined(AKANTU_USE_IOHELPER)
   this->mesh.getDumper().setTimeStep(time_step);
 #endif
 }
 
 /* -------------------------------------------------------------------------- */
 /* Initialization                                                             */
 /* -------------------------------------------------------------------------- */
 /**
  * This function groups  many of the initialization in on  function. For most of
  * basics  case the  function should  be  enough. The  functions initialize  the
  * model, the internal  vectors, set them to 0, and  depending on the parameters
  * it also initialize the explicit or implicit solver.
  *
  * @param material_file the  file containing the materials to  use
  * @param method the analysis method wanted.  See the akantu::AnalysisMethod for
  * the different possibilities
  */
 void SolidMechanicsModel::initFullImpl(const ModelOptions & options) {
   material_index.initialize(mesh, _element_kind = _ek_not_defined,
                             _default_value = UInt(-1), _with_nb_element = true);
   material_local_numbering.initialize(mesh, _element_kind = _ek_not_defined,
                                       _with_nb_element = true);
 
   Model::initFullImpl(options);
 
   // initialize pbc
   if (this->pbc_pair.size() != 0)
     this->initPBC();
 
   // initialize the materials
   if (this->parser.getLastParsedFile() != "") {
     this->instantiateMaterials();
   }
 
   this->initMaterials();
 
   this->initBC(*this, *displacement, *displacement_increment, *external_force);
 }
 
 /* -------------------------------------------------------------------------- */
 TimeStepSolverType SolidMechanicsModel::getDefaultSolverType() const {
   return _tsst_dynamic_lumped;
 }
 
 /* -------------------------------------------------------------------------- */
 ModelSolverOptions SolidMechanicsModel::getDefaultSolverOptions(
     const TimeStepSolverType & type) const {
   ModelSolverOptions options;
 
   switch (type) {
   case _tsst_dynamic_lumped: {
     options.non_linear_solver_type = _nls_lumped;
     options.integration_scheme_type["displacement"] = _ist_central_difference;
     options.solution_type["displacement"] = IntegrationScheme::_acceleration;
     break;
   }
   case _tsst_static: {
     options.non_linear_solver_type = _nls_newton_raphson;
     options.integration_scheme_type["displacement"] = _ist_pseudo_time;
     options.solution_type["displacement"] = IntegrationScheme::_not_defined;
     break;
   }
   case _tsst_dynamic: {
     if (this->method == _explicit_consistent_mass) {
       options.non_linear_solver_type = _nls_newton_raphson;
       options.integration_scheme_type["displacement"] = _ist_central_difference;
       options.solution_type["displacement"] = IntegrationScheme::_acceleration;
     } else {
       options.non_linear_solver_type = _nls_newton_raphson;
       options.integration_scheme_type["displacement"] = _ist_trapezoidal_rule_2;
       options.solution_type["displacement"] = IntegrationScheme::_displacement;
     }
     break;
   }
   default:
     AKANTU_EXCEPTION(type << " is not a valid time step solver type");
   }
 
   return options;
 }
 
 /* -------------------------------------------------------------------------- */
 std::tuple<ID, TimeStepSolverType>
 SolidMechanicsModel::getDefaultSolverID(const AnalysisMethod & method) {
   switch (method) {
   case _explicit_lumped_mass: {
     return std::make_tuple("explicit_lumped", _tsst_dynamic_lumped);
   }
   case _explicit_consistent_mass: {
     return std::make_tuple("explicit", _tsst_dynamic);
   }
   case _static: {
     return std::make_tuple("static", _tsst_static);
   }
   case _implicit_dynamic: {
     return std::make_tuple("implicit", _tsst_dynamic);
   }
   default:
     return std::make_tuple("unknown", _tsst_not_defined);
   }
 }
 
 /* -------------------------------------------------------------------------- */
 void SolidMechanicsModel::initSolver(TimeStepSolverType time_step_solver_type,
                                      NonLinearSolverType) {
   auto & dof_manager = this->getDOFManager();
 
   /* ------------------------------------------------------------------------ */
   // for alloc type of solvers
   this->allocNodalField(this->displacement, spatial_dimension, "displacement");
   this->allocNodalField(this->previous_displacement, spatial_dimension,
                         "previous_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->blocked_dofs, spatial_dimension, "blocked_dofs");
   this->allocNodalField(this->current_position, spatial_dimension,
                         "current_position");
 
   // initialize the current positions
   this->current_position->copy(this->mesh.getNodes());
 
   /* ------------------------------------------------------------------------ */
   if (!dof_manager.hasDOFs("displacement")) {
     dof_manager.registerDOFs("displacement", *this->displacement, _dst_nodal);
     dof_manager.registerBlockedDOFs("displacement", *this->blocked_dofs);
     dof_manager.registerDOFsIncrement("displacement",
                                       *this->displacement_increment);
     dof_manager.registerDOFsPrevious("displacement",
                                      *this->previous_displacement);
   }
 
   /* ------------------------------------------------------------------------ */
   // for dynamic
   if (time_step_solver_type == _tsst_dynamic ||
       time_step_solver_type == _tsst_dynamic_lumped) {
     this->allocNodalField(this->velocity, spatial_dimension, "velocity");
     this->allocNodalField(this->acceleration, spatial_dimension,
                           "acceleration");
 
     if (!dof_manager.hasDOFsDerivatives("displacement", 1)) {
       dof_manager.registerDOFsDerivative("displacement", 1, *this->velocity);
       dof_manager.registerDOFsDerivative("displacement", 2,
                                          *this->acceleration);
     }
   }
 }
 
 /* -------------------------------------------------------------------------- */
 /**
  * Initialize the model,basically it  pre-compute the shapes, shapes derivatives
  * and jacobian
  */
 void SolidMechanicsModel::initModel() {
   /// \todo add  the current position  as a parameter to  initShapeFunctions for
   /// large deformation
   getFEEngine().initShapeFunctions(_not_ghost);
   getFEEngine().initShapeFunctions(_ghost);
 }
 
 /* -------------------------------------------------------------------------- */
 void SolidMechanicsModel::assembleResidual() {
   AKANTU_DEBUG_IN();
 
   /* ------------------------------------------------------------------------ */
   // computes the internal forces
   this->assembleInternalForces();
 
   /* ------------------------------------------------------------------------ */
   this->getDOFManager().assembleToResidual("displacement",
                                            *this->external_force, 1);
   this->getDOFManager().assembleToResidual("displacement",
                                            *this->internal_force, 1);
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void SolidMechanicsModel::assembleResidual(const ID & residual_part) {
   AKANTU_DEBUG_IN();
 
   if ("external" == residual_part) {
     this->getDOFManager().assembleToResidual("displacement",
                                              *this->external_force, 1);
     AKANTU_DEBUG_OUT();
     return;
   }
 
   if ("internal" == residual_part) {
     this->getDOFManager().assembleToResidual("displacement",
                                              *this->internal_force, 1);
     AKANTU_DEBUG_OUT();
     return;
   }
 
   AKANTU_CUSTOM_EXCEPTION(
       debug::SolverCallbackResidualPartUnknown(residual_part));
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 MatrixType SolidMechanicsModel::getMatrixType(const ID & matrix_id) {
   // \TODO check the materials to know what is the correct answer
   if (matrix_id == "C")
     return _mt_not_defined;
 
   return _symmetric;
 }
 
 /* -------------------------------------------------------------------------- */
 void SolidMechanicsModel::assembleMatrix(const ID & matrix_id) {
   if (matrix_id == "K") {
     this->assembleStiffnessMatrix();
   } else if (matrix_id == "M") {
     this->assembleMass();
   }
 }
 
 /* -------------------------------------------------------------------------- */
 void SolidMechanicsModel::assembleLumpedMatrix(const ID & matrix_id) {
   if (matrix_id == "M") {
     this->assembleMassLumped();
   }
 }
 
 /* -------------------------------------------------------------------------- */
 void SolidMechanicsModel::beforeSolveStep() {
   for (auto & material : materials)
     material->beforeSolveStep();
 }
 
 /* -------------------------------------------------------------------------- */
 void SolidMechanicsModel::afterSolveStep() {
   for (auto & material : materials)
     material->afterSolveStep();
 }
 
 /* -------------------------------------------------------------------------- */
 void SolidMechanicsModel::predictor() { ++displacement_release; }
 
 /* -------------------------------------------------------------------------- */
 void SolidMechanicsModel::corrector() { ++displacement_release; }
 
 /* -------------------------------------------------------------------------- */
 /**
  * This function computes the internal forces as F_{int} = \int_{\Omega} N
  * \sigma d\Omega@f$
  */
 void SolidMechanicsModel::assembleInternalForces() {
   AKANTU_DEBUG_IN();
 
   AKANTU_DEBUG_INFO("Assemble the internal forces");
 
   this->internal_force->clear();
 
   // compute the stresses of local elements
   AKANTU_DEBUG_INFO("Compute local stresses");
   for (auto & material : materials) {
     material->computeAllStresses(_not_ghost);
   }
 
   /* ------------------------------------------------------------------------ */
   /* Computation of the non local part */
   if (this->non_local_manager)
     this->non_local_manager->computeAllNonLocalStresses();
 
   // communicate the stresses
   AKANTU_DEBUG_INFO("Send data for residual assembly");
   this->asynchronousSynchronize(_gst_smm_stress);
 
   // assemble the forces due to local stresses
   AKANTU_DEBUG_INFO("Assemble residual for local elements");
   for (auto & material : materials) {
     material->assembleInternalForces(_not_ghost);
   }
 
   // finalize communications
   AKANTU_DEBUG_INFO("Wait distant stresses");
   this->waitEndSynchronize(_gst_smm_stress);
 
   // assemble the stresses due to ghost elements
   AKANTU_DEBUG_INFO("Assemble residual for ghost elements");
   for (auto & material : materials) {
     material->assembleInternalForces(_ghost);
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void SolidMechanicsModel::assembleStiffnessMatrix() {
   AKANTU_DEBUG_IN();
 
   AKANTU_DEBUG_INFO("Assemble the new stiffness matrix.");
 
   // Check if materials need to recompute the matrix
   bool need_to_reassemble = false;
 
   for (auto & material : materials) {
     need_to_reassemble |= material->hasStiffnessMatrixChanged();
   }
 
   if (need_to_reassemble) {
     this->getDOFManager().getMatrix("K").clear();
 
     // call compute stiffness matrix on each local elements
     for (auto & material : materials) {
       material->assembleStiffnessMatrix(_not_ghost);
     }
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void SolidMechanicsModel::updateCurrentPosition() {
   if (this->current_position_release == this->displacement_release)
     return;
 
   this->current_position->copy(this->mesh.getNodes());
 
   auto cpos_it = this->current_position->begin(Model::spatial_dimension);
   auto cpos_end = this->current_position->end(Model::spatial_dimension);
   auto disp_it = this->displacement->begin(Model::spatial_dimension);
 
   for (; cpos_it != cpos_end; ++cpos_it, ++disp_it) {
     *cpos_it += *disp_it;
   }
 
   this->current_position_release = this->displacement_release;
 }
 
 /* -------------------------------------------------------------------------- */
 const Array<Real> & SolidMechanicsModel::getCurrentPosition() {
   this->updateCurrentPosition();
   return *this->current_position;
 }
 
 /* -------------------------------------------------------------------------- */
 void SolidMechanicsModel::updateDataForNonLocalCriterion(
     ElementTypeMapReal & criterion) {
   const ID field_name = criterion.getName();
   for (auto & material : materials) {
     if (!material->isInternal<Real>(field_name, _ek_regular))
       continue;
 
     for (auto ghost_type : ghost_types) {
       material->flattenInternal(field_name, criterion, ghost_type, _ek_regular);
     }
   }
 }
 
 /* -------------------------------------------------------------------------- */
 /* Information                                                                */
 /* -------------------------------------------------------------------------- */
 Real SolidMechanicsModel::getStableTimeStep() {
   AKANTU_DEBUG_IN();
 
   Real min_dt = getStableTimeStep(_not_ghost);
 
   /// reduction min over all processors
   mesh.getCommunicator().allReduce(min_dt, SynchronizerOperation::_min);
 
   AKANTU_DEBUG_OUT();
   return min_dt;
 }
 
 /* -------------------------------------------------------------------------- */
 Real SolidMechanicsModel::getStableTimeStep(const GhostType & ghost_type) {
   AKANTU_DEBUG_IN();
 
   Real min_dt = std::numeric_limits<Real>::max();
 
   this->updateCurrentPosition();
 
   Element elem;
   elem.ghost_type = ghost_type;
 
   for (auto type :
        mesh.elementTypes(Model::spatial_dimension, ghost_type, _ek_regular)) {
     elem.type = type;
     UInt nb_nodes_per_element = mesh.getNbNodesPerElement(type);
     UInt nb_element = mesh.getNbElement(type);
 
     auto mat_indexes = material_index(type, ghost_type).begin();
     auto mat_loc_num = material_local_numbering(type, ghost_type).begin();
 
     Array<Real> X(0, nb_nodes_per_element * Model::spatial_dimension);
     FEEngine::extractNodalToElementField(mesh, *current_position, X, type,
                                          _not_ghost);
 
     auto X_el = X.begin(Model::spatial_dimension, nb_nodes_per_element);
 
     for (UInt el = 0; el < nb_element;
          ++el, ++X_el, ++mat_indexes, ++mat_loc_num) {
       elem.element = *mat_loc_num;
       Real el_h = getFEEngine().getElementInradius(*X_el, type);
       Real el_c = this->materials[*mat_indexes]->getCelerity(elem);
       Real el_dt = el_h / el_c;
 
       min_dt = std::min(min_dt, el_dt);
     }
   }
 
   AKANTU_DEBUG_OUT();
   return min_dt;
 }
 
 /* -------------------------------------------------------------------------- */
 Real SolidMechanicsModel::getKineticEnergy() {
   AKANTU_DEBUG_IN();
 
   Real ekin = 0.;
   UInt nb_nodes = mesh.getNbNodes();
 
   if (this->getDOFManager().hasLumpedMatrix("M")) {
     auto m_it = this->mass->begin(Model::spatial_dimension);
     auto m_end = this->mass->end(Model::spatial_dimension);
     auto v_it = this->velocity->begin(Model::spatial_dimension);
 
     for (UInt n = 0; m_it != m_end; ++n, ++m_it, ++v_it) {
       const Vector<Real> & v = *v_it;
       const Vector<Real> & m = *m_it;
 
       Real mv2 = 0;
       bool is_local_node = mesh.isLocalOrMasterNode(n);
       // bool is_not_pbc_slave_node = !isPBCSlaveNode(n);
       bool count_node = is_local_node; // && is_not_pbc_slave_node;
       if (count_node) {
         for (UInt i = 0; i < Model::spatial_dimension; ++i) {
           if (m(i) > std::numeric_limits<Real>::epsilon())
             mv2 += v(i) * v(i) * m(i);
         }
       }
 
       ekin += mv2;
     }
   } else if (this->getDOFManager().hasMatrix("M")) {
     Array<Real> Mv(nb_nodes, Model::spatial_dimension);
     this->getDOFManager().getMatrix("M").matVecMul(*this->velocity, Mv);
 
     auto mv_it = Mv.begin(Model::spatial_dimension);
     auto mv_end = Mv.end(Model::spatial_dimension);
     auto v_it = this->velocity->begin(Model::spatial_dimension);
 
     for (; mv_it != mv_end; ++mv_it, ++v_it) {
       ekin += v_it->dot(*mv_it);
     }
   } else {
     AKANTU_ERROR("No function called to assemble the mass matrix.");
   }
 
   mesh.getCommunicator().allReduce(ekin, SynchronizerOperation::_sum);
 
   AKANTU_DEBUG_OUT();
   return ekin * .5;
 }
 
 /* -------------------------------------------------------------------------- */
 Real SolidMechanicsModel::getKineticEnergy(const ElementType & type,
                                            UInt index) {
   AKANTU_DEBUG_IN();
 
   UInt nb_quadrature_points = getFEEngine().getNbIntegrationPoints(type);
 
   Array<Real> vel_on_quad(nb_quadrature_points, Model::spatial_dimension);
   Array<UInt> filter_element(1, 1, index);
 
   getFEEngine().interpolateOnIntegrationPoints(*velocity, vel_on_quad,
                                                Model::spatial_dimension, type,
                                                _not_ghost, filter_element);
 
   auto vit = vel_on_quad.begin(Model::spatial_dimension);
   auto vend = vel_on_quad.end(Model::spatial_dimension);
 
   Vector<Real> rho_v2(nb_quadrature_points);
 
   Real rho = materials[material_index(type)(index)]->getRho();
 
   for (UInt q = 0; vit != vend; ++vit, ++q) {
     rho_v2(q) = rho * vit->dot(*vit);
   }
 
   AKANTU_DEBUG_OUT();
 
   return .5 * getFEEngine().integrate(rho_v2, type, index);
 }
 
 /* -------------------------------------------------------------------------- */
 Real SolidMechanicsModel::getExternalWork() {
   AKANTU_DEBUG_IN();
 
   auto ext_force_it = external_force->begin(Model::spatial_dimension);
   auto int_force_it = internal_force->begin(Model::spatial_dimension);
   auto boun_it = blocked_dofs->begin(Model::spatial_dimension);
 
   decltype(ext_force_it) incr_or_velo_it;
   if (this->method == _static) {
     incr_or_velo_it =
         this->displacement_increment->begin(Model::spatial_dimension);
   } else {
     incr_or_velo_it = this->velocity->begin(Model::spatial_dimension);
   }
 
   Real work = 0.;
 
   UInt nb_nodes = this->mesh.getNbNodes();
 
   for (UInt n = 0; n < nb_nodes;
        ++n, ++ext_force_it, ++int_force_it, ++boun_it, ++incr_or_velo_it) {
     const auto & int_force = *int_force_it;
     const auto & ext_force = *ext_force_it;
     const auto & boun = *boun_it;
     const auto & incr_or_velo = *incr_or_velo_it;
 
     bool is_local_node = this->mesh.isLocalOrMasterNode(n);
     // bool is_not_pbc_slave_node = !this->isPBCSlaveNode(n);
     bool count_node = is_local_node; // && is_not_pbc_slave_node;
 
     if (count_node) {
       for (UInt i = 0; i < Model::spatial_dimension; ++i) {
         if (boun(i))
           work -= int_force(i) * incr_or_velo(i);
         else
           work += ext_force(i) * incr_or_velo(i);
       }
     }
   }
 
   mesh.getCommunicator().allReduce(work, SynchronizerOperation::_sum);
 
   if (this->method != _static)
     work *= this->getTimeStep();
 
   AKANTU_DEBUG_OUT();
   return work;
 }
 
 /* -------------------------------------------------------------------------- */
 Real SolidMechanicsModel::getEnergy(const std::string & energy_id) {
   AKANTU_DEBUG_IN();
 
   if (energy_id == "kinetic") {
     return getKineticEnergy();
   } else if (energy_id == "external work") {
     return getExternalWork();
   }
 
   Real energy = 0.;
   for (auto & material : materials)
     energy += material->getEnergy(energy_id);
 
   /// reduction sum over all processors
   mesh.getCommunicator().allReduce(energy, SynchronizerOperation::_sum);
 
   AKANTU_DEBUG_OUT();
   return energy;
 }
 /* -------------------------------------------------------------------------- */
 Real SolidMechanicsModel::getEnergy(const std::string & energy_id,
                                     const ElementType & type, UInt index) {
   AKANTU_DEBUG_IN();
 
   if (energy_id == "kinetic") {
     return getKineticEnergy(type, index);
   }
 
   UInt mat_index = this->material_index(type, _not_ghost)(index);
   UInt mat_loc_num = this->material_local_numbering(type, _not_ghost)(index);
   Real energy =
       this->materials[mat_index]->getEnergy(energy_id, type, mat_loc_num);
 
   AKANTU_DEBUG_OUT();
   return energy;
 }
 
 /* -------------------------------------------------------------------------- */
 void SolidMechanicsModel::onElementsAdded(const Array<Element> & element_list,
                                           const NewElementsEvent & event) {
   AKANTU_DEBUG_IN();
 
   this->material_index.initialize(mesh, _element_kind = _ek_not_defined,
                                   _with_nb_element = true,
                                   _default_value = UInt(-1));
   this->material_local_numbering.initialize(
       mesh, _element_kind = _ek_not_defined, _with_nb_element = true,
       _default_value = UInt(-1));
 
   ElementTypeMapArray<UInt> filter("new_element_filter", this->getID(),
                                    this->getMemoryID());
 
   for (auto & elem : element_list) {
     if (!filter.exists(elem.type, elem.ghost_type))
       filter.alloc(0, 1, elem.type, elem.ghost_type);
     filter(elem.type, elem.ghost_type).push_back(elem.element);
   }
 
   this->assignMaterialToElements(&filter);
 
   for (auto & material : materials)
     material->onElementsAdded(element_list, event);
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void SolidMechanicsModel::onElementsRemoved(
     const Array<Element> & element_list,
     const ElementTypeMapArray<UInt> & new_numbering,
     const RemovedElementsEvent & event) {
   for (auto & material : materials) {
     material->onElementsRemoved(element_list, new_numbering, event);
   }
 }
 
 /* -------------------------------------------------------------------------- */
 void SolidMechanicsModel::onNodesAdded(const Array<UInt> & nodes_list,
                                        const NewNodesEvent & event) {
   AKANTU_DEBUG_IN();
   UInt nb_nodes = mesh.getNbNodes();
 
   if (displacement) {
     displacement->resize(nb_nodes, 0.);
     ++displacement_release;
   }
   if (mass)
     mass->resize(nb_nodes, 0.);
   if (velocity)
     velocity->resize(nb_nodes, 0.);
   if (acceleration)
     acceleration->resize(nb_nodes, 0.);
   if (external_force)
     external_force->resize(nb_nodes, 0.);
   if (internal_force)
     internal_force->resize(nb_nodes, 0.);
   if (blocked_dofs)
     blocked_dofs->resize(nb_nodes, 0.);
   if (current_position)
     current_position->resize(nb_nodes, 0.);
 
   if (previous_displacement)
     previous_displacement->resize(nb_nodes, 0.);
   if (displacement_increment)
     displacement_increment->resize(nb_nodes, 0.);
 
   for (auto & material : materials) {
     material->onNodesAdded(nodes_list, event);
   }
 
   need_to_reassemble_lumped_mass = true;
   need_to_reassemble_mass = true;
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void SolidMechanicsModel::onNodesRemoved(const Array<UInt> & /*element_list*/,
                                          const Array<UInt> & new_numbering,
                                          const RemovedNodesEvent & /*event*/) {
   if (displacement) {
     mesh.removeNodesFromArray(*displacement, new_numbering);
     ++displacement_release;
   }
   if (mass)
     mesh.removeNodesFromArray(*mass, new_numbering);
   if (velocity)
     mesh.removeNodesFromArray(*velocity, new_numbering);
   if (acceleration)
     mesh.removeNodesFromArray(*acceleration, new_numbering);
   if (internal_force)
     mesh.removeNodesFromArray(*internal_force, new_numbering);
   if (external_force)
     mesh.removeNodesFromArray(*external_force, new_numbering);
   if (blocked_dofs)
     mesh.removeNodesFromArray(*blocked_dofs, new_numbering);
 
   // if (increment_acceleration)
   //   mesh.removeNodesFromArray(*increment_acceleration, new_numbering);
   if (displacement_increment)
     mesh.removeNodesFromArray(*displacement_increment, new_numbering);
 
   if (previous_displacement)
     mesh.removeNodesFromArray(*previous_displacement, new_numbering);
 }
 
 /* -------------------------------------------------------------------------- */
 void SolidMechanicsModel::printself(std::ostream & stream, int indent) const {
   std::string space;
   for (Int i = 0; i < indent; i++, space += AKANTU_INDENT)
     ;
 
   stream << space << "Solid 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 << " + nodals information [" << std::endl;
   displacement->printself(stream, indent + 2);
   if (velocity)
     velocity->printself(stream, indent + 2);
   if (acceleration)
     acceleration->printself(stream, indent + 2);
   if (mass)
     mass->printself(stream, indent + 2);
   external_force->printself(stream, indent + 2);
   internal_force->printself(stream, indent + 2);
   blocked_dofs->printself(stream, indent + 2);
   stream << space << AKANTU_INDENT << "]" << std::endl;
 
   stream << space << " + material information [" << std::endl;
   material_index.printself(stream, indent + 2);
   stream << space << AKANTU_INDENT << "]" << std::endl;
 
   stream << space << " + materials [" << std::endl;
   for (auto & material : materials) {
     material->printself(stream, indent + 1);
   }
   stream << space << AKANTU_INDENT << "]" << std::endl;
 
   stream << space << "]" << std::endl;
 }
 
 /* -------------------------------------------------------------------------- */
 void SolidMechanicsModel::initializeNonLocal() {
   this->non_local_manager->synchronize(*this, _gst_material_id);
 }
 
 /* -------------------------------------------------------------------------- */
 void SolidMechanicsModel::insertIntegrationPointsInNeighborhoods(
     const GhostType & ghost_type) {
   for (auto & mat : materials) {
     MaterialNonLocalInterface * mat_non_local;
     if ((mat_non_local =
              dynamic_cast<MaterialNonLocalInterface *>(mat.get())) == nullptr)
       continue;
 
     ElementTypeMapArray<Real> quadrature_points_coordinates(
         "quadrature_points_coordinates_tmp_nl", this->id, this->memory_id);
     quadrature_points_coordinates.initialize(this->getFEEngine(),
                                              _nb_component = spatial_dimension,
                                              _ghost_type = ghost_type);
 
     for (auto & type : quadrature_points_coordinates.elementTypes(
              Model::spatial_dimension, ghost_type)) {
       this->getFEEngine().computeIntegrationPointsCoordinates(
           quadrature_points_coordinates(type, ghost_type), type, ghost_type);
     }
 
     mat_non_local->initMaterialNonLocal();
 
     mat_non_local->insertIntegrationPointsInNeighborhoods(
         ghost_type, quadrature_points_coordinates);
   }
 }
 
 /* -------------------------------------------------------------------------- */
 void SolidMechanicsModel::computeNonLocalStresses(
     const GhostType & ghost_type) {
   for (auto & mat : materials) {
     if (dynamic_cast<MaterialNonLocalInterface *>(mat.get()) == nullptr)
       continue;
 
     auto & mat_non_local = dynamic_cast<MaterialNonLocalInterface &>(*mat);
     mat_non_local.computeNonLocalStresses(ghost_type);
   }
 }
 
 /* -------------------------------------------------------------------------- */
 void SolidMechanicsModel::updateLocalInternal(
     ElementTypeMapReal & internal_flat, const GhostType & ghost_type,
     const ElementKind & kind) {
   const ID field_name = internal_flat.getName();
   for (auto & material : materials) {
     if (material->isInternal<Real>(field_name, kind))
       material->flattenInternal(field_name, internal_flat, ghost_type, kind);
   }
 }
 
 /* -------------------------------------------------------------------------- */
 void SolidMechanicsModel::updateNonLocalInternal(
     ElementTypeMapReal & internal_flat, const GhostType & ghost_type,
     const ElementKind & kind) {
 
   const ID field_name = internal_flat.getName();
 
   for (auto & mat : materials) {
     if (dynamic_cast<MaterialNonLocalInterface *>(mat.get()) == nullptr)
       continue;
 
     auto & mat_non_local = dynamic_cast<MaterialNonLocalInterface &>(*mat);
     mat_non_local.updateNonLocalInternals(internal_flat, field_name, ghost_type,
                                           kind);
   }
 }
 
 /* -------------------------------------------------------------------------- */
 FEEngine & SolidMechanicsModel::getFEEngineBoundary(const ID & name) {
   return dynamic_cast<FEEngine &>(
       getFEEngineClassBoundary<MyFEEngineType>(name));
 }
 
 /* -------------------------------------------------------------------------- */
 void SolidMechanicsModel::splitElementByMaterial(
     const Array<Element> & elements,
     std::vector<Array<Element>> & elements_per_mat) const {
   ElementType current_element_type = _not_defined;
   GhostType current_ghost_type = _casper;
   const Array<UInt> * mat_indexes = nullptr;
   const Array<UInt> * mat_loc_num = nullptr;
 
   for (const auto & el : elements) {
     if (el.type != current_element_type ||
         el.ghost_type != current_ghost_type) {
       current_element_type = el.type;
       current_ghost_type = el.ghost_type;
       mat_indexes = &(this->material_index(el.type, el.ghost_type));
       mat_loc_num = &(this->material_local_numbering(el.type, el.ghost_type));
     }
 
     Element mat_el = el;
 
     mat_el.element = (*mat_loc_num)(el.element);
     elements_per_mat[(*mat_indexes)(el.element)].push_back(mat_el);
   }
 }
 
 /* -------------------------------------------------------------------------- */
 UInt SolidMechanicsModel::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);
   }
 
   switch (tag) {
   case _gst_material_id: {
     size += elements.size() * sizeof(UInt);
     break;
   }
   case _gst_smm_mass: {
     size += nb_nodes_per_element * sizeof(Real) *
             Model::spatial_dimension; // mass vector
     break;
   }
   case _gst_smm_for_gradu: {
     size += nb_nodes_per_element * Model::spatial_dimension *
             sizeof(Real); // displacement
     break;
   }
   case _gst_smm_boundary: {
     // force, displacement, boundary
     size += nb_nodes_per_element * Model::spatial_dimension *
             (2 * sizeof(Real) + sizeof(bool));
     break;
   }
   case _gst_for_dump: {
     // displacement, velocity, acceleration, residual, force
     size += nb_nodes_per_element * Model::spatial_dimension * sizeof(Real) * 5;
     break;
   }
   default: {}
   }
 
   if (tag != _gst_material_id) {
     splitByMaterial(elements, [&](auto && mat, auto && elements) {
       size += mat.getNbData(elements, tag);
     });
   }
 
   AKANTU_DEBUG_OUT();
   return size;
 }
 
 /* -------------------------------------------------------------------------- */
 void SolidMechanicsModel::packData(CommunicationBuffer & buffer,
                                    const Array<Element> & elements,
                                    const SynchronizationTag & tag) const {
   AKANTU_DEBUG_IN();
 
   switch (tag) {
   case _gst_material_id: {
     this->packElementalDataHelper(material_index, buffer, elements, false,
                                   getFEEngine());
     break;
   }
   case _gst_smm_mass: {
     packNodalDataHelper(*mass, buffer, elements, mesh);
     break;
   }
   case _gst_smm_for_gradu: {
     packNodalDataHelper(*displacement, buffer, elements, mesh);
     break;
   }
   case _gst_for_dump: {
     packNodalDataHelper(*displacement, buffer, elements, mesh);
     packNodalDataHelper(*velocity, buffer, elements, mesh);
     packNodalDataHelper(*acceleration, buffer, elements, mesh);
     packNodalDataHelper(*internal_force, buffer, elements, mesh);
     packNodalDataHelper(*external_force, buffer, elements, mesh);
     break;
   }
   case _gst_smm_boundary: {
     packNodalDataHelper(*external_force, buffer, elements, mesh);
     packNodalDataHelper(*velocity, buffer, elements, mesh);
     packNodalDataHelper(*blocked_dofs, buffer, elements, mesh);
     break;
   }
   default: {}
   }
 
   if (tag != _gst_material_id) {
     splitByMaterial(elements, [&](auto && mat, auto && elements) {
       mat.packData(buffer, elements, tag);
     });
   }
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void SolidMechanicsModel::unpackData(CommunicationBuffer & buffer,
                                      const Array<Element> & elements,
                                      const SynchronizationTag & tag) {
   AKANTU_DEBUG_IN();
 
   switch (tag) {
   case _gst_material_id: {
     for (auto && element : elements) {
       UInt recv_mat_index;
       buffer >> recv_mat_index;
       UInt & mat_index = material_index(element);
       if (mat_index != UInt(-1))
         continue;
 
       // add ghosts element to the correct material
       mat_index = recv_mat_index;
       UInt index = materials[mat_index]->addElement(element);
       material_local_numbering(element) = index;
     }
     break;
   }
   case _gst_smm_mass: {
     unpackNodalDataHelper(*mass, buffer, elements, mesh);
     break;
   }
   case _gst_smm_for_gradu: {
     unpackNodalDataHelper(*displacement, buffer, elements, mesh);
     break;
   }
   case _gst_for_dump: {
     unpackNodalDataHelper(*displacement, buffer, elements, mesh);
     unpackNodalDataHelper(*velocity, buffer, elements, mesh);
     unpackNodalDataHelper(*acceleration, buffer, elements, mesh);
     unpackNodalDataHelper(*internal_force, buffer, elements, mesh);
     unpackNodalDataHelper(*external_force, buffer, elements, mesh);
     break;
   }
   case _gst_smm_boundary: {
     unpackNodalDataHelper(*external_force, buffer, elements, mesh);
     unpackNodalDataHelper(*velocity, buffer, elements, mesh);
     unpackNodalDataHelper(*blocked_dofs, buffer, elements, mesh);
     break;
   }
   default: {}
   }
 
   if (tag != _gst_material_id) {
     splitByMaterial(elements, [&](auto && mat, auto && elements) {
       mat.unpackData(buffer, elements, tag);
     });
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 UInt SolidMechanicsModel::getNbData(const Array<UInt> & dofs,
                                     const SynchronizationTag & tag) const {
   AKANTU_DEBUG_IN();
 
   UInt size = 0;
   //  UInt nb_nodes = mesh.getNbNodes();
 
   switch (tag) {
   case _gst_smm_uv: {
     size += sizeof(Real) * Model::spatial_dimension * 2;
     break;
   }
   case _gst_smm_res: {
     size += sizeof(Real) * Model::spatial_dimension;
     break;
   }
   case _gst_smm_mass: {
     size += sizeof(Real) * Model::spatial_dimension;
     break;
   }
   case _gst_for_dump: {
     size += sizeof(Real) * Model::spatial_dimension * 5;
     break;
   }
   default: { AKANTU_ERROR("Unknown ghost synchronization tag : " << tag); }
   }
 
   AKANTU_DEBUG_OUT();
   return size * dofs.size();
 }
 
 /* -------------------------------------------------------------------------- */
 void SolidMechanicsModel::packData(CommunicationBuffer & buffer,
                                    const Array<UInt> & dofs,
                                    const SynchronizationTag & tag) const {
   AKANTU_DEBUG_IN();
 
   switch (tag) {
   case _gst_smm_uv: {
     packDOFDataHelper(*displacement, buffer, dofs);
     packDOFDataHelper(*velocity, buffer, dofs);
     break;
   }
   case _gst_smm_res: {
     packDOFDataHelper(*internal_force, buffer, dofs);
     break;
   }
   case _gst_smm_mass: {
     packDOFDataHelper(*mass, buffer, dofs);
     break;
   }
   case _gst_for_dump: {
     packDOFDataHelper(*displacement, buffer, dofs);
     packDOFDataHelper(*velocity, buffer, dofs);
     packDOFDataHelper(*acceleration, buffer, dofs);
     packDOFDataHelper(*internal_force, buffer, dofs);
     packDOFDataHelper(*external_force, buffer, dofs);
     break;
   }
   default: { AKANTU_ERROR("Unknown ghost synchronization tag : " << tag); }
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void SolidMechanicsModel::unpackData(CommunicationBuffer & buffer,
                                      const Array<UInt> & dofs,
                                      const SynchronizationTag & tag) {
   AKANTU_DEBUG_IN();
 
   switch (tag) {
   case _gst_smm_uv: {
     unpackDOFDataHelper(*displacement, buffer, dofs);
     unpackDOFDataHelper(*velocity, buffer, dofs);
     break;
   }
   case _gst_smm_res: {
     unpackDOFDataHelper(*internal_force, buffer, dofs);
     break;
   }
   case _gst_smm_mass: {
     unpackDOFDataHelper(*mass, buffer, dofs);
     break;
   }
   case _gst_for_dump: {
     unpackDOFDataHelper(*displacement, buffer, dofs);
     unpackDOFDataHelper(*velocity, buffer, dofs);
     unpackDOFDataHelper(*acceleration, buffer, dofs);
     unpackDOFDataHelper(*internal_force, buffer, dofs);
     unpackDOFDataHelper(*external_force, buffer, dofs);
     break;
   }
   default: { AKANTU_ERROR("Unknown ghost synchronization tag : " << tag); }
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 } // namespace akantu
diff --git a/src/model/solid_mechanics/solid_mechanics_model.hh b/src/model/solid_mechanics/solid_mechanics_model.hh
index 57e489704..37c45ef56 100644
--- a/src/model/solid_mechanics/solid_mechanics_model.hh
+++ b/src/model/solid_mechanics/solid_mechanics_model.hh
@@ -1,559 +1,559 @@
 /**
  * @file   solid_mechanics_model.hh
  *
  * @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
  * @author Daniel Pino Muñoz <daniel.pinomunoz@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Tue Jul 27 2010
- * @date last modification: Tue Jan 19 2016
+ * @date last modification: Wed Feb 21 2018
  *
  * @brief  Model of Solid Mechanics
  *
  * @section LICENSE
  *
- * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
- * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
- * Solides)
+ * 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
+ * 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
+ * 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 "data_accessor.hh"
 #include "fe_engine.hh"
 #include "model.hh"
 #include "non_local_manager.hh"
 #include "solid_mechanics_model_event_handler.hh"
 /* -------------------------------------------------------------------------- */
 
 #ifndef __AKANTU_SOLID_MECHANICS_MODEL_HH__
 #define __AKANTU_SOLID_MECHANICS_MODEL_HH__
 
 namespace akantu {
 class Material;
 class MaterialSelector;
 class DumperIOHelper;
 class NonLocalManager;
 template <ElementKind kind, class IntegrationOrderFunctor>
 class IntegratorGauss;
 template <ElementKind kind> class ShapeLagrange;
 } // namespace akantu
 
 /* -------------------------------------------------------------------------- */
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 class SolidMechanicsModel
     : public Model,
       public DataAccessor<Element>,
       public DataAccessor<UInt>,
       public BoundaryCondition<SolidMechanicsModel>,
       public NonLocalManagerCallback,
       public EventHandlerManager<SolidMechanicsModelEventHandler> {
 
   /* ------------------------------------------------------------------------ */
   /* Constructors/Destructors                                                 */
   /* ------------------------------------------------------------------------ */
 public:
   class NewMaterialElementsEvent : public NewElementsEvent {
   public:
     AKANTU_GET_MACRO_NOT_CONST(MaterialList, material, Array<UInt> &);
     AKANTU_GET_MACRO(MaterialList, material, const Array<UInt> &);
 
   protected:
     Array<UInt> material;
   };
 
   using MyFEEngineType = FEEngineTemplate<IntegratorGauss, ShapeLagrange>;
 
 protected:
   using EventManager = EventHandlerManager<SolidMechanicsModelEventHandler>;
 
 public:
   SolidMechanicsModel(
       Mesh & mesh, UInt spatial_dimension = _all_dimensions,
       const ID & id = "solid_mechanics_model", const MemoryID & memory_id = 0,
       const ModelType model_type = ModelType::_solid_mechanics_model);
 
   ~SolidMechanicsModel() override;
 
   /* ------------------------------------------------------------------------ */
   /* Methods                                                                  */
   /* ------------------------------------------------------------------------ */
 protected:
   /// initialize completely the model
   void initFullImpl(
       const ModelOptions & options = SolidMechanicsModelOptions()) override;
 
   /// initialize all internal arrays for materials
   virtual void initMaterials();
 
   /// initialize the model
   void initModel() override;
 
   /// function to print the containt of the class
   void printself(std::ostream & stream, int indent = 0) const override;
 
   /// get some default values for derived classes
   std::tuple<ID, TimeStepSolverType>
   getDefaultSolverID(const AnalysisMethod & method) override;
 
   /* ------------------------------------------------------------------------ */
   /* Solver interface                                                         */
   /* ------------------------------------------------------------------------ */
 public:
   /// assembles the stiffness matrix,
   virtual void assembleStiffnessMatrix();
   /// assembles the internal forces in the array internal_forces
   virtual void assembleInternalForces();
 
 protected:
   /// callback for the solver, this adds f_{ext} - f_{int} to the residual
   void assembleResidual() override;
 
   /// callback for the solver, this adds f_{ext} or  f_{int} to the residual
   void assembleResidual(const ID & residual_part) override;
   bool canSplitResidual() override { return true; }
 
   /// 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;
 
   /// callback for the solver, this is called at beginning of solve
   void predictor() override;
   /// callback for the solver, this is called at end of solve
   void corrector() override;
 
   /// 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() override;
 
   /// Callback for the model to instantiate the matricees when needed
   void initSolver(TimeStepSolverType time_step_solver_type,
                   NonLinearSolverType non_linear_solver_type) override;
 
 protected:
   /* ------------------------------------------------------------------------ */
   TimeStepSolverType getDefaultSolverType() const override;
   /* ------------------------------------------------------------------------ */
   ModelSolverOptions
   getDefaultSolverOptions(const TimeStepSolverType & type) const override;
 
 public:
   bool isDefaultSolverExplicit() {
     return method == _explicit_lumped_mass ||
            method == _explicit_consistent_mass;
   }
 
 protected:
   /// update the current position vector
   void updateCurrentPosition();
 
   /* ------------------------------------------------------------------------ */
   /* Materials (solid_mechanics_model_material.cc)                            */
   /* ------------------------------------------------------------------------ */
 public:
   /// register an empty material of a given type
   Material & registerNewMaterial(const ID & mat_name, const ID & mat_type,
                                  const ID & opt_param);
 
   /// reassigns materials depending on the material selector
   virtual void reassignMaterial();
 
   /// apply a constant eigen_grad_u on all quadrature points of a given material
   virtual void applyEigenGradU(const Matrix<Real> & prescribed_eigen_grad_u,
                                const ID & material_name,
                                const GhostType ghost_type = _not_ghost);
 
 protected:
   /// register a material in the dynamic database
   Material & registerNewMaterial(const ParserSection & mat_section);
 
   /// read the material files to instantiate all the materials
   void instantiateMaterials();
 
   /// set the element_id_by_material and add the elements to the good materials
   virtual void
   assignMaterialToElements(const ElementTypeMapArray<UInt> * filter = nullptr);
 
   /* ------------------------------------------------------------------------ */
   /* Mass (solid_mechanics_model_mass.cc)                                     */
   /* ------------------------------------------------------------------------ */
 public:
   /// assemble the lumped mass matrix
   void assembleMassLumped();
 
   /// assemble the mass matrix for consistent mass resolutions
   void assembleMass();
 
 protected:
   /// assemble the lumped mass matrix for local and ghost elements
   void assembleMassLumped(GhostType ghost_type);
 
   /// assemble the mass matrix for either _ghost or _not_ghost elements
   void assembleMass(GhostType ghost_type);
 
   /// fill a vector of rho
   void computeRho(Array<Real> & rho, ElementType type, GhostType ghost_type);
 
   /// compute the kinetic energy
   Real getKineticEnergy();
   Real getKineticEnergy(const ElementType & type, UInt index);
 
   /// compute the external work (for impose displacement, the velocity should be
   /// given too)
   Real getExternalWork();
 
   /* ------------------------------------------------------------------------ */
   /* NonLocalManager inherited members                                        */
   /* ------------------------------------------------------------------------ */
 protected:
   void initializeNonLocal() override;
 
   void updateDataForNonLocalCriterion(ElementTypeMapReal & criterion) override;
 
   void computeNonLocalStresses(const GhostType & ghost_type) override;
 
   void
   insertIntegrationPointsInNeighborhoods(const GhostType & ghost_type) override;
 
   /// update the values of the non local internal
   void updateLocalInternal(ElementTypeMapReal & internal_flat,
                            const GhostType & ghost_type,
                            const ElementKind & kind) override;
 
   /// copy the results of the averaging in the materials
   void updateNonLocalInternal(ElementTypeMapReal & internal_flat,
                               const GhostType & ghost_type,
                               const ElementKind & kind) override;
 
   /* ------------------------------------------------------------------------ */
   /* 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:
   void
   splitElementByMaterial(const Array<Element> & elements,
                          std::vector<Array<Element>> & elements_per_mat) const;
 
   template <typename Operation>
   void splitByMaterial(const Array<Element> & elements, Operation && op) const;
 
   /* ------------------------------------------------------------------------ */
   /* Mesh Event Handler inherited members                                     */
   /* ------------------------------------------------------------------------ */
 protected:
   void onNodesAdded(const Array<UInt> & nodes_list,
                     const NewNodesEvent & event) override;
   void onNodesRemoved(const Array<UInt> & element_list,
                       const Array<UInt> & new_numbering,
                       const RemovedNodesEvent & event) override;
   void onElementsAdded(const Array<Element> & nodes_list,
                        const NewElementsEvent & event) override;
   void onElementsRemoved(const Array<Element> & element_list,
                          const ElementTypeMapArray<UInt> & new_numbering,
                          const RemovedElementsEvent & event) override;
   void onElementsChanged(const Array<Element> &, const Array<Element> &,
                          const ElementTypeMapArray<UInt> &,
                          const ChangedElementsEvent &) override{};
 
   /* ------------------------------------------------------------------------ */
   /* Dumpable interface (kept for convenience) and dumper relative functions  */
   /* ------------------------------------------------------------------------ */
 public:
   virtual void onDump();
 
   //! decide wether a field is a material internal or not
   bool isInternal(const std::string & field_name,
                   const ElementKind & element_kind);
 #ifndef SWIG
   //! give the amount of data per element
   virtual ElementTypeMap<UInt>
   getInternalDataPerElem(const std::string & field_name,
                          const ElementKind & kind);
 
   //! flatten a given material internal field
   ElementTypeMapArray<Real> &
   flattenInternal(const std::string & field_name, const ElementKind & kind,
                   const GhostType ghost_type = _not_ghost);
   //! flatten all the registered material internals
   void flattenAllRegisteredInternals(const ElementKind & kind);
 #endif
 
   dumper::Field * createNodalFieldReal(const std::string & field_name,
                                        const std::string & group_name,
                                        bool padding_flag) override;
 
   dumper::Field * createNodalFieldBool(const std::string & field_name,
                                        const std::string & group_name,
                                        bool padding_flag) override;
 
   dumper::Field * createElementalField(const std::string & field_name,
                                        const std::string & group_name,
                                        bool padding_flag,
                                        const UInt & spatial_dimension,
                                        const ElementKind & kind) override;
 
   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);
 
   void dump() override;
 
   virtual void dump(UInt step);
 
   virtual void dump(Real time, UInt step);
 
   /* ------------------------------------------------------------------------ */
   /* Accessors                                                                */
   /* ------------------------------------------------------------------------ */
 public:
   /// return the dimension of the system space
   AKANTU_GET_MACRO(SpatialDimension, Model::spatial_dimension, UInt);
 
   /// set the value of the time step
   void setTimeStep(Real time_step, const ID & solver_id = "") override;
 
   /// get the value of the conversion from forces/ mass to acceleration
   AKANTU_GET_MACRO(F_M2A, f_m2a, Real);
 
   /// set the value of the conversion from forces/ mass to acceleration
   AKANTU_SET_MACRO(F_M2A, f_m2a, Real);
 
   /// get the SolidMechanicsModel::displacement vector
   AKANTU_GET_MACRO(Displacement, *displacement, Array<Real> &);
 
   /// get the SolidMechanicsModel::previous_displacement vector
   AKANTU_GET_MACRO(PreviousDisplacement, *previous_displacement, Array<Real> &);
 
   /// get the SolidMechanicsModel::current_position vector \warn only consistent
   /// after a call to SolidMechanicsModel::updateCurrentPosition
   const Array<Real> & getCurrentPosition();
 
   /// get  the SolidMechanicsModel::increment  vector \warn  only  consistent if
   /// SolidMechanicsModel::setIncrementFlagOn has been called before
   AKANTU_GET_MACRO(Increment, *displacement_increment, Array<Real> &);
 
   /// get the lumped SolidMechanicsModel::mass vector
   AKANTU_GET_MACRO(Mass, *mass, Array<Real> &);
 
   /// get the SolidMechanicsModel::velocity vector
   AKANTU_GET_MACRO(Velocity, *velocity, Array<Real> &);
 
   /// get    the    SolidMechanicsModel::acceleration    vector,   updated    by
   /// SolidMechanicsModel::updateAcceleration
   AKANTU_GET_MACRO(Acceleration, *acceleration, Array<Real> &);
 
   /// get the SolidMechanicsModel::force vector (external forces)
   AKANTU_GET_MACRO(Force, *external_force, Array<Real> &);
 
   /// get the SolidMechanicsModel::internal_force vector (internal forces)
   AKANTU_GET_MACRO(InternalForce, *internal_force, Array<Real> &);
 
   /// get the SolidMechanicsModel::blocked_dofs vector
   AKANTU_GET_MACRO(BlockedDOFs, *blocked_dofs, Array<bool> &);
 
   /// get the value of the SolidMechanicsModel::increment_flag
   AKANTU_GET_MACRO(IncrementFlag, increment_flag, bool);
 
   /// get a particular material (by material index)
   inline Material & getMaterial(UInt mat_index);
 
   /// get a particular material (by material index)
   inline const Material & getMaterial(UInt mat_index) const;
 
   /// get a particular material (by material name)
   inline Material & getMaterial(const std::string & name);
 
   /// get a particular material (by material name)
   inline const Material & getMaterial(const std::string & name) const;
 
   /// get a particular material id from is name
   inline UInt getMaterialIndex(const std::string & name) const;
 
   /// give the number of materials
   inline UInt getNbMaterials() const { return materials.size(); }
 
   /// give the material internal index from its id
   Int getInternalIndexFromID(const ID & id) const;
 
   /// compute the stable time step
   Real getStableTimeStep();
 
   /// get the energies
   Real getEnergy(const std::string & energy_id);
 
   /// compute the energy for energy
   Real getEnergy(const std::string & energy_id, const ElementType & type,
                  UInt index);
 
   AKANTU_GET_MACRO(MaterialByElement, material_index,
                    const ElementTypeMapArray<UInt> &);
 
   /// vectors containing local material element index for each global element
   /// index
   AKANTU_GET_MACRO_BY_ELEMENT_TYPE_CONST(MaterialByElement, material_index,
                                          UInt);
   AKANTU_GET_MACRO_BY_ELEMENT_TYPE(MaterialByElement, material_index, UInt);
   AKANTU_GET_MACRO_BY_ELEMENT_TYPE_CONST(MaterialLocalNumbering,
                                          material_local_numbering, UInt);
   AKANTU_GET_MACRO_BY_ELEMENT_TYPE(MaterialLocalNumbering,
                                    material_local_numbering, UInt);
 
   AKANTU_GET_MACRO_NOT_CONST(MaterialSelector, *material_selector,
                              MaterialSelector &);
   AKANTU_SET_MACRO(MaterialSelector, material_selector,
                    std::shared_ptr<MaterialSelector>);
 
   /// Access the non_local_manager interface
   AKANTU_GET_MACRO(NonLocalManager, *non_local_manager, NonLocalManager &);
 
   /// get the FEEngine object to integrate or interpolate on the boundary
   FEEngine & getFEEngineBoundary(const ID & name = "") override;
 
 protected:
   friend class Material;
 
 protected:
   /// compute the stable time step
   Real getStableTimeStep(const GhostType & ghost_type);
 
   /* ------------------------------------------------------------------------ */
   /* Class Members                                                            */
   /* ------------------------------------------------------------------------ */
 protected:
   /// conversion coefficient form force/mass to acceleration
   Real f_m2a;
 
   /// displacements array
   Array<Real> * displacement;
   UInt displacement_release{0};
 
   /// displacements array at the previous time step (used in finite deformation)
   Array<Real> * previous_displacement{nullptr};
 
   /// increment of displacement
   Array<Real> * displacement_increment{nullptr};
 
   /// lumped mass array
   Array<Real> * mass{nullptr};
 
   /// Check if materials need to recompute the mass array
   bool need_to_reassemble_lumped_mass{true};
   /// Check if materials need to recompute the mass matrix
   bool need_to_reassemble_mass{true};
 
   /// velocities array
   Array<Real> * velocity{nullptr};
 
   /// accelerations array
   Array<Real> * acceleration{nullptr};
 
   /// accelerations array
   // Array<Real> * increment_acceleration;
 
   /// external forces array
   Array<Real> * external_force{nullptr};
 
   /// internal forces array
   Array<Real> * internal_force{nullptr};
 
   /// array specifing if a degree of freedom is blocked or not
   Array<bool> * blocked_dofs{nullptr};
 
   /// array of current position used during update residual
   Array<Real> * current_position{nullptr};
   UInt current_position_release{0};
 
   /// Arrays containing the material index for each element
   ElementTypeMapArray<UInt> material_index;
 
   /// Arrays containing the position in the element filter of the material
   /// (material's local numbering)
   ElementTypeMapArray<UInt> material_local_numbering;
 
   /// list of used materials
   std::vector<std::unique_ptr<Material>> materials;
 
   /// mapping between material name and material internal id
   std::map<std::string, UInt> materials_names_to_id;
 
   /// class defining of to choose a material
   std::shared_ptr<MaterialSelector> material_selector;
 
   /// flag defining if the increment must be computed or not
   bool increment_flag;
 
   /// tells if the material are instantiated
   bool are_materials_instantiated;
 
   using flatten_internal_map = std::map<std::pair<std::string, ElementKind>,
                                         ElementTypeMapArray<Real> *>;
 
   /// map a registered internals to be flattened for dump purposes
   flatten_internal_map registered_internals;
 
   /// non local manager
   std::unique_ptr<NonLocalManager> non_local_manager;
 };
 
 /* -------------------------------------------------------------------------- */
 namespace BC {
   namespace Neumann {
     using FromStress = FromHigherDim;
     using FromTraction = FromSameDim;
   } // namespace Neumann
 } // namespace BC
 
 } // namespace akantu
 
 /* -------------------------------------------------------------------------- */
 /* inline functions                                                           */
 /* -------------------------------------------------------------------------- */
 #include "material.hh"
 #include "parser.hh"
 
 #include "solid_mechanics_model_inline_impl.cc"
 #include "solid_mechanics_model_tmpl.hh"
 /* -------------------------------------------------------------------------- */
 
 #endif /* __AKANTU_SOLID_MECHANICS_MODEL_HH__ */
diff --git a/src/model/solid_mechanics/solid_mechanics_model_cohesive/fragment_manager.cc b/src/model/solid_mechanics/solid_mechanics_model_cohesive/fragment_manager.cc
index 63396a1b8..9f1a72dd2 100644
--- a/src/model/solid_mechanics/solid_mechanics_model_cohesive/fragment_manager.cc
+++ b/src/model/solid_mechanics/solid_mechanics_model_cohesive/fragment_manager.cc
@@ -1,611 +1,612 @@
 /**
  * @file   fragment_manager.cc
  *
+ * @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
  * @author Marco Vocialta <marco.vocialta@epfl.ch>
  *
  * @date creation: Thu Jan 23 2014
- * @date last modification: Mon Dec 14 2015
+ * @date last modification: Tue Feb 20 2018
  *
  * @brief  Group manager to handle fragments
  *
  * @section LICENSE
  *
- * Copyright  (©)  2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de Lausanne)
+ * 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
+ * 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
+ * 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 "fragment_manager.hh"
 #include "aka_iterators.hh"
 #include "communicator.hh"
 #include "material_cohesive.hh"
 #include "mesh_iterators.hh"
 #include "solid_mechanics_model_cohesive.hh"
 /* -------------------------------------------------------------------------- */
 #include <algorithm>
 #include <functional>
 #include <numeric>
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 FragmentManager::FragmentManager(SolidMechanicsModelCohesive & model,
                                  bool dump_data, const ID & id,
                                  const MemoryID & memory_id)
     : GroupManager(model.getMesh(), id, memory_id), model(model),
       mass_center(0, model.getSpatialDimension(), "mass_center"),
       mass(0, model.getSpatialDimension(), "mass"),
       velocity(0, model.getSpatialDimension(), "velocity"),
       inertia_moments(0, model.getSpatialDimension(), "inertia_moments"),
       principal_directions(
           0, model.getSpatialDimension() * model.getSpatialDimension(),
           "principal_directions"),
       quad_coordinates("quad_coordinates", id),
       mass_density("mass_density", id),
       nb_elements_per_fragment(0, 1, "nb_elements_per_fragment"),
       dump_data(dump_data) {
   AKANTU_DEBUG_IN();
 
   UInt spatial_dimension = mesh.getSpatialDimension();
 
   /// compute quadrature points' coordinates
   quad_coordinates.initialize(mesh, _nb_component = spatial_dimension,
                               _spatial_dimension = spatial_dimension,
                               _ghost_type = _not_ghost);
   // mesh.initElementTypeMapArray(quad_coordinates, spatial_dimension,
   //                              spatial_dimension, _not_ghost);
 
   model.getFEEngine().interpolateOnIntegrationPoints(model.getMesh().getNodes(),
                                                      quad_coordinates);
 
   /// store mass density per quadrature point
   mass_density.initialize(mesh, _spatial_dimension = spatial_dimension,
                           _ghost_type = _not_ghost);
   // mesh.initElementTypeMapArray(mass_density, 1, spatial_dimension,
   // _not_ghost);
 
   storeMassDensityPerIntegrationPoint();
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 class CohesiveElementFilter : public GroupManager::ClusteringFilter {
 public:
   CohesiveElementFilter(const SolidMechanicsModelCohesive & model,
                         const Real max_damage = 1.)
       : model(model), is_unbroken(max_damage) {}
 
   bool operator()(const Element & el) const override {
     if (Mesh::getKind(el.type) == _ek_regular)
       return true;
 
     const Array<UInt> & mat_indexes =
         model.getMaterialByElement(el.type, el.ghost_type);
     const Array<UInt> & mat_loc_num =
         model.getMaterialLocalNumbering(el.type, el.ghost_type);
 
     const auto & mat = static_cast<const MaterialCohesive &>(
         model.getMaterial(mat_indexes(el.element)));
 
     UInt el_index = mat_loc_num(el.element);
     UInt nb_quad_per_element =
         model.getFEEngine("CohesiveFEEngine")
             .getNbIntegrationPoints(el.type, el.ghost_type);
 
     const Array<Real> & damage_array = mat.getDamage(el.type, el.ghost_type);
 
     AKANTU_DEBUG_ASSERT(nb_quad_per_element * el_index < damage_array.size(),
                         "This quadrature point is out of range");
 
     const Real * element_damage =
         damage_array.storage() + nb_quad_per_element * el_index;
 
     UInt unbroken_quads = std::count_if(
         element_damage, element_damage + nb_quad_per_element, is_unbroken);
 
     if (unbroken_quads > 0)
       return true;
     return false;
   }
 
 private:
   struct IsUnbrokenFunctor {
     IsUnbrokenFunctor(const Real & max_damage) : max_damage(max_damage) {}
     bool operator()(const Real & x) { return x < max_damage; }
     const Real max_damage;
   };
 
   const SolidMechanicsModelCohesive & model;
   const IsUnbrokenFunctor is_unbroken;
 };
 
 /* -------------------------------------------------------------------------- */
 void FragmentManager::buildFragments(Real damage_limit) {
   AKANTU_DEBUG_IN();
 
 #if defined(AKANTU_PARALLEL_COHESIVE_ELEMENT)
   ElementSynchronizer * cohesive_synchronizer =
       const_cast<ElementSynchronizer *>(model.getCohesiveSynchronizer());
 
   if (cohesive_synchronizer) {
     cohesive_synchronizer->computeBufferSize(model, _gst_smmc_damage);
     cohesive_synchronizer->asynchronousSynchronize(model, _gst_smmc_damage);
     cohesive_synchronizer->waitEndSynchronize(model, _gst_smmc_damage);
   }
 #endif
 
   auto & mesh_facets = const_cast<Mesh &>(mesh.getMeshFacets());
 
   UInt spatial_dimension = model.getSpatialDimension();
   std::string fragment_prefix("fragment");
 
   /// generate fragments
   global_nb_fragment =
       createClusters(spatial_dimension, mesh_facets, fragment_prefix,
                      CohesiveElementFilter(model, damage_limit));
 
   nb_fragment = getNbElementGroups(spatial_dimension);
   fragment_index.resize(nb_fragment);
 
   UInt * fragment_index_it = fragment_index.storage();
 
   /// loop over fragments
   for (const_element_group_iterator it(element_group_begin());
        it != element_group_end(); ++it, ++fragment_index_it) {
 
     /// get fragment index
     std::string fragment_index_string =
         it->first.substr(fragment_prefix.size() + 1);
     std::stringstream sstr(fragment_index_string.c_str());
     sstr >> *fragment_index_it;
 
     AKANTU_DEBUG_ASSERT(!sstr.fail(), "fragment_index is not an integer");
   }
 
   /// compute fragments' mass
   computeMass();
 
   if (dump_data) {
     createDumpDataArray(fragment_index, "fragments", true);
     createDumpDataArray(mass, "fragments mass");
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void FragmentManager::computeMass() {
   AKANTU_DEBUG_IN();
 
   UInt spatial_dimension = model.getSpatialDimension();
 
   /// create a unit field per quadrature point, since to compute mass
   /// it's neccessary to integrate only density
   ElementTypeMapArray<Real> unit_field("unit_field", id);
   unit_field.initialize(model.getFEEngine(), _nb_component = spatial_dimension,
                         _spatial_dimension = spatial_dimension,
                         _ghost_type = _not_ghost, _default_value = 1.);
   // mesh.initElementTypeMapArray(unit_field, spatial_dimension,
   // spatial_dimension,
   //                              _not_ghost);
 
   // ElementTypeMapArray<Real>::type_iterator it =
   //     unit_field.firstType(spatial_dimension, _not_ghost, _ek_regular);
   // ElementTypeMapArray<Real>::type_iterator end =
   //     unit_field.lastType(spatial_dimension, _not_ghost, _ek_regular);
 
   // for (; it != end; ++it) {
   //   ElementType type = *it;
   //   Array<Real> & field_array = unit_field(type);
   //   UInt nb_element = mesh.getNbElement(type);
   //   UInt nb_quad_per_element =
   //   model.getFEEngine().getNbIntegrationPoints(type);
 
   //   field_array.resize(nb_element * nb_quad_per_element);
   //   field_array.set(1.);
   // }
 
   integrateFieldOnFragments(unit_field, mass);
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void FragmentManager::computeCenterOfMass() {
   AKANTU_DEBUG_IN();
 
   /// integrate position multiplied by density
   integrateFieldOnFragments(quad_coordinates, mass_center);
 
   /// divide it by the fragments' mass
   Real * mass_storage = mass.storage();
   Real * mass_center_storage = mass_center.storage();
 
   UInt total_components = mass_center.size() * mass_center.getNbComponent();
 
   for (UInt i = 0; i < total_components; ++i)
     mass_center_storage[i] /= mass_storage[i];
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void FragmentManager::computeVelocity() {
   AKANTU_DEBUG_IN();
 
   UInt spatial_dimension = model.getSpatialDimension();
 
   /// compute velocity per quadrature point
   ElementTypeMapArray<Real> velocity_field("velocity_field", id);
   velocity_field.initialize(
       model.getFEEngine(), _nb_component = spatial_dimension,
       _spatial_dimension = spatial_dimension, _ghost_type = _not_ghost);
 
   // mesh.initElementTypeMapArray(velocity_field, spatial_dimension,
   //                              spatial_dimension, _not_ghost);
 
   model.getFEEngine().interpolateOnIntegrationPoints(model.getVelocity(),
                                                      velocity_field);
 
   /// integrate on fragments
   integrateFieldOnFragments(velocity_field, velocity);
 
   /// divide it by the fragments' mass
   Real * mass_storage = mass.storage();
   Real * velocity_storage = velocity.storage();
 
   UInt total_components = velocity.size() * velocity.getNbComponent();
 
   for (UInt i = 0; i < total_components; ++i)
     velocity_storage[i] /= mass_storage[i];
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 /**
  * Given the distance @f$ \mathbf{r} @f$ between a quadrature point
  * and its center of mass, the moment of inertia is computed as \f[
  * I_\mathrm{CM} = \mathrm{tr}(\mathbf{r}\mathbf{r}^\mathrm{T})
  * \mathbf{I} - \mathbf{r}\mathbf{r}^\mathrm{T} \f] for more
  * information check Wikipedia
  * (http://en.wikipedia.org/wiki/Moment_of_inertia#Identities_for_a_skew-symmetric_matrix)
  *
  */
 
 void FragmentManager::computeInertiaMoments() {
   AKANTU_DEBUG_IN();
 
   UInt spatial_dimension = model.getSpatialDimension();
 
   computeCenterOfMass();
 
   /// compute local coordinates products with respect to the center of match
   ElementTypeMapArray<Real> moments_coords("moments_coords", id);
   moments_coords.initialize(model.getFEEngine(),
                             _nb_component =
                                 spatial_dimension * spatial_dimension,
                             _spatial_dimension = spatial_dimension,
                             _ghost_type = _not_ghost, _default_value = 1.);
 
   // mesh.initElementTypeMapArray(moments_coords,
   //                              spatial_dimension * spatial_dimension,
   //                              spatial_dimension, _not_ghost);
 
   // /// resize the by element type
   // ElementTypeMapArray<Real>::type_iterator it =
   //     moments_coords.firstType(spatial_dimension, _not_ghost, _ek_regular);
   // ElementTypeMapArray<Real>::type_iterator end =
   //     moments_coords.lastType(spatial_dimension, _not_ghost, _ek_regular);
 
   // for (; it != end; ++it) {
   //   ElementType type = *it;
   //   Array<Real> & field_array = moments_coords(type);
   //   UInt nb_element = mesh.getNbElement(type);
   //   UInt nb_quad_per_element =
   //   model.getFEEngine().getNbIntegrationPoints(type);
 
   //   field_array.resize(nb_element * nb_quad_per_element);
   // }
 
   /// compute coordinates
   auto mass_center_it = mass_center.begin(spatial_dimension);
 
   /// loop over fragments
   for (const_element_group_iterator it(element_group_begin());
        it != element_group_end(); ++it, ++mass_center_it) {
 
     const ElementTypeMapArray<UInt> & el_list = it->second->getElements();
     /// loop over elements of the fragment
     for (auto type :
          el_list.elementTypes(spatial_dimension, _not_ghost, _ek_regular)) {
       UInt nb_quad_per_element =
           model.getFEEngine().getNbIntegrationPoints(type);
 
       Array<Real> & moments_coords_array = moments_coords(type);
       const Array<Real> & quad_coordinates_array = quad_coordinates(type);
       const Array<UInt> & el_list_array = el_list(type);
 
       Array<Real>::matrix_iterator moments_begin =
           moments_coords_array.begin(spatial_dimension, spatial_dimension);
       auto quad_coordinates_begin =
           quad_coordinates_array.begin(spatial_dimension);
 
       Vector<Real> relative_coords(spatial_dimension);
 
       for (UInt el = 0; el < el_list_array.size(); ++el) {
         UInt global_el = el_list_array(el);
 
         /// loop over quadrature points
         for (UInt q = 0; q < nb_quad_per_element; ++q) {
           UInt global_q = global_el * nb_quad_per_element + q;
           Matrix<Real> moments_matrix = moments_begin[global_q];
           const Vector<Real> & quad_coord_vector =
               quad_coordinates_begin[global_q];
 
           /// to understand this read the documentation written just
           /// before this function
           relative_coords = quad_coord_vector;
           relative_coords -= *mass_center_it;
 
           moments_matrix.outerProduct(relative_coords, relative_coords);
           Real trace = moments_matrix.trace();
           moments_matrix *= -1.;
           moments_matrix += Matrix<Real>::eye(spatial_dimension, trace);
         }
       }
     }
   }
 
   /// integrate moments
   Array<Real> integrated_moments(global_nb_fragment,
                                  spatial_dimension * spatial_dimension);
 
   integrateFieldOnFragments(moments_coords, integrated_moments);
 
   /// compute and store principal moments
   inertia_moments.resize(global_nb_fragment);
   principal_directions.resize(global_nb_fragment);
 
   Array<Real>::matrix_iterator integrated_moments_it =
       integrated_moments.begin(spatial_dimension, spatial_dimension);
   auto inertia_moments_it = inertia_moments.begin(spatial_dimension);
   Array<Real>::matrix_iterator principal_directions_it =
       principal_directions.begin(spatial_dimension, spatial_dimension);
 
   for (UInt frag = 0; frag < global_nb_fragment; ++frag,
             ++integrated_moments_it, ++inertia_moments_it,
             ++principal_directions_it) {
     integrated_moments_it->eig(*inertia_moments_it, *principal_directions_it);
   }
 
   if (dump_data)
     createDumpDataArray(inertia_moments, "moments of inertia");
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void FragmentManager::computeAllData() {
   AKANTU_DEBUG_IN();
 
   buildFragments();
   computeVelocity();
   computeInertiaMoments();
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void FragmentManager::storeMassDensityPerIntegrationPoint() {
   AKANTU_DEBUG_IN();
 
   UInt spatial_dimension = model.getSpatialDimension();
 
   Mesh::type_iterator it = mesh.firstType(spatial_dimension);
   Mesh::type_iterator end = mesh.lastType(spatial_dimension);
 
   for (; it != end; ++it) {
     ElementType type = *it;
 
     Array<Real> & mass_density_array = mass_density(type);
 
     UInt nb_element = mesh.getNbElement(type);
     UInt nb_quad_per_element = model.getFEEngine().getNbIntegrationPoints(type);
     mass_density_array.resize(nb_element * nb_quad_per_element);
 
     const Array<UInt> & mat_indexes = model.getMaterialByElement(type);
 
     Real * mass_density_it = mass_density_array.storage();
 
     /// store mass_density for each element and quadrature point
     for (UInt el = 0; el < nb_element; ++el) {
       Material & mat = model.getMaterial(mat_indexes(el));
 
       for (UInt q = 0; q < nb_quad_per_element; ++q, ++mass_density_it)
         *mass_density_it = mat.getRho();
     }
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void FragmentManager::integrateFieldOnFragments(
     ElementTypeMapArray<Real> & field, Array<Real> & output) {
   AKANTU_DEBUG_IN();
 
   UInt spatial_dimension = model.getSpatialDimension();
   UInt nb_component = output.getNbComponent();
 
   /// integration part
   output.resize(global_nb_fragment);
   output.clear();
 
   UInt * fragment_index_it = fragment_index.storage();
   auto output_begin = output.begin(nb_component);
 
   /// loop over fragments
   for (const_element_group_iterator it(element_group_begin());
        it != element_group_end(); ++it, ++fragment_index_it) {
 
     const ElementTypeMapArray<UInt> & el_list = it->second->getElements();
 
     /// loop over elements of the fragment
     for (auto type :
          el_list.elementTypes(spatial_dimension, _not_ghost, _ek_regular)) {
 
       UInt nb_quad_per_element =
           model.getFEEngine().getNbIntegrationPoints(type);
 
       const Array<Real> & density_array = mass_density(type);
       Array<Real> & field_array = field(type);
       const Array<UInt> & elements = el_list(type);
       UInt nb_element = elements.size();
 
       /// generate array to be integrated by filtering fragment's elements
       Array<Real> integration_array(elements.size() * nb_quad_per_element,
                                     nb_component);
 
       Array<Real>::matrix_iterator int_array_it =
           integration_array.begin_reinterpret(nb_quad_per_element, nb_component,
                                               nb_element);
       Array<Real>::matrix_iterator int_array_end =
           integration_array.end_reinterpret(nb_quad_per_element, nb_component,
                                             nb_element);
       Array<Real>::matrix_iterator field_array_begin =
           field_array.begin_reinterpret(nb_quad_per_element, nb_component,
                                         field_array.size() /
                                             nb_quad_per_element);
       auto density_array_begin = density_array.begin_reinterpret(
           nb_quad_per_element, density_array.size() / nb_quad_per_element);
 
       for (UInt el = 0; int_array_it != int_array_end; ++int_array_it, ++el) {
         UInt global_el = elements(el);
         *int_array_it = field_array_begin[global_el];
 
         /// multiply field by density
         const Vector<Real> & density_vector = density_array_begin[global_el];
 
         for (UInt i = 0; i < nb_quad_per_element; ++i) {
           for (UInt j = 0; j < nb_component; ++j) {
             (*int_array_it)(i, j) *= density_vector(i);
           }
         }
       }
 
       /// integrate the field over the fragment
       Array<Real> integrated_array(elements.size(), nb_component);
       model.getFEEngine().integrate(integration_array, integrated_array,
                                     nb_component, type, _not_ghost, elements);
 
       /// sum over all elements and store the result
       Vector<Real> output_tmp(output_begin[*fragment_index_it]);
       output_tmp += std::accumulate(integrated_array.begin(nb_component),
                                     integrated_array.end(nb_component),
                                     Vector<Real>(nb_component));
     }
   }
 
   /// sum output over all processors
   const Communicator & comm = mesh.getCommunicator();
   comm.allReduce(output, SynchronizerOperation::_sum);
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void FragmentManager::computeNbElementsPerFragment() {
   AKANTU_DEBUG_IN();
 
   UInt spatial_dimension = model.getSpatialDimension();
   nb_elements_per_fragment.resize(global_nb_fragment);
   nb_elements_per_fragment.clear();
 
   UInt * fragment_index_it = fragment_index.storage();
 
   /// loop over fragments
   for (const_element_group_iterator it(element_group_begin());
        it != element_group_end(); ++it, ++fragment_index_it) {
 
     const ElementTypeMapArray<UInt> & el_list = it->second->getElements();
 
     /// loop over elements of the fragment
     for (auto type :
          el_list.elementTypes(spatial_dimension, _not_ghost, _ek_regular)) {
       UInt nb_element = el_list(type).size();
 
       nb_elements_per_fragment(*fragment_index_it) += nb_element;
     }
   }
 
   /// sum values over all processors
   const auto & comm = mesh.getCommunicator();
   comm.allReduce(nb_elements_per_fragment, SynchronizerOperation::_sum);
 
   if (dump_data)
     createDumpDataArray(nb_elements_per_fragment, "elements per fragment");
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <typename T>
 void FragmentManager::createDumpDataArray(Array<T> & data, std::string name,
                                           bool fragment_index_output) {
   AKANTU_DEBUG_IN();
 
   if (data.size() == 0)
     return;
 
   auto & mesh_not_const = const_cast<Mesh &>(mesh);
 
   auto && spatial_dimension = mesh.getSpatialDimension();
   auto && nb_component = data.getNbComponent();
   auto && data_begin = data.begin(nb_component);
   auto fragment_index_it = fragment_index.begin();
 
   /// loop over fragments
   for (const auto & fragment : ElementGroupsIterable(*this)) {
     const auto & fragment_idx = *fragment_index_it;
 
     /// loop over cluster types
     for (auto & type : fragment.elementTypes(spatial_dimension)) {
       /// init mesh data
       auto & mesh_data = mesh_not_const.getDataPointer<T>(
           name, type, _not_ghost, nb_component);
 
       auto mesh_data_begin = mesh_data.begin(nb_component);
 
       /// fill mesh data
       for (const auto & elem : fragment.getElements(type)) {
         Vector<T> md_tmp = mesh_data_begin[elem];
         if (fragment_index_output) {
           md_tmp(0) = fragment_idx;
         } else {
           md_tmp = data_begin[fragment_idx];
         }
       }
     }
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 } // namespace akantu
diff --git a/src/model/solid_mechanics/solid_mechanics_model_cohesive/fragment_manager.hh b/src/model/solid_mechanics/solid_mechanics_model_cohesive/fragment_manager.hh
index 74f676cd4..eaf2025f7 100644
--- a/src/model/solid_mechanics/solid_mechanics_model_cohesive/fragment_manager.hh
+++ b/src/model/solid_mechanics/solid_mechanics_model_cohesive/fragment_manager.hh
@@ -1,169 +1,169 @@
 /**
  * @file   fragment_manager.hh
  *
  * @author Marco Vocialta <marco.vocialta@epfl.ch>
  *
  * @date creation: Thu Jan 23 2014
- * @date last modification: Mon Dec 14 2015
+ * @date last modification: Thu Jul 06 2017
  *
  * @brief  Group manager to handle fragments
  *
  * @section LICENSE
  *
- * Copyright  (©)  2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de Lausanne)
+ * 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
+ * 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
+ * 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 "group_manager.hh"
 /* -------------------------------------------------------------------------- */
 
 #ifndef __AKANTU_FRAGMENT_MANAGER_HH__
 #define __AKANTU_FRAGMENT_MANAGER_HH__
 
 namespace akantu {
 class SolidMechanicsModelCohesive;
 }
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 class FragmentManager : public GroupManager {
   /* ------------------------------------------------------------------------ */
   /* Constructors/Destructors                                                 */
   /* ------------------------------------------------------------------------ */
 public:
   FragmentManager(SolidMechanicsModelCohesive & model, bool dump_data = true,
                   const ID & id = "fragment_manager",
                   const MemoryID & memory_id = 0);
 
   /* ------------------------------------------------------------------------ */
   /* Methods                                                                  */
   /* ------------------------------------------------------------------------ */
 private:
   /// store mass density per integration point
   void storeMassDensityPerIntegrationPoint();
 
   /// integrate an elemental field multiplied by density on global
   /// fragments
   void integrateFieldOnFragments(ElementTypeMapArray<Real> & field,
                                  Array<Real> & output);
 
   /// compute fragments' mass
   void computeMass();
 
   /// create dump data for a single array
   template <typename T>
   void createDumpDataArray(Array<T> & data, std::string name,
                            bool fragment_index_output = false);
 
 public:
   /// build fragment list (cohesive elements are considered broken if
   /// damage >= damage_limit)
   void buildFragments(Real damage_limit = 1.);
 
   /// compute fragments' center of mass
   void computeCenterOfMass();
 
   /// compute fragments' velocity
   void computeVelocity();
 
   /// computes principal moments of inertia with respect to the center
   /// of mass of each fragment
   void computeInertiaMoments();
 
   /// compute all fragments' data
   void computeAllData();
 
   /// compute number of elements per fragment
   void computeNbElementsPerFragment();
 
   /* ------------------------------------------------------------------------ */
   /* Accessors                                                                */
   /* ------------------------------------------------------------------------ */
 public:
   /// get number of fragments
   AKANTU_GET_MACRO(NbFragment, global_nb_fragment, UInt);
 
   /// get fragments' mass
   AKANTU_GET_MACRO(Mass, mass, const Array<Real> &);
 
   /// get fragments' center of mass
   AKANTU_GET_MACRO(CenterOfMass, mass_center, const Array<Real> &);
 
   /// get fragments' velocity
   AKANTU_GET_MACRO(Velocity, velocity, const Array<Real> &);
 
   /// get fragments' principal moments of inertia
   AKANTU_GET_MACRO(MomentsOfInertia, inertia_moments, const Array<Real> &);
 
   /// get fragments' principal directions
   AKANTU_GET_MACRO(PrincipalDirections, principal_directions,
                    const Array<Real> &);
 
   /// get number of elements per fragment
   AKANTU_GET_MACRO(NbElementsPerFragment, nb_elements_per_fragment,
                    const Array<UInt> &);
 
   /* ------------------------------------------------------------------------ */
   /* Class Members                                                            */
   /* ------------------------------------------------------------------------ */
 private:
   /// local_fragment index
   Array<UInt> fragment_index;
 
   /// global number of fragments (parallel simulations)
   UInt global_nb_fragment;
 
   /// number of fragments
   UInt nb_fragment;
 
   /// cohesive solid mechanics model associated
   SolidMechanicsModelCohesive & model;
 
   /// fragments' center of mass
   Array<Real> mass_center;
 
   /// fragments' mass
   Array<Real> mass;
 
   /// fragments' velocity
   Array<Real> velocity;
 
   /// fragments' principal moments of inertia with respect to the
   /// center of mass
   Array<Real> inertia_moments;
 
   /// fragments' principal directions
   Array<Real> principal_directions;
 
   /// quadrature points' coordinates
   ElementTypeMapArray<Real> quad_coordinates;
 
   /// mass density per quadrature point
   ElementTypeMapArray<Real> mass_density;
 
   /// fragment filter
   Array<UInt> nb_elements_per_fragment;
 
   /// dump data
   bool dump_data;
 };
 
 } // akantu
 
 #endif /* __AKANTU_FRAGMENT_MANAGER_HH__ */
diff --git a/src/model/solid_mechanics/solid_mechanics_model_cohesive/material_selector_cohesive.cc b/src/model/solid_mechanics/solid_mechanics_model_cohesive/material_selector_cohesive.cc
index cfed39f0e..3f052a5fb 100644
--- a/src/model/solid_mechanics/solid_mechanics_model_cohesive/material_selector_cohesive.cc
+++ b/src/model/solid_mechanics/solid_mechanics_model_cohesive/material_selector_cohesive.cc
@@ -1,159 +1,159 @@
 /**
  * @file   material_selector_cohesive.cc
  *
  * @author Mauro Corrado <mauro.corrado@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  * @author Marco Vocialta <marco.vocialta@epfl.ch>
  *
  * @date creation: Fri Dec 11 2015
- * @date last modification: Mon Dec 14 2015
+ * @date last modification: Mon Dec 18 2017
  *
  * @brief  Material selector for cohesive elements
  *
  * @section LICENSE
  *
- * Copyright (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne) Laboratory
- * (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * Copyright (©) 2015-2018 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
- * terms  of the  GNU Lesser  General Public  License as  published by  the Free
+ * 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
+ * A PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 #include "material_selector_cohesive.hh"
 #include "solid_mechanics_model_cohesive.hh"
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 DefaultMaterialCohesiveSelector::DefaultMaterialCohesiveSelector(
     const SolidMechanicsModelCohesive & model)
     : facet_material(model.getFacetMaterial()), mesh(model.getMesh()) {
   // backward compatibility v3: to get the former behavior back when the user
   // creates its own selector
   this->fallback_selector =
       std::make_shared<DefaultMaterialSelector>(model.getMaterialByElement());
 }
 
 /* -------------------------------------------------------------------------- */
 UInt DefaultMaterialCohesiveSelector::operator()(const Element & element) {
   if (Mesh::getKind(element.type) == _ek_cohesive) {
     try {
       const Array<Element> & cohesive_el_to_facet =
           mesh.getMeshFacets().getSubelementToElement(element.type,
                                                       element.ghost_type);
       bool third_dimension = (mesh.getSpatialDimension() == 3);
       const Element & facet =
           cohesive_el_to_facet(element.element, third_dimension);
       if (facet_material.exists(facet.type, facet.ghost_type)) {
         return facet_material(facet.type, facet.ghost_type)(facet.element);
       } else {
         return fallback_value;
       }
     } catch (...) {
       return fallback_value;
     }
   } else if (Mesh::getSpatialDimension(element.type) ==
              mesh.getSpatialDimension() - 1) {
     return facet_material(element.type, element.ghost_type)(element.element);
   } else {
     return MaterialSelector::operator()(element);
   }
 }
 
 /* -------------------------------------------------------------------------- */
 MeshDataMaterialCohesiveSelector::MeshDataMaterialCohesiveSelector(
     const SolidMechanicsModelCohesive & model)
     : model(model), mesh_facets(model.getMeshFacets()),
       material_index(mesh_facets.getData<std::string>("physical_names")) {
   third_dimension = (model.getSpatialDimension() == 3);
   // backward compatibility v3: to get the former behavior back when the user
   // creates its own selector
   this->fallback_selector =
       std::make_shared<MeshDataMaterialSelector<std::string>>("physical_names",
                                                               model);
 }
 
 /* -------------------------------------------------------------------------- */
 UInt MeshDataMaterialCohesiveSelector::operator()(const Element & element) {
   if (Mesh::getKind(element.type) == _ek_cohesive) {
     const auto & facet = mesh_facets.getSubelementToElement(
         element.type, element.ghost_type)(element.element, third_dimension);
     try {
       std::string material_name = this->material_index(facet);
       return this->model.getMaterialIndex(material_name);
     } catch (...) {
       return fallback_value;
     }
   } else
     return MaterialSelector::operator()(element);
 }
 
 /* -------------------------------------------------------------------------- */
 /* -------------------------------------------------------------------------- */
 MaterialCohesiveRulesSelector::MaterialCohesiveRulesSelector(
     const SolidMechanicsModelCohesive & model,
     const MaterialCohesiveRules & rules,
     ID mesh_data_id) // what we have here is the name of model and also
                      // the name of different materials
     : model(model), mesh_data_id(std::move(mesh_data_id)),
       mesh(model.getMesh()), mesh_facets(model.getMeshFacets()),
       spatial_dimension(model.getSpatialDimension()), rules(rules) {
 
   // cohesive fallback
   this->fallback_selector =
       std::make_shared<DefaultMaterialCohesiveSelector>(model);
 
   // non cohesive fallback
   this->fallback_selector->setFallback(
       std::make_shared<MeshDataMaterialSelector<std::string>>("physical_names",
                                                               model));
 }
 
 /* -------------------------------------------------------------------------- */
 UInt MaterialCohesiveRulesSelector::operator()(const Element & element) {
   if (mesh_facets.getSpatialDimension(element.type) ==
       (spatial_dimension - 1)) {
     const std::vector<Element> & element_to_subelement =
         mesh_facets.getElementToSubelement(element.type,
                                            element.ghost_type)(element.element);
     // Array<bool> & facets_check = model.getFacetsCheck();
 
     const Element & el1 = element_to_subelement[0];
     const Element & el2 = element_to_subelement[1];
 
     ID id1 = mesh.getData<std::string>(mesh_data_id, el1.type,
                                        el1.ghost_type)(el1.element);
 
     ID id2 = id1;
     if (el2 != ElementNull) {
       id2 = mesh.getData<std::string>(mesh_data_id, el2.type,
                                       el2.ghost_type)(el2.element);
     }
 
     auto rit = rules.find(std::make_pair(id1, id2));
     if (rit == rules.end()) {
       rit = rules.find(std::make_pair(id2, id1));
     }
 
     if (rit != rules.end()) {
       return model.getMaterialIndex(rit->second);
     }
   }
 
   return MaterialSelector::operator()(element);
 }
 
 } // namespace akantu
diff --git a/src/model/solid_mechanics/solid_mechanics_model_cohesive/material_selector_cohesive.hh b/src/model/solid_mechanics/solid_mechanics_model_cohesive/material_selector_cohesive.hh
index a5dd25995..a6ef7c4ed 100644
--- a/src/model/solid_mechanics/solid_mechanics_model_cohesive/material_selector_cohesive.hh
+++ b/src/model/solid_mechanics/solid_mechanics_model_cohesive/material_selector_cohesive.hh
@@ -1,98 +1,99 @@
 /**
  * @file   material_selector_cohesive.hh
  *
  * @author Mauro Corrado <mauro.corrado@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  * @author Marco Vocialta <marco.vocialta@epfl.ch>
  *
  * @date creation: Fri Dec 11 2015
- * @date last modification: Mon Dec 14 2015
+ * @date last modification: Mon Dec 18 2017
  *
  * @brief  Material selectors for cohesive elements
  *
  * @section LICENSE
  *
- * Copyright (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne) Laboratory
- * (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * Copyright (©) 2015-2018 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
- * terms  of the  GNU Lesser  General Public  License as  published by  the Free
+ * 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
+ * A PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
+
 /* -------------------------------------------------------------------------- */
 #include "material_selector.hh"
 /* -------------------------------------------------------------------------- */
 #include <map>
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 class SolidMechanicsModelCohesive;
 }
 
 namespace akantu {
 
 #ifndef __AKANTU_MATERIAL_SELECTOR_COHESIVE_HH__
 #define __AKANTU_MATERIAL_SELECTOR_COHESIVE_HH__
 
 /* -------------------------------------------------------------------------- */
 /**
  * class that assigns the first cohesive material by default to the
  * cohesive elements
  */
 class DefaultMaterialCohesiveSelector : public MaterialSelector {
 public:
   DefaultMaterialCohesiveSelector(const SolidMechanicsModelCohesive & model);
   UInt operator()(const Element & element) override;
 
 private:
   const ElementTypeMapArray<UInt> & facet_material;
   const Mesh & mesh;
 };
 
 /* -------------------------------------------------------------------------- */
 /// To be used with intrinsic elements inserted along mesh physical surfaces
 class MeshDataMaterialCohesiveSelector : public MaterialSelector {
 public:
   MeshDataMaterialCohesiveSelector(const SolidMechanicsModelCohesive & model);
   UInt operator()(const Element & element) override;
 
 protected:
   const SolidMechanicsModelCohesive & model;
   const Mesh & mesh_facets;
   const ElementTypeMapArray<std::string> & material_index;
   bool third_dimension;
 };
 
 /// bulk1, bulk2 -> cohesive
 using MaterialCohesiveRules = std::map<std::pair<ID, ID>, ID>;
 
 /* -------------------------------------------------------------------------- */
 class MaterialCohesiveRulesSelector : public MaterialSelector {
 public:
   MaterialCohesiveRulesSelector(const SolidMechanicsModelCohesive & model,
                                 const MaterialCohesiveRules & rules,
                                 ID mesh_data_id = "physical_names");
   UInt operator()(const Element & element);
 
 private:
   const SolidMechanicsModelCohesive & model;
   ID mesh_data_id;
   const Mesh & mesh;
   const Mesh & mesh_facets;
   UInt spatial_dimension;
   MaterialCohesiveRules rules;
 };
 
 #endif /* __AKANTU_MATERIAL_SELECTOR_COHESIVE_HH__ */
 
 } // akantu
diff --git a/src/model/solid_mechanics/solid_mechanics_model_cohesive/materials/cohesive_internal_field.hh b/src/model/solid_mechanics/solid_mechanics_model_cohesive/materials/cohesive_internal_field.hh
index 22e2c96dd..c67ea80fd 100644
--- a/src/model/solid_mechanics/solid_mechanics_model_cohesive/materials/cohesive_internal_field.hh
+++ b/src/model/solid_mechanics/solid_mechanics_model_cohesive/materials/cohesive_internal_field.hh
@@ -1,68 +1,67 @@
 /**
  * @file   cohesive_internal_field.hh
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Fri Jun 18 2010
- * @date last modification: Thu Oct 08 2015
+ * @date last modification: Wed Nov 08 2017
  *
  * @brief  Internal field for cohesive elements
  *
  * @section LICENSE
  *
- * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
- * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
- * Solides)
+ * 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
+ * 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
+ * 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 "internal_field.hh"
 
 #ifndef __AKANTU_COHESIVE_INTERNAL_FIELD_HH__
 #define __AKANTU_COHESIVE_INTERNAL_FIELD_HH__
 
 namespace akantu {
 
 /// internal field class for cohesive materials
 template <typename T> class CohesiveInternalField : public InternalField<T> {
 public:
   CohesiveInternalField(const ID & id, Material & material);
   ~CohesiveInternalField() override;
 
   /// initialize the field to a given number of component
   void initialize(UInt nb_component) override;
 
 private:
   CohesiveInternalField operator=(__attribute__((unused))
                                   const CohesiveInternalField & other){};
 };
 
 /* -------------------------------------------------------------------------- */
 /* Facet Internal Field                                                       */
 /* -------------------------------------------------------------------------- */
 template <typename T> class FacetInternalField : public InternalField<T> {
 public:
   FacetInternalField(const ID & id, Material & material);
   ~FacetInternalField() override;
 
   /// initialize the field to a given number of component
   void initialize(UInt nb_component) override;
 };
 
 } // akantu
 
 #endif /* __AKANTU_COHESIVE_INTERNAL_FIELD_HH__ */
diff --git a/src/model/solid_mechanics/solid_mechanics_model_cohesive/materials/cohesive_internal_field_tmpl.hh b/src/model/solid_mechanics/solid_mechanics_model_cohesive/materials/cohesive_internal_field_tmpl.hh
index 0b2c80de8..52c688752 100644
--- a/src/model/solid_mechanics/solid_mechanics_model_cohesive/materials/cohesive_internal_field_tmpl.hh
+++ b/src/model/solid_mechanics/solid_mechanics_model_cohesive/materials/cohesive_internal_field_tmpl.hh
@@ -1,95 +1,95 @@
 /**
  * @file   cohesive_internal_field_tmpl.hh
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  * @author Marco Vocialta <marco.vocialta@epfl.ch>
  *
  * @date creation: Wed Nov 13 2013
- * @date last modification: Thu Jan 21 2016
+ * @date last modification: Wed Nov 08 2017
  *
  * @brief  implementation of the cohesive internal field
  *
  * @section LICENSE
  *
- * Copyright  (©)  2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de Lausanne)
+ * 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
+ * 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
+ * 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_COHESIVE_INTERNAL_FIELD_TMPL_HH__
 #define __AKANTU_COHESIVE_INTERNAL_FIELD_TMPL_HH__
 
 namespace akantu {
 
 template <typename T>
 CohesiveInternalField<T>::CohesiveInternalField(const ID & id,
                                                 Material & material)
     : InternalField<T>(
           id, material, material.getModel().getFEEngine("CohesiveFEEngine"),
           dynamic_cast<MaterialCohesive &>(material).getElementFilter()) {
   this->element_kind = _ek_cohesive;
 }
 
 template <typename T>
 CohesiveInternalField<T>::~CohesiveInternalField() = default;
 
 template <typename T>
 void CohesiveInternalField<T>::initialize(UInt nb_component) {
   this->internalInitialize(nb_component);
 }
 
 /* -------------------------------------------------------------------------- */
 template <typename T>
 FacetInternalField<T>::FacetInternalField(const ID & id, Material & material)
     : InternalField<T>(
           id, material, material.getModel().getFEEngine("FacetsFEEngine"),
           dynamic_cast<MaterialCohesive &>(material).getFacetFilter()) {
   this->spatial_dimension -= 1;
   this->element_kind = _ek_regular;
 }
 
 template <typename T> FacetInternalField<T>::~FacetInternalField() = default;
 
 template <typename T>
 void FacetInternalField<T>::initialize(UInt nb_component) {
   this->internalInitialize(nb_component);
 }
 
 /* -------------------------------------------------------------------------- */
 template <>
 inline void
 ParameterTyped<RandomInternalField<Real, FacetInternalField>>::setAuto(
     const ParserParameter & in_param) {
   Parameter::setAuto(in_param);
   RandomParameter<Real> r = in_param;
   param.setRandomDistribution(r);
 }
 
 /* -------------------------------------------------------------------------- */
 template <>
 inline void
 ParameterTyped<RandomInternalField<Real, CohesiveInternalField>>::setAuto(
     const ParserParameter & in_param) {
   Parameter::setAuto(in_param);
   RandomParameter<Real> r = in_param;
   param.setRandomDistribution(r);
 }
 
 } // akantu
 
 #endif /* __AKANTU_COHESIVE_INTERNAL_FIELD_TMPL_HH__ */
diff --git a/src/model/solid_mechanics/solid_mechanics_model_cohesive/materials/constitutive_laws/material_cohesive_bilinear.cc b/src/model/solid_mechanics/solid_mechanics_model_cohesive/materials/constitutive_laws/material_cohesive_bilinear.cc
index 1be65c688..dffd4f680 100644
--- a/src/model/solid_mechanics/solid_mechanics_model_cohesive/materials/constitutive_laws/material_cohesive_bilinear.cc
+++ b/src/model/solid_mechanics/solid_mechanics_model_cohesive/materials/constitutive_laws/material_cohesive_bilinear.cc
@@ -1,217 +1,216 @@
 /**
  * @file   material_cohesive_bilinear.cc
  *
  * @author Marco Vocialta <marco.vocialta@epfl.ch>
  *
  * @date creation: Wed Feb 22 2012
- * @date last modification: Thu Oct 15 2015
+ * @date last modification: Tue Feb 20 2018
  *
  * @brief  Bilinear cohesive constitutive law
  *
  * @section LICENSE
  *
- * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
- * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
- * Solides)
+ * 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
+ * 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
+ * A PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 #include "material_cohesive_bilinear.hh"
 //#include "solid_mechanics_model_cohesive.hh"
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 template <UInt spatial_dimension>
 MaterialCohesiveBilinear<spatial_dimension>::MaterialCohesiveBilinear(
     SolidMechanicsModel & model, const ID & id)
     : MaterialCohesiveLinear<spatial_dimension>(model, id) {
   AKANTU_DEBUG_IN();
 
   this->registerParam("delta_0", delta_0, Real(0.),
                       _pat_parsable | _pat_readable,
                       "Elastic limit displacement");
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <UInt spatial_dimension>
 void MaterialCohesiveBilinear<spatial_dimension>::initMaterial() {
   AKANTU_DEBUG_IN();
 
   this->sigma_c_eff.setRandomDistribution(this->sigma_c.getRandomParameter());
   MaterialCohesiveLinear<spatial_dimension>::initMaterial();
 
   this->delta_max.setDefaultValue(delta_0);
   this->insertion_stress.setDefaultValue(0);
 
   this->delta_max.reset();
   this->insertion_stress.reset();
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <UInt spatial_dimension>
 void MaterialCohesiveBilinear<spatial_dimension>::onElementsAdded(
     const Array<Element> & element_list, const NewElementsEvent & event) {
   AKANTU_DEBUG_IN();
 
   MaterialCohesiveLinear<spatial_dimension>::onElementsAdded(element_list,
                                                              event);
 
   bool scale_traction = false;
 
   // don't scale sigma_c if volume_s hasn't been specified by the user
   if (!Math::are_float_equal(this->volume_s, 0.))
     scale_traction = true;
 
   Array<Element>::const_scalar_iterator el_it = element_list.begin();
   Array<Element>::const_scalar_iterator el_end = element_list.end();
 
   for (; el_it != el_end; ++el_it) {
     // filter not ghost cohesive elements
     if (el_it->ghost_type != _not_ghost ||
         Mesh::getKind(el_it->type) != _ek_cohesive)
       continue;
 
     UInt index = el_it->element;
     ElementType type = el_it->type;
     UInt nb_element = this->model->getMesh().getNbElement(type);
     UInt nb_quad_per_element = this->fem_cohesive.getNbIntegrationPoints(type);
 
     auto sigma_c_begin = this->sigma_c_eff(type).begin_reinterpret(
         nb_quad_per_element, nb_element);
     Vector<Real> sigma_c_vec = sigma_c_begin[index];
 
     auto delta_c_begin = this->delta_c_eff(type).begin_reinterpret(
         nb_quad_per_element, nb_element);
     Vector<Real> delta_c_vec = delta_c_begin[index];
 
     if (scale_traction)
       scaleTraction(*el_it, sigma_c_vec);
 
     /**
      * Recompute sigma_c as
      * @f$ {\sigma_c}_\textup{new} =
      * \frac{{\sigma_c}_\textup{old} \delta_c} {\delta_c - \delta_0} @f$
      */
 
     for (UInt q = 0; q < nb_quad_per_element; ++q) {
       delta_c_vec(q) = 2 * this->G_c / sigma_c_vec(q);
 
       if (delta_c_vec(q) - delta_0 < Math::getTolerance())
         AKANTU_ERROR("delta_0 = " << delta_0 << " must be lower than delta_c = "
                                   << delta_c_vec(q)
                                   << ", modify your material file");
 
       sigma_c_vec(q) *= delta_c_vec(q) / (delta_c_vec(q) - delta_0);
     }
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <UInt spatial_dimension>
 void MaterialCohesiveBilinear<spatial_dimension>::scaleTraction(
     const Element & el, Vector<Real> & sigma_c_vec) {
   AKANTU_DEBUG_IN();
 
   Real base_sigma_c = this->sigma_c_eff;
 
   const Mesh & mesh_facets = this->model->getMeshFacets();
   const FEEngine & fe_engine = this->model->getFEEngine();
 
   auto coh_element_to_facet_begin =
       mesh_facets.getSubelementToElement(el.type).begin(2);
   const Vector<Element> & coh_element_to_facet =
       coh_element_to_facet_begin[el.element];
 
   // compute bounding volume
   Real volume = 0;
 
   // loop over facets
   for (UInt f = 0; f < 2; ++f) {
     const Element & facet = coh_element_to_facet(f);
 
     const Array<std::vector<Element>> & facet_to_element =
         mesh_facets.getElementToSubelement(facet.type, facet.ghost_type);
 
     const std::vector<Element> & element_list = facet_to_element(facet.element);
 
     auto elem = element_list.begin();
     auto elem_end = element_list.end();
 
     // loop over elements connected to each facet
     for (; elem != elem_end; ++elem) {
       // skip cohesive elements and dummy elements
       if (*elem == ElementNull || Mesh::getKind(elem->type) == _ek_cohesive)
         continue;
 
       // unit vector for integration in order to obtain the volume
       UInt nb_quadrature_points = fe_engine.getNbIntegrationPoints(elem->type);
       Vector<Real> unit_vector(nb_quadrature_points, 1);
 
       volume += fe_engine.integrate(unit_vector, elem->type, elem->element,
                                     elem->ghost_type);
     }
   }
 
   // scale sigma_c
   sigma_c_vec -= base_sigma_c;
   sigma_c_vec *= std::pow(this->volume_s / volume, 1. / this->m_s);
   sigma_c_vec += base_sigma_c;
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <UInt spatial_dimension>
 void MaterialCohesiveBilinear<spatial_dimension>::computeTraction(
     const Array<Real> & normal, ElementType el_type, GhostType ghost_type) {
   AKANTU_DEBUG_IN();
   MaterialCohesiveLinear<spatial_dimension>::computeTraction(normal, el_type,
                                                              ghost_type);
 
   // adjust damage
   Array<Real>::scalar_iterator delta_c_it =
       this->delta_c_eff(el_type, ghost_type).begin();
 
   Array<Real>::scalar_iterator delta_max_it =
       this->delta_max(el_type, ghost_type).begin();
 
   Array<Real>::scalar_iterator damage_it =
       this->damage(el_type, ghost_type).begin();
 
   Array<Real>::scalar_iterator damage_end =
       this->damage(el_type, ghost_type).end();
 
   for (; damage_it != damage_end; ++damage_it, ++delta_max_it, ++delta_c_it) {
     *damage_it =
         std::max((*delta_max_it - delta_0) / (*delta_c_it - delta_0), Real(0.));
     *damage_it = std::min(*damage_it, Real(1.));
   }
 }
 
 /* -------------------------------------------------------------------------- */
 
 INSTANTIATE_MATERIAL(cohesive_bilinear, MaterialCohesiveBilinear);
 
 } // namespace akantu
diff --git a/src/model/solid_mechanics/solid_mechanics_model_cohesive/materials/constitutive_laws/material_cohesive_bilinear.hh b/src/model/solid_mechanics/solid_mechanics_model_cohesive/materials/constitutive_laws/material_cohesive_bilinear.hh
index 4c5b6a09d..5653bf663 100644
--- a/src/model/solid_mechanics/solid_mechanics_model_cohesive/materials/constitutive_laws/material_cohesive_bilinear.hh
+++ b/src/model/solid_mechanics/solid_mechanics_model_cohesive/materials/constitutive_laws/material_cohesive_bilinear.hh
@@ -1,106 +1,105 @@
 /**
  * @file   material_cohesive_bilinear.hh
  *
  * @author Marco Vocialta <marco.vocialta@epfl.ch>
  *
  * @date creation: Fri Jun 18 2010
- * @date last modification: Sun Oct 19 2014
+ * @date last modification: Sun Dec 03 2017
  *
  * @brief  Bilinear cohesive constitutive law
  *
  * @section LICENSE
  *
- * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
- * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
- * Solides)
+ * 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
+ * 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
+ * A PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 
 #include "material_cohesive_linear.hh"
 
 #ifndef __AKANTU_MATERIAL_COHESIVE_BILINEAR_HH__
 #define __AKANTU_MATERIAL_COHESIVE_BILINEAR_HH__
 
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 
 /**
  * Cohesive material bilinear
  *
  * parameters in the material files :
  *   - delta_0   : elastic limit displacement (default: 0)
  *   - sigma_c   : critical stress sigma_c  (default: 0)
  *   - beta      : weighting parameter for sliding and normal opening (default:
  * 0)
  *   - G_cI      : fracture energy for mode I (default: 0)
  *   - G_cII     : fracture energy for mode II (default: 0)
  *   - penalty   : stiffness in compression to prevent penetration
  */
 template <UInt spatial_dimension>
 class MaterialCohesiveBilinear
     : public MaterialCohesiveLinear<spatial_dimension> {
   /* ------------------------------------------------------------------------ */
   /* Constructors/Destructors                                                 */
   /* ------------------------------------------------------------------------ */
 public:
   MaterialCohesiveBilinear(SolidMechanicsModel & model, const ID & id = "");
 
   /* ------------------------------------------------------------------------ */
   /* Methods                                                                  */
   /* ------------------------------------------------------------------------ */
 public:
   /// initialize the material computed parameter
   void initMaterial() override;
 
   /// set material parameters for new elements
   void onElementsAdded(const Array<Element> & element_list,
                        const NewElementsEvent & event) override;
 
 protected:
   /// constitutive law
   void computeTraction(const Array<Real> & normal, ElementType el_type,
                        GhostType ghost_type = _not_ghost) override;
 
   /**
    * Scale traction sigma_c according to the volume of the
    * two elements surrounding an element
    */
   void scaleTraction(const Element & el, Vector<Real> & sigma_c_vec);
 
   /* ------------------------------------------------------------------------ */
   /* Accessors                                                                */
   /* ------------------------------------------------------------------------ */
 public:
   /* ------------------------------------------------------------------------ */
   /* Class Members                                                            */
   /* ------------------------------------------------------------------------ */
 protected:
   /// elastic limit displacement
   Real delta_0;
 };
 
 /* -------------------------------------------------------------------------- */
 /* inline functions                                                           */
 /* -------------------------------------------------------------------------- */
 
 //#include "material_cohesive_elastic_inline_impl.cc"
 
 } // akantu
 
 #endif /* __AKANTU_MATERIAL_COHESIVE_BILINEAR_HH__ */
diff --git a/src/model/solid_mechanics/solid_mechanics_model_cohesive/materials/constitutive_laws/material_cohesive_exponential.cc b/src/model/solid_mechanics/solid_mechanics_model_cohesive/materials/constitutive_laws/material_cohesive_exponential.cc
index 35ecec09e..139d64a96 100644
--- a/src/model/solid_mechanics/solid_mechanics_model_cohesive/materials/constitutive_laws/material_cohesive_exponential.cc
+++ b/src/model/solid_mechanics/solid_mechanics_model_cohesive/materials/constitutive_laws/material_cohesive_exponential.cc
@@ -1,349 +1,349 @@
 /**
  * @file   material_cohesive_exponential.cc
  *
+ * @author Mauro Corrado <mauro.corrado@epfl.ch>
  * @author Seyedeh Mohadeseh Taheri Mousavi <mohadeseh.taherimousavi@epfl.ch>
  * @author Marco Vocialta <marco.vocialta@epfl.ch>
  *
  * @date creation: Mon Jul 09 2012
- * @date last modification: Tue Aug 04 2015
+ * @date last modification: Tue Feb 20 2018
  *
  * @brief  Exponential irreversible cohesive law of mixed mode loading
  *
  * @section LICENSE
  *
- * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
- * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
- * Solides)
+ * 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
+ * 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
+ * A PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 #include "material_cohesive_exponential.hh"
 #include "dof_synchronizer.hh"
 #include "solid_mechanics_model.hh"
 #include "sparse_matrix.hh"
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 template <UInt spatial_dimension>
 MaterialCohesiveExponential<spatial_dimension>::MaterialCohesiveExponential(
     SolidMechanicsModel & model, const ID & id)
     : MaterialCohesive(model, id) {
   AKANTU_DEBUG_IN();
 
   this->registerParam("beta", beta, Real(0.), _pat_parsable, "Beta parameter");
 
   this->registerParam("exponential_penalty", exp_penalty, true, _pat_parsable,
                       "Is contact penalty following the exponential law?");
 
   this->registerParam(
       "contact_tangent", contact_tangent, Real(1.0), _pat_parsable,
       "Ratio of contact tangent over the initial exponential tangent");
 
   // this->initInternalArray(delta_max, 1, _ek_cohesive);
 
   use_previous_delta_max = true;
 
   AKANTU_DEBUG_OUT();
 }
 /* -------------------------------------------------------------------------- */
 template <UInt spatial_dimension>
 void MaterialCohesiveExponential<spatial_dimension>::initMaterial() {
 
   AKANTU_DEBUG_IN();
   MaterialCohesive::initMaterial();
 
   if ((exp_penalty) && (contact_tangent != 1)) {
 
     contact_tangent = 1;
     AKANTU_DEBUG_WARNING("The parsed paramter <contact_tangent> is forced to "
                          "1.0 when the contact penalty follows the exponential "
                          "law");
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <UInt spatial_dimension>
 void MaterialCohesiveExponential<spatial_dimension>::computeTraction(
     const Array<Real> & normal, ElementType el_type, GhostType ghost_type) {
   AKANTU_DEBUG_IN();
 
   /// define iterators
   auto traction_it = tractions(el_type, ghost_type).begin(spatial_dimension);
 
   auto opening_it = opening(el_type, ghost_type).begin(spatial_dimension);
 
   auto normal_it = normal.begin(spatial_dimension);
 
   auto traction_end = tractions(el_type, ghost_type).end(spatial_dimension);
 
   auto delta_max_it = delta_max(el_type, ghost_type).begin();
 
   auto delta_max_prev_it = delta_max.previous(el_type, ghost_type).begin();
 
   /// compute scalars
   Real beta2 = beta * beta;
 
   /// loop on each quadrature point
   for (; traction_it != traction_end; ++traction_it, ++opening_it, ++normal_it,
                                       ++delta_max_it, ++delta_max_prev_it) {
 
     /// compute normal and tangential opening vectors
     Real normal_opening_norm = opening_it->dot(*normal_it);
     Vector<Real> normal_opening(spatial_dimension);
     normal_opening = (*normal_it);
     normal_opening *= normal_opening_norm;
 
     Vector<Real> tangential_opening(spatial_dimension);
     tangential_opening = *opening_it;
     tangential_opening -= normal_opening;
 
     Real tangential_opening_norm = tangential_opening.norm();
 
     /**
      * compute effective opening displacement
      * @f$ \delta = \sqrt{
      * \beta^2 \Delta_t^2 + \Delta_n^2 } @f$
      */
     Real delta = tangential_opening_norm;
     delta *= delta * beta2;
     delta += normal_opening_norm * normal_opening_norm;
 
     delta = sqrt(delta);
 
     if ((normal_opening_norm < 0) &&
         (std::abs(normal_opening_norm) > Math::getTolerance())) {
 
       Vector<Real> op_n(*normal_it);
       op_n *= normal_opening_norm;
       Vector<Real> delta_s(*opening_it);
       delta_s -= op_n;
       delta = tangential_opening_norm * beta;
 
       computeCoupledTraction(*traction_it, *normal_it, delta, delta_s,
                              *delta_max_it, *delta_max_prev_it);
 
       computeCompressiveTraction(*traction_it, *normal_it, normal_opening_norm,
                                  *opening_it);
 
     } else
       computeCoupledTraction(*traction_it, *normal_it, delta, *opening_it,
                              *delta_max_it, *delta_max_prev_it);
   }
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <UInt spatial_dimension>
 void MaterialCohesiveExponential<spatial_dimension>::computeCoupledTraction(
     Vector<Real> & tract, const Vector<Real> & normal, Real delta,
     const Vector<Real> & opening, Real & delta_max_new, Real delta_max) {
   AKANTU_DEBUG_IN();
 
   /// full damage case
   if (std::abs(delta) < Math::getTolerance()) {
     /// set traction to zero
     tract.clear();
   } else { /// element not fully damaged
     /**
      * Compute traction loading @f$ \mathbf{T} =
      * e \sigma_c \frac{\delta}{\delta_c} e^{-\delta/ \delta_c}@f$
      */
     /**
      * Compute traction unloading @f$ \mathbf{T} =
      *  \frac{t_{max}}{\delta_{max}} \delta @f$
      */
     Real beta2 = beta * beta;
     Real normal_open_norm = opening.dot(normal);
     Vector<Real> op_n_n(spatial_dimension);
     op_n_n = normal;
     op_n_n *= (1 - beta2);
     op_n_n *= normal_open_norm;
     tract = beta2 * opening;
     tract += op_n_n;
 
     delta_max_new = std::max(delta_max, delta);
     tract *= exp(1) * sigma_c * exp(-delta_max_new / delta_c) / delta_c;
   }
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <UInt spatial_dimension>
 void MaterialCohesiveExponential<spatial_dimension>::computeCompressiveTraction(
     Vector<Real> & tract, const Vector<Real> & normal, Real delta_n,
     __attribute__((unused)) const Vector<Real> & opening) {
   Vector<Real> temp_tract(normal);
 
   if (exp_penalty) {
     temp_tract *=
         delta_n * exp(1) * sigma_c * exp(-delta_n / delta_c) / delta_c;
   } else {
     Real initial_tg = contact_tangent * exp(1) * sigma_c * delta_n / delta_c;
     temp_tract *= initial_tg;
   }
 
   tract += temp_tract;
 }
 
 /* -------------------------------------------------------------------------- */
 template <UInt spatial_dimension>
 void MaterialCohesiveExponential<spatial_dimension>::computeTangentTraction(
     const ElementType & el_type, Array<Real> & tangent_matrix,
     const Array<Real> & normal, GhostType ghost_type) {
   AKANTU_DEBUG_IN();
 
   Array<Real>::matrix_iterator tangent_it =
       tangent_matrix.begin(spatial_dimension, spatial_dimension);
 
   Array<Real>::matrix_iterator tangent_end =
       tangent_matrix.end(spatial_dimension, spatial_dimension);
 
   auto normal_it = normal.begin(spatial_dimension);
 
   auto opening_it = opening(el_type, ghost_type).begin(spatial_dimension);
 
   auto delta_max_it = delta_max.previous(el_type, ghost_type).begin();
 
   Real beta2 = beta * beta;
 
   /**
    * compute tangent matrix  @f$ \frac{\partial \mathbf{t}}
    * {\partial \delta} = \hat{\mathbf{t}} \otimes
    * \frac{\partial (t/\delta)}{\partial \delta}
    * \frac{\hat{\mathbf{t}}}{\delta}+ \frac{t}{\delta}  [ \beta^2 \mathbf{I} +
    * (1-\beta^2) (\mathbf{n} \otimes \mathbf{n})] @f$
    **/
 
   /**
    * In which @f$
    *  \frac{\partial(t/ \delta)}{\partial \delta} =
    * \left\{\begin{array} {l l}
    *  -e  \frac{\sigma_c}{\delta_c^2  }e^{-\delta  /  \delta_c} &  \quad  if
    *  \delta \geq \delta_{max} \\
    *  0 & \quad if \delta < \delta_{max}, \delta_n > 0
    *  \end{array}\right. @f$
    **/
 
   for (; tangent_it != tangent_end;
        ++tangent_it, ++normal_it, ++opening_it, ++delta_max_it) {
 
     Real normal_opening_norm = opening_it->dot(*normal_it);
     Vector<Real> normal_opening(spatial_dimension);
     normal_opening = (*normal_it);
     normal_opening *= normal_opening_norm;
 
     Vector<Real> tangential_opening(spatial_dimension);
     tangential_opening = *opening_it;
     tangential_opening -= normal_opening;
 
     Real tangential_opening_norm = tangential_opening.norm();
 
     Real delta = tangential_opening_norm;
     delta *= delta * beta2;
     delta += normal_opening_norm * normal_opening_norm;
     delta = sqrt(delta);
 
     if ((normal_opening_norm < 0) &&
         (std::abs(normal_opening_norm) > Math::getTolerance())) {
 
       Vector<Real> op_n(*normal_it);
       op_n *= normal_opening_norm;
       Vector<Real> delta_s(*opening_it);
       delta_s -= op_n;
       delta = tangential_opening_norm * beta;
 
       computeCoupledTangent(*tangent_it, *normal_it, delta, delta_s,
                             *delta_max_it);
 
       computeCompressivePenalty(*tangent_it, *normal_it, normal_opening_norm);
 
     } else
       computeCoupledTangent(*tangent_it, *normal_it, delta, *opening_it,
                             *delta_max_it);
   }
 
   AKANTU_DEBUG_OUT();
 }
 /* -------------------------------------------------------------------------- */
 template <UInt spatial_dimension>
 void MaterialCohesiveExponential<spatial_dimension>::computeCoupledTangent(
     Matrix<Real> & tangent, const Vector<Real> & normal, Real delta,
     const Vector<Real> & opening, Real) {
   AKANTU_DEBUG_IN();
 
   Real beta2 = beta * beta;
   Matrix<Real> J(spatial_dimension, spatial_dimension);
   J.eye(beta2);
 
   if (std::abs(delta) < Math::getTolerance()) {
     delta = Math::getTolerance();
   }
 
   Real opening_normal;
   opening_normal = opening.dot(normal);
 
   Vector<Real> delta_e(normal);
   delta_e *= opening_normal;
   delta_e *= (1 - beta2);
   delta_e += (beta2 * opening);
 
   Real exponent = exp(1 - delta / delta_c) * sigma_c / delta_c;
 
   Matrix<Real> first_term(spatial_dimension, spatial_dimension);
   first_term.outerProduct(normal, normal);
   first_term *= (1 - beta2);
   first_term += J;
 
   Matrix<Real> second_term(spatial_dimension, spatial_dimension);
   second_term.outerProduct(delta_e, delta_e);
   second_term /= delta;
   second_term /= delta_c;
 
   Matrix<Real> diff(first_term);
   diff -= second_term;
 
   tangent = diff;
   tangent *= exponent;
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <UInt spatial_dimension>
 void MaterialCohesiveExponential<spatial_dimension>::computeCompressivePenalty(
     Matrix<Real> & tangent, const Vector<Real> & normal, Real delta_n) {
 
   if (!exp_penalty)
     delta_n = 0;
 
   Matrix<Real> n_outer_n(spatial_dimension, spatial_dimension);
   n_outer_n.outerProduct(normal, normal);
 
   Real normal_tg = contact_tangent * exp(1) * sigma_c *
                    exp(-delta_n / delta_c) * (1 - delta_n / delta_c) / delta_c;
 
   n_outer_n *= normal_tg;
 
   tangent += n_outer_n;
 }
 
 INSTANTIATE_MATERIAL(cohesive_exponential, MaterialCohesiveExponential);
 
 } // akantu
diff --git a/src/model/solid_mechanics/solid_mechanics_model_cohesive/materials/constitutive_laws/material_cohesive_exponential.hh b/src/model/solid_mechanics/solid_mechanics_model_cohesive/materials/constitutive_laws/material_cohesive_exponential.hh
index 3b2b569c0..17e667827 100644
--- a/src/model/solid_mechanics/solid_mechanics_model_cohesive/materials/constitutive_laws/material_cohesive_exponential.hh
+++ b/src/model/solid_mechanics/solid_mechanics_model_cohesive/materials/constitutive_laws/material_cohesive_exponential.hh
@@ -1,123 +1,122 @@
 /**
  * @file   material_cohesive_exponential.hh
  *
  * @author Fabian Barras <fabian.barras@epfl.ch>
  * @author Seyedeh Mohadeseh Taheri Mousavi <mohadeseh.taherimousavi@epfl.ch>
  * @author Marco Vocialta <marco.vocialta@epfl.ch>
  *
  * @date creation: Fri Jun 18 2010
- * @date last modification: Fri Feb 06 2015
+ * @date last modification: Sun Dec 03 2017
  *
  * @brief  Exponential irreversible cohesive law of mixed mode loading
  *
  * @section LICENSE
  *
- * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
- * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
- * Solides)
+ * 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
+ * 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
+ * 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 "material_cohesive.hh"
 
 /* -------------------------------------------------------------------------- */
 
 #ifndef __AKANTU_MATERIAL_COHESIVE_EXPONENTIAL_HH__
 #define __AKANTU_MATERIAL_COHESIVE_EXPONENTIAL_HH__
 
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 
 /**
  * Cohesive material Exponential damage
  *
  * parameters in the material files :
  *   - sigma_c   : critical stress sigma_c  (default: 0)
  *   - beta      : weighting parameter for sliding and normal opening (default:
  * 0)
  *   - delta_c   : critical opening (default: 0)
  */
 template <UInt spatial_dimension>
 class MaterialCohesiveExponential : public MaterialCohesive {
   /* ------------------------------------------------------------------------ */
   /* Constructors/Destructors                                                 */
   /* ------------------------------------------------------------------------ */
 public:
   MaterialCohesiveExponential(SolidMechanicsModel & model, const ID & id = "");
 
   /* ------------------------------------------------------------------------ */
   /* Methods                                                                  */
   /* ------------------------------------------------------------------------ */
 protected:
   /// Initialization
   void initMaterial() override;
 
   /// constitutive law
   void computeTraction(const Array<Real> & normal, ElementType el_type,
                        GhostType ghost_type = _not_ghost) override;
 
   /// compute the tangent stiffness matrix for an element type
   void computeTangentTraction(const ElementType & el_type,
                               Array<Real> & tangent_matrix,
                               const Array<Real> & normal,
                               GhostType ghost_type = _not_ghost) override;
 
 private:
   void computeCoupledTraction(Vector<Real> & tract, const Vector<Real> & normal,
                               Real delta, const Vector<Real> & opening,
                               Real & delta_max_new, Real delta_max);
 
   void computeCompressiveTraction(Vector<Real> & tract,
                                   const Vector<Real> & normal, Real delta_n,
                                   const Vector<Real> & opening);
 
   void computeCoupledTangent(Matrix<Real> & tangent,
                              const Vector<Real> & normal, Real delta,
                              const Vector<Real> & opening, Real delta_max_new);
 
   void computeCompressivePenalty(Matrix<Real> & tangent,
                                  const Vector<Real> & normal, Real delta_n);
 
   /* ------------------------------------------------------------------------ */
   /* Accessors                                                                */
   /* ------------------------------------------------------------------------ */
 public:
   /* ------------------------------------------------------------------------ */
   /* Class Members                                                            */
   /* ------------------------------------------------------------------------ */
 protected:
   /// beta parameter
   Real beta;
 
   /// contact penalty = initial slope ?
   bool exp_penalty;
 
   /// Ratio of contact tangent over the initial exponential tangent
   Real contact_tangent;
 };
 
 /* -------------------------------------------------------------------------- */
 /* inline functions                                                           */
 /* -------------------------------------------------------------------------- */
 
 // #include "material_cohesive_exponential_inline_impl.cc"
 
 } // akantu
 
 #endif /* __AKANTU_MATERIAL_COHESIVE_EXPONENTIAL_HH__ */
diff --git a/src/model/solid_mechanics/solid_mechanics_model_cohesive/materials/constitutive_laws/material_cohesive_linear.cc b/src/model/solid_mechanics/solid_mechanics_model_cohesive/materials/constitutive_laws/material_cohesive_linear.cc
index 806cb7ef9..e63e3154a 100644
--- a/src/model/solid_mechanics/solid_mechanics_model_cohesive/materials/constitutive_laws/material_cohesive_linear.cc
+++ b/src/model/solid_mechanics/solid_mechanics_model_cohesive/materials/constitutive_laws/material_cohesive_linear.cc
@@ -1,419 +1,419 @@
 /**
  * @file   material_cohesive_linear.cc
  *
  * @author Mauro Corrado <mauro.corrado@epfl.ch>
+ * @author Nicolas Richart <nicolas.richart@epfl.ch>
  * @author Marco Vocialta <marco.vocialta@epfl.ch>
  *
  * @date creation: Wed Feb 22 2012
- * @date last modification: Thu Jan 14 2016
+ * @date last modification: Wed Feb 21 2018
  *
  * @brief  Linear irreversible cohesive law of mixed mode loading with
  * random stress definition for extrinsic type
  *
  * @section LICENSE
  *
- * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
- * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
- * Solides)
+ * 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
+ * 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
+ * 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 <algorithm>
 #include <numeric>
 
 /* -------------------------------------------------------------------------- */
 #include "dof_synchronizer.hh"
 #include "material_cohesive_linear.hh"
 #include "solid_mechanics_model_cohesive.hh"
 #include "sparse_matrix.hh"
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 template <UInt spatial_dimension>
 MaterialCohesiveLinear<spatial_dimension>::MaterialCohesiveLinear(
     SolidMechanicsModel & model, const ID & id)
     : MaterialCohesive(model, id), sigma_c_eff("sigma_c_eff", *this),
       delta_c_eff("delta_c_eff", *this),
       insertion_stress("insertion_stress", *this) {
   AKANTU_DEBUG_IN();
 
   this->registerParam("beta", beta, Real(0.), _pat_parsable | _pat_readable,
                       "Beta parameter");
 
   this->registerParam("G_c", G_c, Real(0.), _pat_parsable | _pat_readable,
                       "Mode I fracture energy");
 
   this->registerParam("penalty", penalty, Real(0.),
                       _pat_parsable | _pat_readable, "Penalty coefficient");
 
   this->registerParam("volume_s", volume_s, Real(0.),
                       _pat_parsable | _pat_readable,
                       "Reference volume for sigma_c scaling");
 
   this->registerParam("m_s", m_s, Real(1.), _pat_parsable | _pat_readable,
                       "Weibull exponent for sigma_c scaling");
 
   this->registerParam("kappa", kappa, Real(1.), _pat_parsable | _pat_readable,
                       "Kappa parameter");
 
   this->registerParam(
       "contact_after_breaking", contact_after_breaking, false,
       _pat_parsable | _pat_readable,
       "Activation of contact when the elements are fully damaged");
 
   this->registerParam("max_quad_stress_insertion", max_quad_stress_insertion,
                       false, _pat_parsable | _pat_readable,
                       "Insertion of cohesive element when stress is high "
                       "enough just on one quadrature point");
 
   this->registerParam("recompute", recompute, false,
                       _pat_parsable | _pat_modifiable, "recompute solution");
 
   this->use_previous_delta_max = true;
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <UInt spatial_dimension>
 void MaterialCohesiveLinear<spatial_dimension>::initMaterial() {
   AKANTU_DEBUG_IN();
 
   MaterialCohesive::initMaterial();
 
   sigma_c_eff.initialize(1);
   delta_c_eff.initialize(1);
   insertion_stress.initialize(spatial_dimension);
 
   if (not Math::are_float_equal(delta_c, 0.))
     delta_c_eff.setDefaultValue(delta_c);
   else
     delta_c_eff.setDefaultValue(2 * G_c / sigma_c);
 
   if (model->getIsExtrinsic())
     scaleInsertionTraction();
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <UInt spatial_dimension>
 void MaterialCohesiveLinear<spatial_dimension>::updateInternalParameters() {
   /// compute scalars
   beta2_kappa2 = beta * beta / kappa / kappa;
   beta2_kappa = beta * beta / kappa;
 
   if (Math::are_float_equal(beta, 0))
     beta2_inv = 0;
   else
     beta2_inv = 1. / beta / beta;
 }
 
 /* -------------------------------------------------------------------------- */
 template <UInt spatial_dimension>
 void MaterialCohesiveLinear<spatial_dimension>::scaleInsertionTraction() {
   AKANTU_DEBUG_IN();
 
   // do nothing if volume_s hasn't been specified by the user
   if (Math::are_float_equal(volume_s, 0.))
     return;
 
   const Mesh & mesh_facets = model->getMeshFacets();
   const auto & fe_engine = model->getFEEngine();
   const auto & fe_engine_facet = model->getFEEngine("FacetsFEEngine");
 
   Real base_sigma_c = sigma_c;
 
   for (auto && type_facet : mesh_facets.elementTypes(spatial_dimension - 1)) {
     const Array<std::vector<Element>> & facet_to_element =
         mesh_facets.getElementToSubelement(type_facet);
 
     UInt nb_facet = facet_to_element.size();
     UInt nb_quad_per_facet = fe_engine_facet.getNbIntegrationPoints(type_facet);
 
     // iterator to modify sigma_c for all the quadrature points of a facet
     auto sigma_c_iterator =
         sigma_c(type_facet).begin_reinterpret(nb_quad_per_facet, nb_facet);
 
     for (UInt f = 0; f < nb_facet; ++f, ++sigma_c_iterator) {
 
       const std::vector<Element> & element_list = facet_to_element(f);
 
       // compute bounding volume
       Real volume = 0;
 
       auto elem = element_list.begin();
       auto elem_end = element_list.end();
 
       for (; elem != elem_end; ++elem) {
         if (*elem == ElementNull)
           continue;
 
         // unit vector for integration in order to obtain the volume
         UInt nb_quadrature_points =
             fe_engine.getNbIntegrationPoints(elem->type);
         Vector<Real> unit_vector(nb_quadrature_points, 1);
 
         volume += fe_engine.integrate(unit_vector, elem->type, elem->element,
                                       elem->ghost_type);
       }
 
       // scale sigma_c
       *sigma_c_iterator -= base_sigma_c;
       *sigma_c_iterator *= std::pow(volume_s / volume, 1. / m_s);
       *sigma_c_iterator += base_sigma_c;
     }
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <UInt spatial_dimension>
 void MaterialCohesiveLinear<spatial_dimension>::checkInsertion(
     bool check_only) {
   AKANTU_DEBUG_IN();
 
   const Mesh & mesh_facets = model->getMeshFacets();
   CohesiveElementInserter & inserter = model->getElementInserter();
 
   for (auto && type_facet : mesh_facets.elementTypes(spatial_dimension - 1)) {
     ElementType type_cohesive = FEEngine::getCohesiveElementType(type_facet);
     const auto & facets_check = inserter.getCheckFacets(type_facet);
     auto & f_insertion = inserter.getInsertionFacets(type_facet);
     auto & f_filter = facet_filter(type_facet);
     auto & sig_c_eff = sigma_c_eff(type_cohesive);
     auto & del_c = delta_c_eff(type_cohesive);
     auto & ins_stress = insertion_stress(type_cohesive);
     auto & trac_old = tractions.previous(type_cohesive);
     const auto & f_stress = model->getStressOnFacets(type_facet);
     const auto & sigma_lim = sigma_c(type_facet);
 
     UInt nb_quad_facet =
         model->getFEEngine("FacetsFEEngine").getNbIntegrationPoints(type_facet);
     UInt nb_quad_cohesive = model->getFEEngine("CohesiveFEEngine")
                                 .getNbIntegrationPoints(type_cohesive);
 
     AKANTU_DEBUG_ASSERT(nb_quad_cohesive == nb_quad_facet,
                         "The cohesive element and the corresponding facet do "
                         "not have the same numbers of integration points");
 
     UInt nb_facet = f_filter.size();
     //  if (nb_facet == 0) continue;
 
     auto sigma_lim_it = sigma_lim.begin();
 
     Matrix<Real> stress_tmp(spatial_dimension, spatial_dimension);
     Matrix<Real> normal_traction(spatial_dimension, nb_quad_facet);
     Vector<Real> stress_check(nb_quad_facet);
     UInt sp2 = spatial_dimension * spatial_dimension;
 
     const auto & tangents = model->getTangents(type_facet);
     const auto & normals = model->getFEEngine("FacetsFEEngine")
                                .getNormalsOnIntegrationPoints(type_facet);
     auto normal_begin = normals.begin(spatial_dimension);
     auto tangent_begin = tangents.begin(tangents.getNbComponent());
     auto facet_stress_begin =
         f_stress.begin(spatial_dimension, spatial_dimension * 2);
 
     std::vector<Real> new_sigmas;
     std::vector<Vector<Real>> new_normal_traction;
     std::vector<Real> new_delta_c;
 
     // loop over each facet belonging to this material
     for (UInt f = 0; f < nb_facet; ++f, ++sigma_lim_it) {
       UInt facet = f_filter(f);
       // skip facets where check shouldn't be realized
       if (!facets_check(facet))
         continue;
 
       // compute the effective norm on each quadrature point of the facet
       for (UInt q = 0; q < nb_quad_facet; ++q) {
         UInt current_quad = facet * nb_quad_facet + q;
         const Vector<Real> & normal = normal_begin[current_quad];
         const Vector<Real> & tangent = tangent_begin[current_quad];
         const Matrix<Real> & facet_stress_it = facet_stress_begin[current_quad];
 
         // compute average stress on the current quadrature point
         Matrix<Real> stress_1(facet_stress_it.storage(), spatial_dimension,
                               spatial_dimension);
 
         Matrix<Real> stress_2(facet_stress_it.storage() + sp2,
                               spatial_dimension, spatial_dimension);
 
         stress_tmp.copy(stress_1);
         stress_tmp += stress_2;
         stress_tmp /= 2.;
 
         Vector<Real> normal_traction_vec(normal_traction(q));
 
         // compute normal and effective stress
         stress_check(q) = computeEffectiveNorm(stress_tmp, normal, tangent,
                                                normal_traction_vec);
       }
 
       // verify if the effective stress overcomes the threshold
       Real final_stress = stress_check.mean();
       if (max_quad_stress_insertion)
         final_stress = *std::max_element(
             stress_check.storage(), stress_check.storage() + nb_quad_facet);
 
       if (final_stress > *sigma_lim_it) {
         f_insertion(facet) = true;
 
         if (check_only)
           continue;
 
         // store the new cohesive material parameters for each quadrature
         // point
         for (UInt q = 0; q < nb_quad_facet; ++q) {
           Real new_sigma = stress_check(q);
           Vector<Real> normal_traction_vec(normal_traction(q));
 
           if (spatial_dimension != 3)
             normal_traction_vec *= -1.;
 
           new_sigmas.push_back(new_sigma);
           new_normal_traction.push_back(normal_traction_vec);
 
           Real new_delta;
 
           // set delta_c in function of G_c or a given delta_c value
           if (Math::are_float_equal(delta_c, 0.))
             new_delta = 2 * G_c / new_sigma;
           else
             new_delta = (*sigma_lim_it) / new_sigma * delta_c;
 
           new_delta_c.push_back(new_delta);
         }
       }
     }
 
     // update material data for the new elements
     UInt old_nb_quad_points = sig_c_eff.size();
     UInt new_nb_quad_points = new_sigmas.size();
     sig_c_eff.resize(old_nb_quad_points + new_nb_quad_points);
     ins_stress.resize(old_nb_quad_points + new_nb_quad_points);
     trac_old.resize(old_nb_quad_points + new_nb_quad_points);
     del_c.resize(old_nb_quad_points + new_nb_quad_points);
 
     for (UInt q = 0; q < new_nb_quad_points; ++q) {
       sig_c_eff(old_nb_quad_points + q) = new_sigmas[q];
       del_c(old_nb_quad_points + q) = new_delta_c[q];
       for (UInt dim = 0; dim < spatial_dimension; ++dim) {
         ins_stress(old_nb_quad_points + q, dim) = new_normal_traction[q](dim);
         trac_old(old_nb_quad_points + q, dim) = new_normal_traction[q](dim);
       }
     }
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <UInt spatial_dimension>
 void MaterialCohesiveLinear<spatial_dimension>::computeTraction(
     const Array<Real> & normal, ElementType el_type, GhostType ghost_type) {
   AKANTU_DEBUG_IN();
 
   /// define iterators
   auto traction_it = tractions(el_type, ghost_type).begin(spatial_dimension);
   auto opening_it = opening(el_type, ghost_type).begin(spatial_dimension);
   auto contact_traction_it =
       contact_tractions(el_type, ghost_type).begin(spatial_dimension);
   auto contact_opening_it =
       contact_opening(el_type, ghost_type).begin(spatial_dimension);
 
   auto normal_it = normal.begin(spatial_dimension);
   auto traction_end = tractions(el_type, ghost_type).end(spatial_dimension);
   auto sigma_c_it = sigma_c_eff(el_type, ghost_type).begin();
   auto delta_max_it = delta_max(el_type, ghost_type).begin();
   auto delta_c_it = delta_c_eff(el_type, ghost_type).begin();
   auto damage_it = damage(el_type, ghost_type).begin();
   auto insertion_stress_it =
       insertion_stress(el_type, ghost_type).begin(spatial_dimension);
 
   Vector<Real> normal_opening(spatial_dimension);
   Vector<Real> tangential_opening(spatial_dimension);
 
   /// loop on each quadrature point
   for (; traction_it != traction_end;
        ++traction_it, ++opening_it, ++normal_it, ++sigma_c_it, ++delta_max_it,
        ++delta_c_it, ++damage_it, ++contact_traction_it, ++insertion_stress_it,
        ++contact_opening_it) {
 
     Real normal_opening_norm, tangential_opening_norm;
     bool penetration;
     this->computeTractionOnQuad(
         *traction_it, *opening_it, *normal_it, *delta_max_it, *delta_c_it,
         *insertion_stress_it, *sigma_c_it, normal_opening, tangential_opening,
         normal_opening_norm, tangential_opening_norm, *damage_it, penetration,
         *contact_traction_it, *contact_opening_it);
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <UInt spatial_dimension>
 void MaterialCohesiveLinear<spatial_dimension>::computeTangentTraction(
     const ElementType & el_type, Array<Real> & tangent_matrix,
     const Array<Real> & normal, GhostType ghost_type) {
   AKANTU_DEBUG_IN();
 
   /// define iterators
   auto tangent_it = tangent_matrix.begin(spatial_dimension, spatial_dimension);
 
   auto tangent_end = tangent_matrix.end(spatial_dimension, spatial_dimension);
 
   auto normal_it = normal.begin(spatial_dimension);
 
   auto opening_it = opening(el_type, ghost_type).begin(spatial_dimension);
 
   /// NB: delta_max_it points on delta_max_previous, i.e. the
   /// delta_max related to the solution of the previous incremental
   /// step
   auto delta_max_it = delta_max.previous(el_type, ghost_type).begin();
   auto sigma_c_it = sigma_c_eff(el_type, ghost_type).begin();
   auto delta_c_it = delta_c_eff(el_type, ghost_type).begin();
   auto damage_it = damage(el_type, ghost_type).begin();
   auto contact_opening_it =
       contact_opening(el_type, ghost_type).begin(spatial_dimension);
 
   Vector<Real> normal_opening(spatial_dimension);
   Vector<Real> tangential_opening(spatial_dimension);
 
   for (; tangent_it != tangent_end; ++tangent_it, ++normal_it, ++opening_it,
                                     ++delta_max_it, ++sigma_c_it, ++delta_c_it,
                                     ++damage_it, ++contact_opening_it) {
 
     Real normal_opening_norm, tangential_opening_norm;
     bool penetration;
     this->computeTangentTractionOnQuad(
         *tangent_it, *delta_max_it, *delta_c_it, *sigma_c_it, *opening_it,
         *normal_it, normal_opening, tangential_opening, normal_opening_norm,
         tangential_opening_norm, *damage_it, penetration, *contact_opening_it);
   }
 
   AKANTU_DEBUG_OUT();
 }
 /* -------------------------------------------------------------------------- */
 
 INSTANTIATE_MATERIAL(cohesive_linear, MaterialCohesiveLinear);
 
 } // akantu
diff --git a/src/model/solid_mechanics/solid_mechanics_model_cohesive/materials/constitutive_laws/material_cohesive_linear.hh b/src/model/solid_mechanics/solid_mechanics_model_cohesive/materials/constitutive_laws/material_cohesive_linear.hh
index 56dd8570e..6102277b5 100644
--- a/src/model/solid_mechanics/solid_mechanics_model_cohesive/materials/constitutive_laws/material_cohesive_linear.hh
+++ b/src/model/solid_mechanics/solid_mechanics_model_cohesive/materials/constitutive_laws/material_cohesive_linear.hh
@@ -1,188 +1,188 @@
 /**
  * @file   material_cohesive_linear.hh
  *
  * @author Mauro Corrado <mauro.corrado@epfl.ch>
+ * @author Nicolas Richart <nicolas.richart@epfl.ch>
  * @author Marco Vocialta <marco.vocialta@epfl.ch>
  *
  * @date creation: Fri Jun 18 2010
- * @date last modification: Thu Jan 14 2016
+ * @date last modification: Wed Feb 21 2018
  *
  * @brief  Linear irreversible cohesive law of mixed mode loading with
  * random stress definition for extrinsic type
  *
  * @section LICENSE
  *
- * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
- * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
- * Solides)
+ * 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
+ * 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
+ * A PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 #include "material_cohesive.hh"
 /* -------------------------------------------------------------------------- */
 
 #ifndef __AKANTU_MATERIAL_COHESIVE_LINEAR_HH__
 #define __AKANTU_MATERIAL_COHESIVE_LINEAR_HH__
 
 namespace akantu {
 
 /**
  * Cohesive material linear damage for extrinsic case
  *
  * parameters in the material files :
  *   - sigma_c   : critical stress sigma_c  (default: 0)
  *   - beta      : weighting parameter for sliding and normal opening (default:
  * 0)
  *   - G_cI      : fracture energy for mode I (default: 0)
  *   - G_cII     : fracture energy for mode II (default: 0)
  *   - penalty   : stiffness in compression to prevent penetration
  */
 template <UInt spatial_dimension>
 class MaterialCohesiveLinear : public MaterialCohesive {
   /* ------------------------------------------------------------------------ */
   /* Constructors/Destructors                                                 */
   /* ------------------------------------------------------------------------ */
 public:
   MaterialCohesiveLinear(SolidMechanicsModel & model, const ID & id = "");
 
   /* ------------------------------------------------------------------------ */
   /* Methods                                                                  */
   /* ------------------------------------------------------------------------ */
 public:
   /// initialize the material parameters
   void initMaterial() override;
 
   void updateInternalParameters() override;
 
   /// check stress for cohesive elements' insertion
   void checkInsertion(bool check_only = false) override;
 
   /// compute effective stress norm for insertion check
   Real computeEffectiveNorm(const Matrix<Real> & stress,
                             const Vector<Real> & normal,
                             const Vector<Real> & tangent,
                             Vector<Real> & normal_stress) const;
 
 protected:
   /// constitutive law
   void computeTraction(const Array<Real> & normal, ElementType el_type,
                        GhostType ghost_type = _not_ghost) override;
 
   /// compute tangent stiffness matrix
   void computeTangentTraction(const ElementType & el_type,
                               Array<Real> & tangent_matrix,
                               const Array<Real> & normal,
                               GhostType ghost_type) override;
 
   /**
    * Scale insertion traction sigma_c according to the volume of the
    * two elements surrounding a facet
    *
    * see the article: F. Zhou and J. F. Molinari "Dynamic crack
    * propagation with cohesive elements: a methodology to address mesh
    * dependency" International Journal for Numerical Methods in
    * Engineering (2004)
    */
   void scaleInsertionTraction();
 
   /// compute the traction for a given quadrature point
   inline void computeTractionOnQuad(
       Vector<Real> & traction, Vector<Real> & opening,
       const Vector<Real> & normal, Real & delta_max, const Real & delta_c,
       const Vector<Real> & insertion_stress, const Real & sigma_c,
       Vector<Real> & normal_opening, Vector<Real> & tangential_opening,
       Real & normal_opening_norm, Real & tangential_opening_norm, Real & damage,
       bool & penetration, Vector<Real> & contact_traction,
       Vector<Real> & contact_opening);
 
   inline void computeTangentTractionOnQuad(
       Matrix<Real> & tangent, Real & delta_max, const Real & delta_c,
       const Real & sigma_c, Vector<Real> & opening, const Vector<Real> & normal,
       Vector<Real> & normal_opening, Vector<Real> & tangential_opening,
       Real & normal_opening_norm, Real & tangential_opening_norm, Real & damage,
       bool & penetration, Vector<Real> & contact_opening);
 
   /* ------------------------------------------------------------------------ */
   /* Accessors                                                                */
   /* ------------------------------------------------------------------------ */
 public:
   /// get sigma_c_eff
   AKANTU_GET_MACRO_BY_ELEMENT_TYPE_CONST(InsertionTraction, sigma_c_eff, Real);
 
   /* ------------------------------------------------------------------------ */
   /* Class Members                                                            */
   /* ------------------------------------------------------------------------ */
 protected:
   /// beta parameter
   Real beta;
 
   /// beta square inverse to compute effective norm
   Real beta2_inv;
 
   /// mode I fracture energy
   Real G_c;
 
   /// kappa parameter
   Real kappa;
 
   /// constitutive law scalar to compute delta
   Real beta2_kappa2;
 
   /// constitutive law scalar to compute traction
   Real beta2_kappa;
 
   /// penalty coefficient
   Real penalty;
 
   /// reference volume used to scale sigma_c
   Real volume_s;
 
   /// weibull exponent used to scale sigma_c
   Real m_s;
 
   /// variable defining if we are recomputing the last loading step
   /// after load_reduction
   bool recompute;
 
   /// critical effective stress
   RandomInternalField<Real, CohesiveInternalField> sigma_c_eff;
 
   /// effective critical displacement (each element can have a
   /// different value)
   CohesiveInternalField<Real> delta_c_eff;
 
   /// stress at insertion
   CohesiveInternalField<Real> insertion_stress;
 
   /// variable saying if there should be penalty contact also after
   /// breaking the cohesive elements
   bool contact_after_breaking;
 
   /// insertion of cohesive element when stress is high enough just on
   /// one quadrature point
   bool max_quad_stress_insertion;
 };
 
 /* -------------------------------------------------------------------------- */
 /* inline functions                                                           */
 /* -------------------------------------------------------------------------- */
 
 } // akantu
 
 #include "material_cohesive_linear_inline_impl.cc"
 
 #endif /* __AKANTU_MATERIAL_COHESIVE_LINEAR_HH__ */
diff --git a/src/model/solid_mechanics/solid_mechanics_model_cohesive/materials/constitutive_laws/material_cohesive_linear_fatigue.cc b/src/model/solid_mechanics/solid_mechanics_model_cohesive/materials/constitutive_laws/material_cohesive_linear_fatigue.cc
index 432b7e673..0f931e311 100644
--- a/src/model/solid_mechanics/solid_mechanics_model_cohesive/materials/constitutive_laws/material_cohesive_linear_fatigue.cc
+++ b/src/model/solid_mechanics/solid_mechanics_model_cohesive/materials/constitutive_laws/material_cohesive_linear_fatigue.cc
@@ -1,298 +1,298 @@
 /**
  * @file   material_cohesive_linear_fatigue.cc
  *
  * @author Marco Vocialta <marco.vocialta@epfl.ch>
  *
  * @date creation: Fri Feb 20 2015
- * @date last modification: Tue Jan 12 2016
+ * @date last modification: Tue Feb 20 2018
  *
  * @brief  See material_cohesive_linear_fatigue.hh for information
  *
  * @section LICENSE
  *
- * Copyright (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne) Laboratory
- * (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * Copyright (©) 2015-2018 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
- * terms  of the  GNU Lesser  General Public  License as  published by  the Free
+ * 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
+ * A PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 #include "material_cohesive_linear_fatigue.hh"
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 template <UInt spatial_dimension>
 MaterialCohesiveLinearFatigue<spatial_dimension>::MaterialCohesiveLinearFatigue(
     SolidMechanicsModel & model, const ID & id)
     : MaterialCohesiveLinear<spatial_dimension>(model, id),
       delta_prec("delta_prec", *this), K_plus("K_plus", *this),
       K_minus("K_minus", *this), T_1d("T_1d", *this),
       switches("switches", *this), delta_dot_prec("delta_dot_prec", *this),
       normal_regime("normal_regime", *this) {
 
   this->registerParam("delta_f", delta_f, Real(-1.),
                       _pat_parsable | _pat_readable, "delta_f");
 
   this->registerParam("progressive_delta_f", progressive_delta_f, false,
                       _pat_parsable | _pat_readable,
                       "Whether or not delta_f is equal to delta_max");
 
   this->registerParam("count_switches", count_switches, false,
                       _pat_parsable | _pat_readable,
                       "Count the opening/closing switches per element");
 
   this->registerParam(
       "fatigue_ratio", fatigue_ratio, Real(1.), _pat_parsable | _pat_readable,
       "What portion of the cohesive law is subjected to fatigue");
 }
 
 /* -------------------------------------------------------------------------- */
 template <UInt spatial_dimension>
 void MaterialCohesiveLinearFatigue<spatial_dimension>::initMaterial() {
   MaterialCohesiveLinear<spatial_dimension>::initMaterial();
 
   // check that delta_f has a proper value or assign a defaul value
   if (delta_f < 0)
     delta_f = this->delta_c_eff;
   else if (delta_f < this->delta_c_eff)
     AKANTU_ERROR("Delta_f must be greater or equal to delta_c");
 
   delta_prec.initialize(1);
   K_plus.initialize(1);
   K_minus.initialize(1);
   T_1d.initialize(1);
   normal_regime.initialize(1);
 
   if (count_switches) {
     switches.initialize(1);
     delta_dot_prec.initialize(1);
   }
 }
 
 /* -------------------------------------------------------------------------- */
 template <UInt spatial_dimension>
 void MaterialCohesiveLinearFatigue<spatial_dimension>::computeTraction(
     const Array<Real> & normal, ElementType el_type, GhostType ghost_type) {
   AKANTU_DEBUG_IN();
 
   /// define iterators
   auto traction_it =
       this->tractions(el_type, ghost_type).begin(spatial_dimension);
 
   auto opening_it = this->opening(el_type, ghost_type).begin(spatial_dimension);
 
   auto contact_traction_it =
       this->contact_tractions(el_type, ghost_type).begin(spatial_dimension);
 
   auto contact_opening_it =
       this->contact_opening(el_type, ghost_type).begin(spatial_dimension);
 
   auto normal_it = normal.begin(spatial_dimension);
 
   auto traction_end =
       this->tractions(el_type, ghost_type).end(spatial_dimension);
 
   const Array<Real> & sigma_c_array = this->sigma_c_eff(el_type, ghost_type);
   Array<Real> & delta_max_array = this->delta_max(el_type, ghost_type);
   const Array<Real> & delta_c_array = this->delta_c_eff(el_type, ghost_type);
   Array<Real> & damage_array = this->damage(el_type, ghost_type);
 
   auto insertion_stress_it =
       this->insertion_stress(el_type, ghost_type).begin(spatial_dimension);
 
   Array<Real> & delta_prec_array = delta_prec(el_type, ghost_type);
   Array<Real> & K_plus_array = K_plus(el_type, ghost_type);
   Array<Real> & K_minus_array = K_minus(el_type, ghost_type);
   Array<Real> & T_1d_array = T_1d(el_type, ghost_type);
   Array<bool> & normal_regime_array = normal_regime(el_type, ghost_type);
 
   Array<UInt> * switches_array = nullptr;
   Array<Real> * delta_dot_prec_array = nullptr;
 
   if (count_switches) {
     switches_array = &switches(el_type, ghost_type);
     delta_dot_prec_array = &delta_dot_prec(el_type, ghost_type);
   }
 
   auto * memory_space = new Real[2 * spatial_dimension];
   Vector<Real> normal_opening(memory_space, spatial_dimension);
   Vector<Real> tangential_opening(memory_space + spatial_dimension,
                                   spatial_dimension);
 
   Real tolerance = Math::getTolerance();
 
   /// loop on each quadrature point
   for (UInt q = 0; traction_it != traction_end; ++traction_it, ++opening_it,
             ++normal_it, ++contact_traction_it, ++insertion_stress_it,
             ++contact_opening_it, ++q) {
 
     /// compute normal and tangential opening vectors
     Real normal_opening_norm = opening_it->dot(*normal_it);
     normal_opening = (*normal_it);
     normal_opening *= normal_opening_norm;
 
     tangential_opening = *opening_it;
     tangential_opening -= normal_opening;
 
     Real tangential_opening_norm = tangential_opening.norm();
 
     /**
      * compute effective opening displacement
      * @f$ \delta = \sqrt{
      * \frac{\beta^2}{\kappa^2} \Delta_t^2 + \Delta_n^2 } @f$
      */
     Real delta =
         tangential_opening_norm * tangential_opening_norm * this->beta2_kappa2;
 
     bool penetration = normal_opening_norm < -tolerance;
     if (this->contact_after_breaking == false &&
         Math::are_float_equal(damage_array(q), 1.))
       penetration = false;
 
     if (penetration) {
       /// use penalty coefficient in case of penetration
       *contact_traction_it = normal_opening;
       *contact_traction_it *= this->penalty;
       *contact_opening_it = normal_opening;
       /// don't consider penetration contribution for delta
       *opening_it = tangential_opening;
       normal_opening.clear();
     } else {
       delta += normal_opening_norm * normal_opening_norm;
       contact_traction_it->clear();
       contact_opening_it->clear();
     }
 
     delta = std::sqrt(delta);
 
     /**
      * Compute traction @f$ \mathbf{T} = \left(
      * \frac{\beta^2}{\kappa} \Delta_t \mathbf{t} + \Delta_n
      * \mathbf{n} \right) \frac{\sigma_c}{\delta} \left( 1-
      * \frac{\delta}{\delta_c} \right)@f$
      */
 
     // update maximum displacement and damage
     delta_max_array(q) = std::max(delta, delta_max_array(q));
     damage_array(q) = std::min(delta_max_array(q) / delta_c_array(q), Real(1.));
 
     Real delta_dot = delta - delta_prec_array(q);
 
     // count switches if asked
     if (count_switches) {
       if ((delta_dot > 0. && (*delta_dot_prec_array)(q) <= 0.) ||
           (delta_dot < 0. && (*delta_dot_prec_array)(q) >= 0.))
         ++((*switches_array)(q));
 
       (*delta_dot_prec_array)(q) = delta_dot;
     }
 
     // set delta_f equal to delta_max if desired
     if (progressive_delta_f)
       delta_f = delta_max_array(q);
 
     // broken element case
     if (Math::are_float_equal(damage_array(q), 1.))
       traction_it->clear();
     // just inserted element case
     else if (Math::are_float_equal(damage_array(q), 0.)) {
       if (penetration)
         traction_it->clear();
       else
         *traction_it = *insertion_stress_it;
       // initialize the 1d traction to sigma_c
       T_1d_array(q) = sigma_c_array(q);
     }
     // normal case
     else {
       // if element is closed then there are zero tractions
       if (delta <= tolerance)
         traction_it->clear();
       // otherwise compute new tractions if the new delta is different
       // than the previous one
       else if (std::abs(delta_dot) > tolerance) {
         // loading case
         if (delta_dot > 0.) {
           if (!normal_regime_array(q)) {
             // equation (4) of the article
             K_plus_array(q) *= 1. - delta_dot / delta_f;
             // equivalent to equation (2) of the article
             T_1d_array(q) += K_plus_array(q) * delta_dot;
 
             // in case of reloading, traction must not exceed that of the
             // envelop of the cohesive law
             Real max_traction =
                 sigma_c_array(q) * (1 - delta / delta_c_array(q));
             bool max_traction_exceeded = T_1d_array(q) > max_traction;
             if (max_traction_exceeded)
               T_1d_array(q) = max_traction;
 
             // switch to standard linear cohesive law
             if (delta_max_array(q) > fatigue_ratio * delta_c_array(q)) {
               // reset delta_max to avoid big jumps in the traction
               delta_max_array(q) =
                   sigma_c_array(q) /
                   (T_1d_array(q) / delta + sigma_c_array(q) / delta_c_array(q));
               damage_array(q) =
                   std::min(delta_max_array(q) / delta_c_array(q), Real(1.));
               K_minus_array(q) = sigma_c_array(q) / delta_max_array(q) *
                                  (1. - damage_array(q));
               normal_regime_array(q) = true;
             } else {
               // equation (3) of the article
               K_minus_array(q) = T_1d_array(q) / delta;
 
               // if the traction is following the cohesive envelop, then
               // K_plus has to be reset
               if (max_traction_exceeded)
                 K_plus_array(q) = K_minus_array(q);
             }
           } else {
             // compute stiffness according to the standard law
             K_minus_array(q) =
                 sigma_c_array(q) / delta_max_array(q) * (1. - damage_array(q));
           }
         }
         // unloading case
         else if (!normal_regime_array(q)) {
           // equation (4) of the article
           K_plus_array(q) +=
               (K_plus_array(q) - K_minus_array(q)) * delta_dot / delta_f;
           // equivalent to equation (2) of the article
           T_1d_array(q) = K_minus_array(q) * delta;
         }
 
         // applying the actual stiffness
         *traction_it = tangential_opening;
         *traction_it *= this->beta2_kappa;
         *traction_it += normal_opening;
         *traction_it *= K_minus_array(q);
       }
     }
 
     // update precendent delta
     delta_prec_array(q) = delta;
   }
 
   delete[] memory_space;
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 
 INSTANTIATE_MATERIAL(cohesive_linear_fatigue, MaterialCohesiveLinearFatigue);
 
 } // akantu
diff --git a/src/model/solid_mechanics/solid_mechanics_model_cohesive/materials/constitutive_laws/material_cohesive_linear_fatigue.hh b/src/model/solid_mechanics/solid_mechanics_model_cohesive/materials/constitutive_laws/material_cohesive_linear_fatigue.hh
index 93d3329d2..7c204eadc 100644
--- a/src/model/solid_mechanics/solid_mechanics_model_cohesive/materials/constitutive_laws/material_cohesive_linear_fatigue.hh
+++ b/src/model/solid_mechanics/solid_mechanics_model_cohesive/materials/constitutive_laws/material_cohesive_linear_fatigue.hh
@@ -1,133 +1,132 @@
 /**
  * @file   material_cohesive_linear_fatigue.hh
  *
  * @author Marco Vocialta <marco.vocialta@epfl.ch>
  *
  * @date creation: Fri Jun 18 2010
- * @date last modification: Thu Jun 25 2015
+ * @date last modification: Sun Dec 03 2017
  *
  * @brief  Linear irreversible cohesive law with dissipative
  * unloading-reloading cycles
  *
  * @section LICENSE
  *
- * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
- * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
- * Solides)
+ * 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
+ * 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
+ * A PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 
 #include "material_cohesive_linear.hh"
 
 /* -------------------------------------------------------------------------- */
 #ifndef __AKANTU_MATERIAL_COHESIVE_LINEAR_FATIGUE_HH__
 #define __AKANTU_MATERIAL_COHESIVE_LINEAR_FATIGUE_HH__
 
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 
 /**
  * Linear irreversible cohesive law with dissipative
  * unloading-reloading cycles
  *
  * This law uses two different stiffnesses during unloading and
  * reloading. The implementation is based on the article entitled "A
  * cohesive model for fatigue crack growth" by Nguyen, Repetto, Ortiz
  * and Radovitzky (2001). This law is identical to the
  * MaterialCohesiveLinear one except for the unloading-reloading
  * phase.
  *
  * input parameter:
  *
  * - delta_f : it must be greater than delta_c and it is inversely
  *      proportional to the dissipation in the unloading-reloading
  *      cycles (default: delta_c)
  */
 
 template <UInt spatial_dimension>
 class MaterialCohesiveLinearFatigue
     : public MaterialCohesiveLinear<spatial_dimension> {
   /* ------------------------------------------------------------------------ */
   /* Constructors/Destructors                                                 */
   /* ------------------------------------------------------------------------ */
 public:
   MaterialCohesiveLinearFatigue(SolidMechanicsModel & model,
                                 const ID & id = "");
 
   /* ------------------------------------------------------------------------ */
   /* Methods                                                                  */
   /* ------------------------------------------------------------------------ */
 public:
   /// initialize the material parameters
   void initMaterial() override;
 
 protected:
   /// constitutive law
   void computeTraction(const Array<Real> & normal, ElementType el_type,
                        GhostType ghost_type = _not_ghost) override;
 
   /* ------------------------------------------------------------------------ */
   /* Accessors                                                                */
   /* ------------------------------------------------------------------------ */
 public:
   /// get the switches
   AKANTU_GET_MACRO_BY_ELEMENT_TYPE_CONST(Switches, switches, UInt);
 
   /* ------------------------------------------------------------------------ */
   /* Class Members                                                            */
   /* ------------------------------------------------------------------------ */
 private:
   /// delta_f parameter
   Real delta_f;
 
   /// variable saying if delta_f is equal to delta_max for each
   /// element when the traction is computed
   bool progressive_delta_f;
 
   /// count the opening/closing switches per element
   bool count_switches;
 
   /// delta of the previous step
   CohesiveInternalField<Real> delta_prec;
 
   /// stiffness for reloading
   CohesiveInternalField<Real> K_plus;
 
   /// stiffness for unloading
   CohesiveInternalField<Real> K_minus;
 
   /// 1D traction in the cohesive law
   CohesiveInternalField<Real> T_1d;
 
   /// Number of opening/closing switches
   CohesiveInternalField<UInt> switches;
 
   /// delta increment of the previous time step
   CohesiveInternalField<Real> delta_dot_prec;
 
   /// has the element passed to normal regime (not in fatigue anymore)
   CohesiveInternalField<bool> normal_regime;
 
   /// ratio indicating until what point fatigue is applied in the cohesive law
   Real fatigue_ratio;
 };
 
 } // akantu
 
 #endif /* __AKANTU_MATERIAL_COHESIVE_LINEAR_FATIGUE_HH__ */
diff --git a/src/model/solid_mechanics/solid_mechanics_model_cohesive/materials/constitutive_laws/material_cohesive_linear_friction.cc b/src/model/solid_mechanics/solid_mechanics_model_cohesive/materials/constitutive_laws/material_cohesive_linear_friction.cc
index 9de56ad9b..0379b2531 100644
--- a/src/model/solid_mechanics/solid_mechanics_model_cohesive/materials/constitutive_laws/material_cohesive_linear_friction.cc
+++ b/src/model/solid_mechanics/solid_mechanics_model_cohesive/materials/constitutive_laws/material_cohesive_linear_friction.cc
@@ -1,277 +1,277 @@
 /**
  * @file   material_cohesive_linear_friction.cc
  *
  * @author Mauro Corrado <mauro.corrado@epfl.ch>
  *
  * @date creation: Tue Jan 12 2016
- * @date last modification: Thu Jan 14 2016
+ * @date last modification: Wed Feb 21 2018
  *
  * @brief  Linear irreversible cohesive law of mixed mode loading with
  * random stress definition for extrinsic type
  *
  * @section LICENSE
  *
- * Copyright (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne) Laboratory
- * (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * Copyright (©) 2015-2018 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
- * terms  of the  GNU Lesser  General Public  License as  published by  the Free
+ * 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
+ * A PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 #include "material_cohesive_linear_friction.hh"
 #include "solid_mechanics_model_cohesive.hh"
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 template <UInt spatial_dimension>
 MaterialCohesiveLinearFriction<spatial_dimension>::
     MaterialCohesiveLinearFriction(SolidMechanicsModel & model, const ID & id)
     : MaterialParent(model, id), residual_sliding("residual_sliding", *this),
       friction_force("friction_force", *this) {
   AKANTU_DEBUG_IN();
 
   this->registerParam("mu", mu_max, Real(0.), _pat_parsable | _pat_readable,
                       "Maximum value of the friction coefficient");
 
   this->registerParam("penalty_for_friction", friction_penalty, Real(0.),
                       _pat_parsable | _pat_readable,
                       "Penalty parameter for the friction behavior");
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <UInt spatial_dimension>
 void MaterialCohesiveLinearFriction<spatial_dimension>::initMaterial() {
   AKANTU_DEBUG_IN();
 
   MaterialParent::initMaterial();
 
   friction_force.initialize(spatial_dimension);
   residual_sliding.initialize(1);
   residual_sliding.initializeHistory();
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <UInt spatial_dimension>
 void MaterialCohesiveLinearFriction<spatial_dimension>::computeTraction(
     __attribute__((unused)) const Array<Real> & normal, ElementType el_type,
     GhostType ghost_type) {
   AKANTU_DEBUG_IN();
 
   residual_sliding.resize();
   friction_force.resize();
 
   /// define iterators
   auto traction_it =
       this->tractions(el_type, ghost_type).begin(spatial_dimension);
   auto traction_end =
       this->tractions(el_type, ghost_type).end(spatial_dimension);
   auto opening_it = this->opening(el_type, ghost_type).begin(spatial_dimension);
   auto previous_opening_it =
       this->opening.previous(el_type, ghost_type).begin(spatial_dimension);
   auto contact_traction_it =
       this->contact_tractions(el_type, ghost_type).begin(spatial_dimension);
   auto contact_opening_it =
       this->contact_opening(el_type, ghost_type).begin(spatial_dimension);
   auto normal_it = this->normal.begin(spatial_dimension);
   auto sigma_c_it = this->sigma_c_eff(el_type, ghost_type).begin();
   auto delta_max_it = this->delta_max(el_type, ghost_type).begin();
   auto delta_max_prev_it =
       this->delta_max.previous(el_type, ghost_type).begin();
   auto delta_c_it = this->delta_c_eff(el_type, ghost_type).begin();
   auto damage_it = this->damage(el_type, ghost_type).begin();
   auto insertion_stress_it =
       this->insertion_stress(el_type, ghost_type).begin(spatial_dimension);
   auto res_sliding_it = this->residual_sliding(el_type, ghost_type).begin();
   auto res_sliding_prev_it =
       this->residual_sliding.previous(el_type, ghost_type).begin();
   auto friction_force_it =
       this->friction_force(el_type, ghost_type).begin(spatial_dimension);
 
   Vector<Real> normal_opening(spatial_dimension);
   Vector<Real> tangential_opening(spatial_dimension);
 
   if (not this->model->isDefaultSolverExplicit())
     this->delta_max(el_type, ghost_type)
         .copy(this->delta_max.previous(el_type, ghost_type));
 
   /// loop on each quadrature point
   for (; traction_it != traction_end;
        ++traction_it, ++opening_it, ++normal_it, ++sigma_c_it, ++delta_max_it,
        ++delta_c_it, ++damage_it, ++contact_traction_it, ++insertion_stress_it,
        ++contact_opening_it, ++delta_max_prev_it, ++res_sliding_it,
        ++res_sliding_prev_it, ++friction_force_it, ++previous_opening_it) {
 
     Real normal_opening_norm, tangential_opening_norm;
     bool penetration;
     this->computeTractionOnQuad(
         *traction_it, *opening_it, *normal_it, *delta_max_it, *delta_c_it,
         *insertion_stress_it, *sigma_c_it, normal_opening, tangential_opening,
         normal_opening_norm, tangential_opening_norm, *damage_it, penetration,
         *contact_traction_it, *contact_opening_it);
 
     if (penetration) {
       /// the friction coefficient mu increases with the damage. It
       /// equals the maximum value when damage = 1.
       //      Real damage = std::min(*delta_max_prev_it / *delta_c_it,
       //      Real(1.));
       Real mu = mu_max; // * damage;
 
       /// the definition of tau_max refers to the opening
       /// (penetration) of the previous incremental step
       Real normal_opening_prev_norm =
           std::min(previous_opening_it->dot(*normal_it), Real(0.));
 
       //      Vector<Real> normal_opening_prev = (*normal_it);
       //      normal_opening_prev *= normal_opening_prev_norm;
       Real tau_max = mu * this->penalty * (std::abs(normal_opening_prev_norm));
       Real delta_sliding_norm =
           std::abs(tangential_opening_norm - *res_sliding_prev_it);
 
       /// tau is the norm of the friction force, acting tangentially to the
       /// surface
       Real tau = std::min(friction_penalty * delta_sliding_norm, tau_max);
 
       if ((tangential_opening_norm - *res_sliding_prev_it) < 0.0)
         tau = -tau;
 
       /// from tau get the x and y components of friction, to be added in the
       /// force vector
       Vector<Real> tangent_unit_vector(spatial_dimension);
       tangent_unit_vector = tangential_opening / tangential_opening_norm;
       *friction_force_it = tau * tangent_unit_vector;
 
       /// update residual_sliding
       *res_sliding_it =
           tangential_opening_norm - (std::abs(tau) / friction_penalty);
     } else {
       friction_force_it->clear();
     }
 
     *traction_it += *friction_force_it;
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <UInt spatial_dimension>
 void MaterialCohesiveLinearFriction<spatial_dimension>::computeTangentTraction(
     const ElementType & el_type, Array<Real> & tangent_matrix,
     __attribute__((unused)) const Array<Real> & normal, GhostType ghost_type) {
   AKANTU_DEBUG_IN();
 
   /// define iterators
   auto tangent_it = tangent_matrix.begin(spatial_dimension, spatial_dimension);
   auto tangent_end = tangent_matrix.end(spatial_dimension, spatial_dimension);
 
   auto normal_it = this->normal.begin(spatial_dimension);
 
   auto opening_it = this->opening(el_type, ghost_type).begin(spatial_dimension);
   auto previous_opening_it =
       this->opening.previous(el_type, ghost_type).begin(spatial_dimension);
 
   /**
    * NB: delta_max_it points on delta_max_previous, i.e. the
    * delta_max related to the solution of the previous incremental
    * step
    */
   auto delta_max_it = this->delta_max.previous(el_type, ghost_type).begin();
   auto sigma_c_it = this->sigma_c_eff(el_type, ghost_type).begin();
   auto delta_c_it = this->delta_c_eff(el_type, ghost_type).begin();
   auto damage_it = this->damage(el_type, ghost_type).begin();
 
   auto contact_opening_it =
       this->contact_opening(el_type, ghost_type).begin(spatial_dimension);
 
   auto res_sliding_prev_it =
       this->residual_sliding.previous(el_type, ghost_type).begin();
 
   Vector<Real> normal_opening(spatial_dimension);
   Vector<Real> tangential_opening(spatial_dimension);
 
   for (; tangent_it != tangent_end;
        ++tangent_it, ++normal_it, ++opening_it, ++previous_opening_it,
        ++delta_max_it, ++sigma_c_it, ++delta_c_it, ++damage_it,
        ++contact_opening_it, ++res_sliding_prev_it) {
 
     Real normal_opening_norm, tangential_opening_norm;
     bool penetration;
     this->computeTangentTractionOnQuad(
         *tangent_it, *delta_max_it, *delta_c_it, *sigma_c_it, *opening_it,
         *normal_it, normal_opening, tangential_opening, normal_opening_norm,
         tangential_opening_norm, *damage_it, penetration, *contact_opening_it);
 
     if (penetration) {
       //      Real damage = std::min(*delta_max_it / *delta_c_it, Real(1.));
       Real mu = mu_max; // * damage;
 
       Real normal_opening_prev_norm =
           std::min(previous_opening_it->dot(*normal_it), Real(0.));
       //      Vector<Real> normal_opening_prev = (*normal_it);
       //      normal_opening_prev *= normal_opening_prev_norm;
 
       Real tau_max = mu * this->penalty * (std::abs(normal_opening_prev_norm));
       Real delta_sliding_norm =
           std::abs(tangential_opening_norm - *res_sliding_prev_it);
 
       // tau is the norm of the friction force, acting tangentially to the
       // surface
       Real tau = std::min(friction_penalty * delta_sliding_norm, tau_max);
 
       if (tau < tau_max && tau_max > Math::getTolerance()) {
         Matrix<Real> I(spatial_dimension, spatial_dimension);
         I.eye(1.);
 
         Matrix<Real> n_outer_n(spatial_dimension, spatial_dimension);
         n_outer_n.outerProduct(*normal_it, *normal_it);
 
         Matrix<Real> nn(n_outer_n);
         I -= nn;
         *tangent_it += I * friction_penalty;
       }
     }
 
     // check if the tangential stiffness matrix is symmetric
     //    for (UInt h = 0; h < spatial_dimension; ++h){
     //      for (UInt l = h; l < spatial_dimension; ++l){
     //        if (l > h){
     //          Real k_ls = (*tangent_it)[spatial_dimension*h+l];
     //          Real k_us =  (*tangent_it)[spatial_dimension*l+h];
     //          //          std::cout << "k_ls = " << k_ls << std::endl;
     //          //          std::cout << "k_us = " << k_us << std::endl;
     //          if (std::abs(k_ls) > 1e-13 && std::abs(k_us) > 1e-13){
     //            Real error = std::abs((k_ls - k_us) / k_us);
     //            if (error > 1e-10){
     //	      std::cout << "non symmetric cohesive matrix" << std::endl;
     //	      //  std::cout << "error " << error << std::endl;
     //            }
     //          }
     //        }
     //      }
     //    }
   }
 
   AKANTU_DEBUG_OUT();
 }
 /* -------------------------------------------------------------------------- */
 
 INSTANTIATE_MATERIAL(cohesive_linear_friction, MaterialCohesiveLinearFriction);
 
 } // akantu
diff --git a/src/model/solid_mechanics/solid_mechanics_model_cohesive/materials/constitutive_laws/material_cohesive_linear_friction.hh b/src/model/solid_mechanics/solid_mechanics_model_cohesive/materials/constitutive_laws/material_cohesive_linear_friction.hh
index f928863f1..8df782f9c 100644
--- a/src/model/solid_mechanics/solid_mechanics_model_cohesive/materials/constitutive_laws/material_cohesive_linear_friction.hh
+++ b/src/model/solid_mechanics/solid_mechanics_model_cohesive/materials/constitutive_laws/material_cohesive_linear_friction.hh
@@ -1,106 +1,105 @@
 /**
  * @file   material_cohesive_linear_friction.hh
  *
  * @author Mauro Corrado <mauro.corrado@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Fri Jun 18 2010
- * @date last modification: Tue Jan 12 2016
+ * @date last modification: Wed Feb 21 2018
  *
  * @brief  Linear irreversible cohesive law of mixed mode loading with
  * random stress definition for extrinsic type
  *
  * @section LICENSE
  *
- * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
- * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
- * Solides)
+ * 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
+ * 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
+ * A PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 
 #include "material_cohesive_linear.hh"
 
 /* -------------------------------------------------------------------------- */
 #ifndef __AKANTU_MATERIAL_COHESIVE_LINEAR_FRICTION_HH__
 #define __AKANTU_MATERIAL_COHESIVE_LINEAR_FRICTION_HH__
 
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 
 /**
  * Cohesive material linear with friction force
  *
  * parameters in the material files :
  *   - mu   : friction coefficient
  *   - penalty_for_friction : Penalty parameter for the friction behavior
  */
 template <UInt spatial_dimension>
 class MaterialCohesiveLinearFriction
     : public MaterialCohesiveLinear<spatial_dimension> {
   /* ------------------------------------------------------------------------ */
   /* Constructors/Destructors                                                 */
   /* ------------------------------------------------------------------------ */
   using MaterialParent = MaterialCohesiveLinear<spatial_dimension>;
 
 public:
   MaterialCohesiveLinearFriction(SolidMechanicsModel & model,
                                  const ID & id = "");
 
   /* ------------------------------------------------------------------------ */
   /* Methods                                                                  */
   /* ------------------------------------------------------------------------ */
 public:
   /// initialize the material parameters
   void initMaterial() override;
 
 protected:
   /// constitutive law
   void computeTraction(const Array<Real> & normal, ElementType el_type,
                        GhostType ghost_type = _not_ghost) override;
 
   /// compute tangent stiffness matrix
   void computeTangentTraction(const ElementType & el_type,
                               Array<Real> & tangent_matrix,
                               const Array<Real> & normal,
                               GhostType ghost_type) override;
 
   /* ------------------------------------------------------------------------ */
   /* Accessors                                                                */
   /* ------------------------------------------------------------------------ */
 public:
   /* ------------------------------------------------------------------------ */
   /* Class Members                                                            */
   /* ------------------------------------------------------------------------ */
 protected:
   /// maximum value of the friction coefficient
   Real mu_max;
 
   /// penalty parameter for the friction law
   Real friction_penalty;
 
   /// history parameter for the friction law
   CohesiveInternalField<Real> residual_sliding;
 
   /// friction force
   CohesiveInternalField<Real> friction_force;
 };
 
 } // akantu
 
 #endif /* __AKANTU_MATERIAL_COHESIVE_LINEAR_FRICTION_HH__ */
diff --git a/src/model/solid_mechanics/solid_mechanics_model_cohesive/materials/constitutive_laws/material_cohesive_linear_inline_impl.cc b/src/model/solid_mechanics/solid_mechanics_model_cohesive/materials/constitutive_laws/material_cohesive_linear_inline_impl.cc
index 08322ed07..448c63ea2 100644
--- a/src/model/solid_mechanics/solid_mechanics_model_cohesive/materials/constitutive_laws/material_cohesive_linear_inline_impl.cc
+++ b/src/model/solid_mechanics/solid_mechanics_model_cohesive/materials/constitutive_laws/material_cohesive_linear_inline_impl.cc
@@ -1,264 +1,266 @@
 /**
  * @file   material_cohesive_linear_inline_impl.cc
  *
  * @author Mauro Corrado <mauro.corrado@epfl.ch>
+ * @author Nicolas Richart <nicolas.richart@epfl.ch>
  * @author Marco Vocialta <marco.vocialta@epfl.ch>
  *
  * @date creation: Wed Apr 22 2015
- * @date last modification: Thu Jan 14 2016
+ * @date last modification: Wed Feb 21 2018
  *
  * @brief  Inline functions of the MaterialCohesiveLinear
  *
  * @section LICENSE
  *
- * Copyright (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne) Laboratory
- * (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * Copyright (©) 2015-2018 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
- * terms  of the  GNU Lesser  General Public  License as  published by  the Free
+ * 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
+ * A PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
+
 /* -------------------------------------------------------------------------- */
 #include "material_cohesive_linear.hh"
 #include "solid_mechanics_model_cohesive.hh"
 /* -------------------------------------------------------------------------- */
 
 /* -------------------------------------------------------------------------- */
 #ifndef __AKANTU_MATERIAL_COHESIVE_LINEAR_INLINE_IMPL_CC__
 #define __AKANTU_MATERIAL_COHESIVE_LINEAR_INLINE_IMPL_CC__
 
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 template <UInt dim>
 inline Real MaterialCohesiveLinear<dim>::computeEffectiveNorm(
     const Matrix<Real> & stress, const Vector<Real> & normal,
     const Vector<Real> & tangent, Vector<Real> & normal_traction) const {
   normal_traction.mul<false>(stress, normal);
 
   Real normal_contrib = normal_traction.dot(normal);
 
   /// in 3D tangential components must be summed
   Real tangent_contrib = 0;
 
   if (dim == 2) {
     Real tangent_contrib_tmp = normal_traction.dot(tangent);
     tangent_contrib += tangent_contrib_tmp * tangent_contrib_tmp;
   } else if (dim == 3) {
     for (UInt s = 0; s < dim - 1; ++s) {
       const Vector<Real> tangent_v(tangent.storage() + s * dim, dim);
       Real tangent_contrib_tmp = normal_traction.dot(tangent_v);
       tangent_contrib += tangent_contrib_tmp * tangent_contrib_tmp;
     }
   }
 
   tangent_contrib = std::sqrt(tangent_contrib);
   normal_contrib = std::max(Real(0.), normal_contrib);
 
   return std::sqrt(normal_contrib * normal_contrib +
                    tangent_contrib * tangent_contrib * beta2_inv);
 }
 
 /* -------------------------------------------------------------------------- */
 template <UInt dim>
 inline void MaterialCohesiveLinear<dim>::computeTractionOnQuad(
     Vector<Real> & traction, Vector<Real> & opening,
     const Vector<Real> & normal, Real & delta_max, const Real & delta_c,
     const Vector<Real> & insertion_stress, const Real & sigma_c,
     Vector<Real> & normal_opening, Vector<Real> & tangential_opening,
     Real & normal_opening_norm, Real & tangential_opening_norm, Real & damage,
     bool & penetration, Vector<Real> & contact_traction,
     Vector<Real> & contact_opening) {
 
   /// compute normal and tangential opening vectors
   normal_opening_norm = opening.dot(normal);
   normal_opening = normal;
   normal_opening *= normal_opening_norm;
 
   tangential_opening = opening;
   tangential_opening -= normal_opening;
   tangential_opening_norm = tangential_opening.norm();
 
   /**
    * compute effective opening displacement
    * @f$ \delta = \sqrt{
    * \frac{\beta^2}{\kappa^2} \Delta_t^2 + \Delta_n^2 } @f$
    */
   Real delta =
       tangential_opening_norm * tangential_opening_norm * this->beta2_kappa2;
 
   penetration = normal_opening_norm / delta_c < -Math::getTolerance();
   // penetration = normal_opening_norm < 0.;
   if (this->contact_after_breaking == false &&
       Math::are_float_equal(damage, 1.))
     penetration = false;
 
   if (penetration) {
     /// use penalty coefficient in case of penetration
     contact_traction = normal_opening;
     contact_traction *= this->penalty;
     contact_opening = normal_opening;
 
     /// don't consider penetration contribution for delta
     opening = tangential_opening;
     normal_opening.clear();
   } else {
     delta += normal_opening_norm * normal_opening_norm;
     contact_traction.clear();
     contact_opening.clear();
   }
 
   delta = std::sqrt(delta);
 
   /// update maximum displacement and damage
   delta_max = std::max(delta_max, delta);
   damage = std::min(delta_max / delta_c, Real(1.));
 
   /**
    * Compute traction @f$ \mathbf{T} = \left(
    * \frac{\beta^2}{\kappa} \Delta_t \mathbf{t} + \Delta_n
    * \mathbf{n} \right) \frac{\sigma_c}{\delta} \left( 1-
    * \frac{\delta}{\delta_c} \right)@f$
    */
 
   if (Math::are_float_equal(damage, 1.))
     traction.clear();
   else if (Math::are_float_equal(damage, 0.)) {
     if (penetration)
       traction.clear();
     else
       traction = insertion_stress;
   } else {
     traction = tangential_opening;
     traction *= this->beta2_kappa;
     traction += normal_opening;
 
     AKANTU_DEBUG_ASSERT(delta_max != 0.,
                         "Division by zero, tolerance might be too low");
 
     traction *= sigma_c / delta_max * (1. - damage);
   }
 }
 
 /* -------------------------------------------------------------------------- */
 template <UInt dim>
 inline void MaterialCohesiveLinear<dim>::computeTangentTractionOnQuad(
     Matrix<Real> & tangent, Real & delta_max, const Real & delta_c,
     const Real & sigma_c, Vector<Real> & opening, const Vector<Real> & normal,
     Vector<Real> & normal_opening, Vector<Real> & tangential_opening,
     Real & normal_opening_norm, Real & tangential_opening_norm, Real & damage,
     bool & penetration, Vector<Real> & contact_opening) {
 
   /**
    * During the update of the residual the interpenetrations are
    * stored in the array "contact_opening", therefore, in the case
    * of penetration, in the array "opening" there are only the
    * tangential components.
    */
   opening += contact_opening;
 
   /// compute normal and tangential opening vectors
   normal_opening_norm = opening.dot(normal);
   normal_opening = normal;
   normal_opening *= normal_opening_norm;
 
   tangential_opening = opening;
   tangential_opening -= normal_opening;
   tangential_opening_norm = tangential_opening.norm();
 
   Real delta =
       tangential_opening_norm * tangential_opening_norm * this->beta2_kappa2;
 
   penetration = normal_opening_norm < 0.0;
   if (this->contact_after_breaking == false &&
       Math::are_float_equal(damage, 1.))
     penetration = false;
 
   Real derivative = 0; // derivative = d(t/delta)/ddelta
   Real t = 0;
 
   Matrix<Real> n_outer_n(spatial_dimension, spatial_dimension);
   n_outer_n.outerProduct(normal, normal);
 
   if (penetration) {
     /// stiffness in compression given by the penalty parameter
     tangent += n_outer_n;
     tangent *= penalty;
 
     opening = tangential_opening;
     normal_opening_norm = opening.dot(normal);
     normal_opening = normal;
     normal_opening *= normal_opening_norm;
   } else {
     delta += normal_opening_norm * normal_opening_norm;
   }
 
   delta = std::sqrt(delta);
 
   /**
    * Delta has to be different from 0 to have finite values of
    * tangential stiffness.  At the element insertion, delta =
    * 0. Therefore, a fictictious value is defined, for the
    * evaluation of the first value of K.
    */
   if (delta < Math::getTolerance())
     delta = delta_c / 1000.;
 
   if (delta >= delta_max) {
     if (delta <= delta_c) {
       derivative = -sigma_c / (delta * delta);
       t = sigma_c * (1 - delta / delta_c);
     } else {
       derivative = 0.;
       t = 0.;
     }
   } else if (delta < delta_max) {
     Real tmax = sigma_c * (1 - delta_max / delta_c);
     t = tmax / delta_max * delta;
   }
 
   /// computation of the derivative of the constitutive law (dT/ddelta)
   Matrix<Real> I(spatial_dimension, spatial_dimension);
   I.eye(this->beta2_kappa);
 
   Matrix<Real> nn(n_outer_n);
   nn *= (1. - this->beta2_kappa);
   nn += I;
   nn *= t / delta;
 
   Vector<Real> t_tilde(normal_opening);
   t_tilde *= (1. - this->beta2_kappa2);
 
   Vector<Real> mm(opening);
   mm *= this->beta2_kappa2;
   t_tilde += mm;
 
   Vector<Real> t_hat(normal_opening);
   t_hat += this->beta2_kappa * tangential_opening;
 
   Matrix<Real> prov(spatial_dimension, spatial_dimension);
   prov.outerProduct(t_hat, t_tilde);
   prov *= derivative / delta;
   prov += nn;
 
   Matrix<Real> prov_t = prov.transpose();
   tangent += prov_t;
 }
 
 /* -------------------------------------------------------------------------- */
 } // akantu
 
 /* -------------------------------------------------------------------------- */
 #endif //__AKANTU_MATERIAL_COHESIVE_LINEAR_INLINE_IMPL_CC__
diff --git a/src/model/solid_mechanics/solid_mechanics_model_cohesive/materials/constitutive_laws/material_cohesive_linear_uncoupled.cc b/src/model/solid_mechanics/solid_mechanics_model_cohesive/materials/constitutive_laws/material_cohesive_linear_uncoupled.cc
index f31411171..622b5e77b 100644
--- a/src/model/solid_mechanics/solid_mechanics_model_cohesive/materials/constitutive_laws/material_cohesive_linear_uncoupled.cc
+++ b/src/model/solid_mechanics/solid_mechanics_model_cohesive/materials/constitutive_laws/material_cohesive_linear_uncoupled.cc
@@ -1,414 +1,413 @@
 /**
  * @file   material_cohesive_linear_uncoupled.cc
  *
  * @author Mauro Corrado <mauro.corrado@epfl.ch>
  *
- * @date creation: Wed Feb 22 2012
- * @date last modification: Thu Jan 14 2016
+ * @date creation: Mon Jul 25 2016
+ * @date last modification: Wed Feb 21 2018
  *
  * @brief  Linear irreversible cohesive law of mixed mode loading with
  * random stress definition for extrinsic type
  *
  * @section LICENSE
  *
- * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
- * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
- * Solides)
+ * 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
+ * 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
+ * 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 <algorithm>
 #include <numeric>
 
 /* -------------------------------------------------------------------------- */
 #include "material_cohesive_linear_uncoupled.hh"
 #include "solid_mechanics_model_cohesive.hh"
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 template <UInt spatial_dimension>
 MaterialCohesiveLinearUncoupled<spatial_dimension>::
     MaterialCohesiveLinearUncoupled(SolidMechanicsModel & model, const ID & id)
     : MaterialCohesiveLinear<spatial_dimension>(model, id),
       delta_n_max("delta_n_max", *this), delta_t_max("delta_t_max", *this),
       damage_n("damage_n", *this), damage_t("damage_t", *this) {
 
   AKANTU_DEBUG_IN();
 
   this->registerParam(
       "roughness", R, Real(1.), _pat_parsable | _pat_readable,
       "Roughness to define coupling between mode II and mode I");
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <UInt spatial_dimension>
 void MaterialCohesiveLinearUncoupled<spatial_dimension>::initMaterial() {
   AKANTU_DEBUG_IN();
 
   MaterialCohesiveLinear<spatial_dimension>::initMaterial();
 
   delta_n_max.initialize(1);
   delta_t_max.initialize(1);
   damage_n.initialize(1);
   damage_t.initialize(1);
 
   delta_n_max.initializeHistory();
   delta_t_max.initializeHistory();
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <UInt spatial_dimension>
 void MaterialCohesiveLinearUncoupled<spatial_dimension>::computeTraction(
     const Array<Real> &, ElementType el_type, GhostType ghost_type) {
   AKANTU_DEBUG_IN();
 
   delta_n_max.resize();
   delta_t_max.resize();
   damage_n.resize();
   damage_t.resize();
 
   /// define iterators
   auto traction_it =
       this->tractions(el_type, ghost_type).begin(spatial_dimension);
 
   auto traction_end =
       this->tractions(el_type, ghost_type).end(spatial_dimension);
 
   auto opening_it = this->opening(el_type, ghost_type).begin(spatial_dimension);
   auto contact_traction_it =
       this->contact_tractions(el_type, ghost_type).begin(spatial_dimension);
   auto contact_opening_it =
       this->contact_opening(el_type, ghost_type).begin(spatial_dimension);
 
   auto normal_it = this->normal.begin(spatial_dimension);
   auto sigma_c_it = this->sigma_c_eff(el_type, ghost_type).begin();
   auto delta_n_max_it = delta_n_max(el_type, ghost_type).begin();
   auto delta_t_max_it = delta_t_max(el_type, ghost_type).begin();
   auto delta_c_it = this->delta_c_eff(el_type, ghost_type).begin();
   auto damage_n_it = damage_n(el_type, ghost_type).begin();
   auto damage_t_it = damage_t(el_type, ghost_type).begin();
 
   auto insertion_stress_it =
       this->insertion_stress(el_type, ghost_type).begin(spatial_dimension);
 
   Vector<Real> normal_opening(spatial_dimension);
   Vector<Real> tangential_opening(spatial_dimension);
 
   /// loop on each quadrature point
   for (; traction_it != traction_end;
        ++traction_it, ++opening_it, ++contact_traction_it, ++contact_opening_it,
        ++normal_it, ++sigma_c_it, ++delta_n_max_it, ++delta_t_max_it,
        ++delta_c_it, ++damage_n_it, ++damage_t_it, ++insertion_stress_it) {
 
     Real normal_opening_norm, tangential_opening_norm;
     bool penetration;
 
     Real delta_c2_R2 = *delta_c_it * (*delta_c_it) / R / R;
 
     /// compute normal and tangential opening vectors
     normal_opening_norm = opening_it->dot(*normal_it);
     Vector<Real> normal_opening = *normal_it;
     normal_opening *= normal_opening_norm;
 
     //    std::cout<< "normal_opening_norm = " << normal_opening_norm
     //    <<std::endl;
 
     Vector<Real> tangential_opening = *opening_it;
     tangential_opening -= normal_opening;
     tangential_opening_norm = tangential_opening.norm();
 
     /// compute effective opening displacement
     Real delta_n =
         tangential_opening_norm * tangential_opening_norm * this->beta2_kappa2;
     Real delta_t =
         tangential_opening_norm * tangential_opening_norm * this->beta2_kappa2;
 
     penetration = normal_opening_norm < 0.0;
     if (this->contact_after_breaking == false &&
         Math::are_float_equal(*damage_n_it, 1.))
       penetration = false;
 
     if (penetration) {
       /// use penalty coefficient in case of penetration
       *contact_traction_it = normal_opening;
       *contact_traction_it *= this->penalty;
       *contact_opening_it = normal_opening;
 
       /// don't consider penetration contribution for delta
       //*opening_it = tangential_opening;
       normal_opening.clear();
 
     } else {
       delta_n += normal_opening_norm * normal_opening_norm;
       delta_t += normal_opening_norm * normal_opening_norm * delta_c2_R2;
       contact_traction_it->clear();
       contact_opening_it->clear();
     }
 
     delta_n = std::sqrt(delta_n);
     delta_t = std::sqrt(delta_t);
 
     /// update maximum displacement and damage
     *delta_n_max_it = std::max(*delta_n_max_it, delta_n);
     *damage_n_it = std::min(*delta_n_max_it / *delta_c_it, Real(1.));
 
     *delta_t_max_it = std::max(*delta_t_max_it, delta_t);
     *damage_t_it = std::min(*delta_t_max_it / *delta_c_it, Real(1.));
 
     Vector<Real> normal_traction(spatial_dimension);
     Vector<Real> shear_traction(spatial_dimension);
 
     /// NORMAL TRACTIONS
     if (Math::are_float_equal(*damage_n_it, 1.))
       normal_traction.clear();
     else if (Math::are_float_equal(*damage_n_it, 0.)) {
       if (penetration)
         normal_traction.clear();
       else
         normal_traction = *insertion_stress_it;
     } else {
       // the following formulation holds both in loading and in
       // unloading-reloading
       normal_traction = normal_opening;
 
       AKANTU_DEBUG_ASSERT(*delta_n_max_it != 0.,
                           "Division by zero, tolerance might be too low");
 
       normal_traction *= *sigma_c_it / (*delta_n_max_it) * (1. - *damage_n_it);
     }
 
     /// SHEAR TRACTIONS
     if (Math::are_float_equal(*damage_t_it, 1.))
       shear_traction.clear();
     else if (Math::are_float_equal(*damage_t_it, 0.)) {
       shear_traction.clear();
     } else {
       shear_traction = tangential_opening;
 
       AKANTU_DEBUG_ASSERT(*delta_t_max_it != 0.,
                           "Division by zero, tolerance might be too low");
 
       shear_traction *= this->beta2_kappa;
       shear_traction *= *sigma_c_it / (*delta_t_max_it) * (1. - *damage_t_it);
     }
 
     *traction_it = normal_traction;
     *traction_it += shear_traction;
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <UInt spatial_dimension>
 void MaterialCohesiveLinearUncoupled<spatial_dimension>::computeTangentTraction(
     const ElementType & el_type, Array<Real> & tangent_matrix,
     const Array<Real> &, GhostType ghost_type) {
   AKANTU_DEBUG_IN();
 
   /// define iterators
   auto tangent_it = tangent_matrix.begin(spatial_dimension, spatial_dimension);
   auto tangent_end = tangent_matrix.end(spatial_dimension, spatial_dimension);
   auto normal_it = this->normal.begin(spatial_dimension);
   auto opening_it = this->opening(el_type, ghost_type).begin(spatial_dimension);
 
   /// NB: delta_max_it points on delta_max_previous, i.e. the
   /// delta_max related to the solution of the previous incremental
   /// step
   auto delta_n_max_it = delta_n_max.previous(el_type, ghost_type).begin();
   auto delta_t_max_it = delta_t_max.previous(el_type, ghost_type).begin();
   auto sigma_c_it = this->sigma_c_eff(el_type, ghost_type).begin();
   auto delta_c_it = this->delta_c_eff(el_type, ghost_type).begin();
   auto damage_n_it = damage_n(el_type, ghost_type).begin();
 
   auto contact_opening_it =
       this->contact_opening(el_type, ghost_type).begin(spatial_dimension);
 
   Vector<Real> normal_opening(spatial_dimension);
   Vector<Real> tangential_opening(spatial_dimension);
 
   for (; tangent_it != tangent_end; ++tangent_it, ++normal_it, ++opening_it,
                                     ++sigma_c_it, ++delta_c_it,
                                     ++delta_n_max_it, ++delta_t_max_it,
                                     ++damage_n_it, ++contact_opening_it) {
 
     Real normal_opening_norm, tangential_opening_norm;
     bool penetration;
     Real delta_c2_R2 = *delta_c_it * (*delta_c_it) / R / R;
 
     /**
      * During the update of the residual the interpenetrations are
      * stored in the array "contact_opening", therefore, in the case
      * of penetration, in the array "opening" there are only the
      * tangential components.
      */
     *opening_it += *contact_opening_it;
 
     /// compute normal and tangential opening vectors
     normal_opening_norm = opening_it->dot(*normal_it);
     Vector<Real> normal_opening = *normal_it;
     normal_opening *= normal_opening_norm;
 
     Vector<Real> tangential_opening = *opening_it;
     tangential_opening -= normal_opening;
     tangential_opening_norm = tangential_opening.norm();
 
     Real delta_n =
         tangential_opening_norm * tangential_opening_norm * this->beta2_kappa2;
     Real delta_t =
         tangential_opening_norm * tangential_opening_norm * this->beta2_kappa2;
 
     penetration = normal_opening_norm < 0.0;
     if (this->contact_after_breaking == false &&
         Math::are_float_equal(*damage_n_it, 1.))
       penetration = false;
 
     Real derivative = 0; // derivative = d(t/delta)/ddelta
     Real T = 0;
 
     /// TANGENT STIFFNESS FOR NORMAL TRACTIONS
     Matrix<Real> n_outer_n(spatial_dimension, spatial_dimension);
     n_outer_n.outerProduct(*normal_it, *normal_it);
 
     if (penetration) {
       /// stiffness in compression given by the penalty parameter
       *tangent_it = n_outer_n;
       *tangent_it *= this->penalty;
 
       //*opening_it = tangential_opening;
       normal_opening.clear();
     } else {
       delta_n += normal_opening_norm * normal_opening_norm;
       delta_n = std::sqrt(delta_n);
 
       delta_t += normal_opening_norm * normal_opening_norm * delta_c2_R2;
 
       /**
        * Delta has to be different from 0 to have finite values of
        * tangential stiffness.  At the element insertion, delta =
        * 0. Therefore, a fictictious value is defined, for the
        * evaluation of the first value of K.
        */
       if (delta_n < Math::getTolerance())
         delta_n = *delta_c_it / 1000.;
 
       // loading
       if (delta_n >= *delta_n_max_it) {
         if (delta_n <= *delta_c_it) {
           derivative = -(*sigma_c_it) / (delta_n * delta_n);
           T = *sigma_c_it * (1 - delta_n / *delta_c_it);
         } else {
           derivative = 0.;
           T = 0.;
         }
         // unloading-reloading
       } else if (delta_n < *delta_n_max_it) {
         Real T_max = *sigma_c_it * (1 - *delta_n_max_it / *delta_c_it);
         derivative = 0.;
         T = T_max / *delta_n_max_it * delta_n;
       }
 
       /// computation of the derivative of the constitutive law (dT/ddelta)
       Matrix<Real> nn(n_outer_n);
       nn *= T / delta_n;
 
       Vector<Real> Delta_tilde(normal_opening);
       Delta_tilde *= (1. - this->beta2_kappa2);
       Vector<Real> mm(*opening_it);
       mm *= this->beta2_kappa2;
       Delta_tilde += mm;
 
       const Vector<Real> & Delta_hat(normal_opening);
       Matrix<Real> prov(spatial_dimension, spatial_dimension);
       prov.outerProduct(Delta_hat, Delta_tilde);
       prov *= derivative / delta_n;
       prov += nn;
 
       Matrix<Real> prov_t = prov.transpose();
 
       *tangent_it = prov_t;
     }
 
     derivative = 0.;
     T = 0.;
 
     /// TANGENT STIFFNESS FOR SHEAR TRACTIONS
     delta_t = std::sqrt(delta_t);
 
     /**
      * Delta has to be different from 0 to have finite values of
      * tangential stiffness.  At the element insertion, delta =
      * 0. Therefore, a fictictious value is defined, for the
      * evaluation of the first value of K.
      */
     if (delta_t < Math::getTolerance())
       delta_t = *delta_c_it / 1000.;
 
     // loading
     if (delta_t >= *delta_t_max_it) {
       if (delta_t <= *delta_c_it) {
         derivative = -(*sigma_c_it) / (delta_t * delta_t);
         T = *sigma_c_it * (1 - delta_t / *delta_c_it);
       } else {
         derivative = 0.;
         T = 0.;
       }
       // unloading-reloading
     } else if (delta_t < *delta_t_max_it) {
       Real T_max = *sigma_c_it * (1 - *delta_t_max_it / *delta_c_it);
       derivative = 0.;
       T = T_max / *delta_t_max_it * delta_t;
     }
 
     /// computation of the derivative of the constitutive law (dT/ddelta)
     Matrix<Real> I(spatial_dimension, spatial_dimension);
     I.eye();
     Matrix<Real> nn(n_outer_n);
     I -= nn;
     I *= T / delta_t;
 
     Vector<Real> Delta_tilde(normal_opening);
     Delta_tilde *= (delta_c2_R2 - this->beta2_kappa2);
     Vector<Real> mm(*opening_it);
     mm *= this->beta2_kappa2;
     Delta_tilde += mm;
 
     Vector<Real> Delta_hat(tangential_opening);
     Delta_hat *= this->beta2_kappa;
     Matrix<Real> prov(spatial_dimension, spatial_dimension);
     prov.outerProduct(Delta_hat, Delta_tilde);
     prov *= derivative / delta_t;
     prov += I;
 
     Matrix<Real> prov_t = prov.transpose();
 
     *tangent_it += prov_t;
   }
 
   AKANTU_DEBUG_OUT();
 }
 /* -------------------------------------------------------------------------- */
 
 INSTANTIATE_MATERIAL(cohesive_linear_uncoupled,
                      MaterialCohesiveLinearUncoupled);
 
 } // akantu
diff --git a/src/model/solid_mechanics/solid_mechanics_model_cohesive/materials/constitutive_laws/material_cohesive_linear_uncoupled.hh b/src/model/solid_mechanics/solid_mechanics_model_cohesive/materials/constitutive_laws/material_cohesive_linear_uncoupled.hh
index f63de86de..4a7d61404 100644
--- a/src/model/solid_mechanics/solid_mechanics_model_cohesive/materials/constitutive_laws/material_cohesive_linear_uncoupled.hh
+++ b/src/model/solid_mechanics/solid_mechanics_model_cohesive/materials/constitutive_laws/material_cohesive_linear_uncoupled.hh
@@ -1,103 +1,102 @@
 /**
- * @file   material_cohesive_linear.hh
+ * @file   material_cohesive_linear_uncoupled.hh
  *
  * @author Mauro Corrado <mauro.corrado@epfl.ch>
  *
  * @date creation: Fri Jun 18 2010
- * @date last modification: Thu Jan 14 2016
+ * @date last modification: Wed Feb 21 2018
  *
  * @brief  Linear irreversible cohesive law of mixed mode loading with
  * random stress definition for extrinsic type
  *
  * @section LICENSE
  *
- * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
- * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
- * Solides)
+ * 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
+ * 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
+ * A PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 
 #include "material_cohesive_linear.hh"
 
 /* -------------------------------------------------------------------------- */
 #ifndef __AKANTU_MATERIAL_COHESIVE_LINEAR_UNCOUPLED_HH__
 #define __AKANTU_MATERIAL_COHESIVE_LINEAR_UNCOUPLED_HH__
 
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 
 /**
  * Cohesive material linear with two different laws for mode I and
  * mode II, for extrinsic case
  *
  * parameters in the material files :
  *  - roughness : define the interaction between mode I and mode II (default: 0)
  */
 template <UInt spatial_dimension>
 class MaterialCohesiveLinearUncoupled
     : public MaterialCohesiveLinear<spatial_dimension> {
   /* ------------------------------------------------------------------------ */
   /* Constructors/Destructors                                                 */
   /* ------------------------------------------------------------------------ */
   //  typedef MaterialCohesiveLinear<spatial_dimension> MaterialParent;
 public:
   MaterialCohesiveLinearUncoupled(SolidMechanicsModel & model,
                                   const ID & id = "");
 
   /* ------------------------------------------------------------------------ */
   /* Methods                                                                  */
   /* ------------------------------------------------------------------------ */
 public:
   /// initialize the material parameters
   void initMaterial() override;
 
 protected:
   /// constitutive law
   void computeTraction(const Array<Real> & normal, ElementType el_type,
                        GhostType ghost_type = _not_ghost) override;
 
   /// compute tangent stiffness matrix
   void computeTangentTraction(const ElementType & el_type,
                               Array<Real> & tangent_matrix,
                               const Array<Real> & normal,
                               GhostType ghost_type) override;
 
   /* ------------------------------------------------------------------------ */
   /* Class Members                                                            */
   /* ------------------------------------------------------------------------ */
 protected:
   /// parameter to tune the interaction between mode II and mode I
   Real R;
 
   /// maximum normal displacement
   CohesiveInternalField<Real> delta_n_max;
 
   /// maximum tangential displacement
   CohesiveInternalField<Real> delta_t_max;
 
   /// damage associated to normal tractions
   CohesiveInternalField<Real> damage_n;
 
   /// damage associated to shear tractions
   CohesiveInternalField<Real> damage_t;
 };
 
 } // akantu
 
 #endif /* __AKANTU_MATERIAL_COHESIVE_LINEAR_UNCOUPLED_HH__ */
diff --git a/src/model/solid_mechanics/solid_mechanics_model_cohesive/materials/material_cohesive.cc b/src/model/solid_mechanics/solid_mechanics_model_cohesive/materials/material_cohesive.cc
index 4d55b04ce..e22a4f934 100644
--- a/src/model/solid_mechanics/solid_mechanics_model_cohesive/materials/material_cohesive.cc
+++ b/src/model/solid_mechanics/solid_mechanics_model_cohesive/materials/material_cohesive.cc
@@ -1,573 +1,574 @@
 /**
  * @file   material_cohesive.cc
  *
+ * @author Mauro Corrado <mauro.corrado@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  * @author Seyedeh Mohadeseh Taheri Mousavi <mohadeseh.taherimousavi@epfl.ch>
  * @author Marco Vocialta <marco.vocialta@epfl.ch>
  *
  * @date creation: Wed Feb 22 2012
- * @date last modification: Tue Jan 12 2016
+ * @date last modification: Mon Feb 19 2018
  *
  * @brief  Specialization of the material class for cohesive elements
  *
  * @section LICENSE
  *
- * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
- * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
- * Solides)
+ * 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
+ * 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
+ * A PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
+
 /* -------------------------------------------------------------------------- */
 #include "material_cohesive.hh"
 #include "aka_random_generator.hh"
 #include "dof_synchronizer.hh"
 #include "fe_engine_template.hh"
 #include "integrator_gauss.hh"
 #include "shape_cohesive.hh"
 #include "solid_mechanics_model_cohesive.hh"
 #include "sparse_matrix.hh"
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 MaterialCohesive::MaterialCohesive(SolidMechanicsModel & model, const ID & id)
     : Material(model, id),
       facet_filter("facet_filter", id, this->getMemoryID()),
       fem_cohesive(
           model.getFEEngineClass<MyFEEngineCohesiveType>("CohesiveFEEngine")),
       reversible_energy("reversible_energy", *this),
       total_energy("total_energy", *this), opening("opening", *this),
       tractions("tractions", *this),
       contact_tractions("contact_tractions", *this),
       contact_opening("contact_opening", *this), delta_max("delta max", *this),
       use_previous_delta_max(false), use_previous_opening(false),
       damage("damage", *this), sigma_c("sigma_c", *this),
       normal(0, spatial_dimension, "normal") {
 
   AKANTU_DEBUG_IN();
 
   this->model = dynamic_cast<SolidMechanicsModelCohesive *>(&model);
 
   this->registerParam("sigma_c", sigma_c, _pat_parsable | _pat_readable,
                       "Critical stress");
   this->registerParam("delta_c", delta_c, Real(0.),
                       _pat_parsable | _pat_readable, "Critical displacement");
 
   this->element_filter.initialize(this->model->getMesh(),
                                   _spatial_dimension = spatial_dimension,
                                   _element_kind = _ek_cohesive);
   // this->model->getMesh().initElementTypeMapArray(
   //     this->element_filter, 1, spatial_dimension, false, _ek_cohesive);
 
   if (this->model->getIsExtrinsic())
     this->facet_filter.initialize(this->model->getMeshFacets(),
                                   _spatial_dimension = spatial_dimension - 1,
                                   _element_kind = _ek_regular);
   // this->model->getMeshFacets().initElementTypeMapArray(facet_filter, 1,
   //                                                      spatial_dimension -
   //                                                      1);
 
   this->reversible_energy.initialize(1);
   this->total_energy.initialize(1);
 
   this->tractions.initialize(spatial_dimension);
   this->tractions.initializeHistory();
 
   this->contact_tractions.initialize(spatial_dimension);
   this->contact_opening.initialize(spatial_dimension);
 
   this->opening.initialize(spatial_dimension);
   this->opening.initializeHistory();
 
   this->delta_max.initialize(1);
   this->damage.initialize(1);
 
   if (this->model->getIsExtrinsic())
     this->sigma_c.initialize(1);
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 MaterialCohesive::~MaterialCohesive() {
   AKANTU_DEBUG_IN();
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void MaterialCohesive::initMaterial() {
   AKANTU_DEBUG_IN();
   Material::initMaterial();
   if (this->use_previous_delta_max)
     this->delta_max.initializeHistory();
   if (this->use_previous_opening)
     this->opening.initializeHistory();
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void MaterialCohesive::assembleInternalForces(GhostType ghost_type) {
   AKANTU_DEBUG_IN();
 
 #if defined(AKANTU_DEBUG_TOOLS)
   debug::element_manager.printData(debug::_dm_material_cohesive,
                                    "Cohesive Tractions", tractions);
 #endif
 
   auto & internal_force = const_cast<Array<Real> &>(model->getInternalForce());
 
   for (auto type : element_filter.elementTypes(spatial_dimension, ghost_type,
                                                _ek_cohesive)) {
     auto & elem_filter = element_filter(type, ghost_type);
     UInt nb_element = elem_filter.size();
     if (nb_element == 0)
       continue;
 
     const auto & shapes = fem_cohesive.getShapes(type, ghost_type);
     auto & traction = tractions(type, ghost_type);
     auto & contact_traction = contact_tractions(type, ghost_type);
 
     UInt size_of_shapes = shapes.getNbComponent();
     UInt nb_nodes_per_element = Mesh::getNbNodesPerElement(type);
     UInt nb_quadrature_points =
         fem_cohesive.getNbIntegrationPoints(type, ghost_type);
 
     /// compute @f$t_i N_a@f$
 
     Array<Real> * traction_cpy = new Array<Real>(
         nb_element * nb_quadrature_points, spatial_dimension * size_of_shapes);
 
     auto traction_it = traction.begin(spatial_dimension, 1);
     auto contact_traction_it = contact_traction.begin(spatial_dimension, 1);
     auto shapes_filtered_begin = shapes.begin(1, size_of_shapes);
     auto traction_cpy_it =
         traction_cpy->begin(spatial_dimension, size_of_shapes);
 
     Matrix<Real> traction_tmp(spatial_dimension, 1);
 
     for (UInt el = 0; el < nb_element; ++el) {
 
       UInt current_quad = elem_filter(el) * nb_quadrature_points;
 
       for (UInt q = 0; q < nb_quadrature_points; ++q, ++traction_it,
                 ++contact_traction_it, ++current_quad, ++traction_cpy_it) {
 
         const Matrix<Real> & shapes_filtered =
             shapes_filtered_begin[current_quad];
 
         traction_tmp.copy(*traction_it);
         traction_tmp += *contact_traction_it;
 
         traction_cpy_it->mul<false, false>(traction_tmp, shapes_filtered);
       }
     }
 
     /**
      * compute @f$\int t \cdot N\, dS@f$ by  @f$ \sum_q \mathbf{N}^t
      * \mathbf{t}_q \overline w_q J_q@f$
      */
     Array<Real> * int_t_N = new Array<Real>(
         nb_element, spatial_dimension * size_of_shapes, "int_t_N");
 
     fem_cohesive.integrate(*traction_cpy, *int_t_N,
                            spatial_dimension * size_of_shapes, type, ghost_type,
                            elem_filter);
 
     delete traction_cpy;
 
     int_t_N->extendComponentsInterlaced(2, int_t_N->getNbComponent());
 
     Real * int_t_N_val = int_t_N->storage();
     for (UInt el = 0; el < nb_element; ++el) {
       for (UInt n = 0; n < size_of_shapes * spatial_dimension; ++n)
         int_t_N_val[n] *= -1.;
       int_t_N_val += nb_nodes_per_element * spatial_dimension;
     }
 
     /// assemble
     model->getDOFManager().assembleElementalArrayLocalArray(
         *int_t_N, internal_force, type, ghost_type, -1, elem_filter);
 
     delete int_t_N;
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void MaterialCohesive::assembleStiffnessMatrix(GhostType ghost_type) {
 
   AKANTU_DEBUG_IN();
 
   for (auto type : element_filter.elementTypes(spatial_dimension, ghost_type,
                                                _ek_cohesive)) {
     UInt nb_quadrature_points =
         fem_cohesive.getNbIntegrationPoints(type, ghost_type);
     UInt nb_nodes_per_element = Mesh::getNbNodesPerElement(type);
 
     const Array<Real> & shapes = fem_cohesive.getShapes(type, ghost_type);
     Array<UInt> & elem_filter = element_filter(type, ghost_type);
 
     UInt nb_element = elem_filter.size();
 
     if (!nb_element)
       continue;
 
     UInt size_of_shapes = shapes.getNbComponent();
 
     Array<Real> * shapes_filtered = new Array<Real>(
         nb_element * nb_quadrature_points, size_of_shapes, "filtered shapes");
 
     Real * shapes_filtered_val = shapes_filtered->storage();
     UInt * elem_filter_val = elem_filter.storage();
 
     for (UInt el = 0; el < nb_element; ++el) {
       auto shapes_val =
           shapes.storage() +
           elem_filter_val[el] * size_of_shapes * nb_quadrature_points;
       memcpy(shapes_filtered_val, shapes_val,
              size_of_shapes * nb_quadrature_points * sizeof(Real));
       shapes_filtered_val += size_of_shapes * nb_quadrature_points;
     }
 
     /**
      * compute A matrix @f$ \mathbf{A} = \left[\begin{array}{c c c c c c c c c c
      *c c}
      * 1 & 0 & 0 & 0 & 0 & 0 & -1 &  0 &  0 &  0 &  0 &  0 \\
      * 0 & 1 & 0 & 0 & 0 & 0 &  0 & -1 &  0 &  0 &  0 &  0 \\
      * 0 & 0 & 1 & 0 & 0 & 0 &  0 &  0 & -1 &  0 &  0 &  0 \\
      * 0 & 0 & 0 & 1 & 0 & 0 &  0 &  0 &  0 & -1 &  0 &  0 \\
      * 0 & 0 & 0 & 0 & 1 & 0 &  0 &  0 &  0 &  0 & -1 &  0 \\
      * 0 & 0 & 0 & 0 & 0 & 1 &  0 &  0 &  0 &  0 &  0 & -1
      * \end{array} \right]@f$
      **/
 
     // UInt size_of_A =
     // spatial_dimension*size_of_shapes*spatial_dimension*nb_nodes_per_element;
     // Real * A = new Real[size_of_A];
     // memset(A, 0, size_of_A*sizeof(Real));
     Matrix<Real> A(spatial_dimension * size_of_shapes,
                    spatial_dimension * nb_nodes_per_element);
 
     for (UInt i = 0; i < spatial_dimension * size_of_shapes; ++i) {
       A(i, i) = 1;
       A(i, i + spatial_dimension * size_of_shapes) = -1;
     }
 
     // compute traction. This call is not necessary for the linear
     // cohesive law that, currently, is the only one used for the
     // extrinsic approach.
     //    if (!model->getIsExtrinsic()){
     //  computeTraction(ghost_type);
     //}
 
     /// get the tangent matrix @f$\frac{\partial{(t/\delta)}}{\partial{\delta}}
     /// @f$
     Array<Real> * tangent_stiffness_matrix = new Array<Real>(
         nb_element * nb_quadrature_points,
         spatial_dimension * spatial_dimension, "tangent_stiffness_matrix");
 
     //    Array<Real> * normal = new Array<Real>(nb_element *
     //    nb_quadrature_points, spatial_dimension, "normal");
     normal.resize(nb_quadrature_points);
 
     computeNormal(model->getCurrentPosition(), normal, type, ghost_type);
 
     /// compute openings @f$\mathbf{\delta}@f$
     // computeOpening(model->getDisplacement(), opening(type, ghost_type), type,
     // ghost_type);
 
     tangent_stiffness_matrix->clear();
 
     computeTangentTraction(type, *tangent_stiffness_matrix, normal, ghost_type);
 
     // delete normal;
 
     UInt size_at_nt_d_n_a = spatial_dimension * nb_nodes_per_element *
                             spatial_dimension * nb_nodes_per_element;
     Array<Real> * at_nt_d_n_a = new Array<Real>(
         nb_element * nb_quadrature_points, size_at_nt_d_n_a, "A^t*N^t*D*N*A");
 
     Array<Real>::iterator<Vector<Real>> shapes_filt_it =
         shapes_filtered->begin(size_of_shapes);
 
     Array<Real>::matrix_iterator D_it =
         tangent_stiffness_matrix->begin(spatial_dimension, spatial_dimension);
 
     Array<Real>::matrix_iterator At_Nt_D_N_A_it =
         at_nt_d_n_a->begin(spatial_dimension * nb_nodes_per_element,
                            spatial_dimension * nb_nodes_per_element);
 
     Array<Real>::matrix_iterator At_Nt_D_N_A_end =
         at_nt_d_n_a->end(spatial_dimension * nb_nodes_per_element,
                          spatial_dimension * nb_nodes_per_element);
 
     Matrix<Real> N(spatial_dimension, spatial_dimension * size_of_shapes);
     Matrix<Real> N_A(spatial_dimension,
                      spatial_dimension * nb_nodes_per_element);
     Matrix<Real> D_N_A(spatial_dimension,
                        spatial_dimension * nb_nodes_per_element);
 
     for (; At_Nt_D_N_A_it != At_Nt_D_N_A_end;
          ++At_Nt_D_N_A_it, ++D_it, ++shapes_filt_it) {
       N.clear();
       /**
        * store  the   shapes  in  voigt   notations  matrix  @f$\mathbf{N}  =
        * \begin{array}{cccccc} N_0(\xi) & 0 & N_1(\xi)  &0 & N_2(\xi) & 0 \\
        * 0 & * N_0(\xi)& 0 &N_1(\xi)& 0 & N_2(\xi) \end{array} @f$
        **/
       for (UInt i = 0; i < spatial_dimension; ++i)
         for (UInt n = 0; n < size_of_shapes; ++n)
           N(i, i + spatial_dimension * n) = (*shapes_filt_it)(n);
 
       /**
        * compute stiffness matrix  @f$   \mathbf{K}    =    \delta \mathbf{U}^T
        * \int_{\Gamma_c}    {\mathbf{P}^t \frac{\partial{\mathbf{t}}}
        *{\partial{\delta}}
        * \mathbf{P} d\Gamma \Delta \mathbf{U}}  @f$
        **/
       N_A.mul<false, false>(N, A);
       D_N_A.mul<false, false>(*D_it, N_A);
       (*At_Nt_D_N_A_it).mul<true, false>(D_N_A, N_A);
     }
 
     delete tangent_stiffness_matrix;
     delete shapes_filtered;
 
     Array<Real> * K_e = new Array<Real>(nb_element, size_at_nt_d_n_a, "K_e");
 
     fem_cohesive.integrate(*at_nt_d_n_a, *K_e, size_at_nt_d_n_a, type,
                            ghost_type, elem_filter);
 
     delete at_nt_d_n_a;
 
     model->getDOFManager().assembleElementalMatricesToMatrix(
         "K", "displacement", *K_e, type, ghost_type, _unsymmetric, elem_filter);
 
     delete K_e;
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- *
  * Compute traction from displacements
  *
  * @param[in] ghost_type compute the residual for _ghost or _not_ghost element
  */
 void MaterialCohesive::computeTraction(GhostType ghost_type) {
   AKANTU_DEBUG_IN();
 
 #if defined(AKANTU_DEBUG_TOOLS)
   debug::element_manager.printData(debug::_dm_material_cohesive,
                                    "Cohesive Openings", opening);
 #endif
 
   for (auto & type : element_filter.elementTypes(spatial_dimension, ghost_type,
                                                  _ek_cohesive)) {
     Array<UInt> & elem_filter = element_filter(type, ghost_type);
 
     UInt nb_element = elem_filter.size();
     if (nb_element == 0)
       continue;
 
     UInt nb_quadrature_points =
         nb_element * fem_cohesive.getNbIntegrationPoints(type, ghost_type);
 
     normal.resize(nb_quadrature_points);
 
     /// compute normals @f$\mathbf{n}@f$
     computeNormal(model->getCurrentPosition(), normal, type, ghost_type);
 
     /// compute openings @f$\mathbf{\delta}@f$
     computeOpening(model->getDisplacement(), opening(type, ghost_type), type,
                    ghost_type);
 
     /// compute traction @f$\mathbf{t}@f$
     computeTraction(normal, type, ghost_type);
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void MaterialCohesive::computeNormal(const Array<Real> & position,
                                      Array<Real> & normal, ElementType type,
                                      GhostType ghost_type) {
   AKANTU_DEBUG_IN();
 
   auto & fem_cohesive =
       this->model->getFEEngineClass<MyFEEngineCohesiveType>("CohesiveFEEngine");
 
 #define COMPUTE_NORMAL(type)                                                   \
   fem_cohesive.getShapeFunctions()                                             \
       .computeNormalsOnIntegrationPoints<type, CohesiveReduceFunctionMean>(    \
           position, normal, ghost_type, element_filter(type, ghost_type));
 
   AKANTU_BOOST_COHESIVE_ELEMENT_SWITCH(COMPUTE_NORMAL);
 #undef COMPUTE_NORMAL
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void MaterialCohesive::computeOpening(const Array<Real> & displacement,
                                       Array<Real> & opening, ElementType type,
                                       GhostType ghost_type) {
   AKANTU_DEBUG_IN();
 
   auto & fem_cohesive =
       this->model->getFEEngineClass<MyFEEngineCohesiveType>("CohesiveFEEngine");
 
 #define COMPUTE_OPENING(type)                                                  \
   fem_cohesive.getShapeFunctions()                                             \
       .interpolateOnIntegrationPoints<type, CohesiveReduceFunctionOpening>(    \
           displacement, opening, spatial_dimension, ghost_type,                \
           element_filter(type, ghost_type));
 
   AKANTU_BOOST_COHESIVE_ELEMENT_SWITCH(COMPUTE_OPENING);
 #undef COMPUTE_OPENING
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void MaterialCohesive::updateEnergies(ElementType type, GhostType ghost_type) {
   AKANTU_DEBUG_IN();
 
   if (Mesh::getKind(type) != _ek_cohesive)
     return;
 
   Vector<Real> b(spatial_dimension);
   Vector<Real> h(spatial_dimension);
   auto erev = reversible_energy(type, ghost_type).begin();
   auto etot = total_energy(type, ghost_type).begin();
   auto traction_it = tractions(type, ghost_type).begin(spatial_dimension);
   auto traction_old_it =
       tractions.previous(type, ghost_type).begin(spatial_dimension);
   auto opening_it = opening(type, ghost_type).begin(spatial_dimension);
   auto opening_old_it =
       opening.previous(type, ghost_type).begin(spatial_dimension);
 
   auto traction_end = tractions(type, ghost_type).end(spatial_dimension);
 
   /// loop on each quadrature point
   for (; traction_it != traction_end; ++traction_it, ++traction_old_it,
                                       ++opening_it, ++opening_old_it, ++erev,
                                       ++etot) {
     /// trapezoidal integration
     b = *opening_it;
     b -= *opening_old_it;
 
     h = *traction_old_it;
     h += *traction_it;
 
     *etot += .5 * b.dot(h);
     *erev = .5 * traction_it->dot(*opening_it);
   }
 
   /// update old values
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 Real MaterialCohesive::getReversibleEnergy() {
   AKANTU_DEBUG_IN();
   Real erev = 0.;
 
   /// integrate reversible energy for each type of elements
   for (auto & type : element_filter.elementTypes(spatial_dimension, _not_ghost,
                                                  _ek_cohesive)) {
     erev +=
         fem_cohesive.integrate(reversible_energy(type, _not_ghost), type,
                                _not_ghost, element_filter(type, _not_ghost));
   }
 
   AKANTU_DEBUG_OUT();
   return erev;
 }
 
 /* -------------------------------------------------------------------------- */
 Real MaterialCohesive::getDissipatedEnergy() {
   AKANTU_DEBUG_IN();
   Real edis = 0.;
 
   /// integrate dissipated energy for each type of elements
   for (auto & type : element_filter.elementTypes(spatial_dimension, _not_ghost,
                                                  _ek_cohesive)) {
     Array<Real> dissipated_energy(total_energy(type, _not_ghost));
     dissipated_energy -= reversible_energy(type, _not_ghost);
     edis += fem_cohesive.integrate(dissipated_energy, type, _not_ghost,
                                    element_filter(type, _not_ghost));
   }
 
   AKANTU_DEBUG_OUT();
   return edis;
 }
 
 /* -------------------------------------------------------------------------- */
 Real MaterialCohesive::getContactEnergy() {
   AKANTU_DEBUG_IN();
   Real econ = 0.;
 
   /// integrate contact energy for each type of elements
   for (auto & type : element_filter.elementTypes(spatial_dimension, _not_ghost,
                                                  _ek_cohesive)) {
 
     auto & el_filter = element_filter(type, _not_ghost);
     UInt nb_quad_per_el = fem_cohesive.getNbIntegrationPoints(type, _not_ghost);
     UInt nb_quad_points = el_filter.size() * nb_quad_per_el;
     Array<Real> contact_energy(nb_quad_points);
 
     auto contact_traction_it =
         contact_tractions(type, _not_ghost).begin(spatial_dimension);
     auto contact_opening_it =
         contact_opening(type, _not_ghost).begin(spatial_dimension);
 
     /// loop on each quadrature point
     for (UInt q = 0; q < nb_quad_points;
          ++contact_traction_it, ++contact_opening_it, ++q) {
 
       contact_energy(q) = .5 * contact_traction_it->dot(*contact_opening_it);
     }
 
     econ += fem_cohesive.integrate(contact_energy, type, _not_ghost, el_filter);
   }
 
   AKANTU_DEBUG_OUT();
   return econ;
 }
 
 /* -------------------------------------------------------------------------- */
 Real MaterialCohesive::getEnergy(const std::string & type) {
   AKANTU_DEBUG_IN();
 
   if (type == "reversible")
     return getReversibleEnergy();
   else if (type == "dissipated")
     return getDissipatedEnergy();
   else if (type == "cohesive contact")
     return getContactEnergy();
 
   AKANTU_DEBUG_OUT();
   return 0.;
 }
 
 /* -------------------------------------------------------------------------- */
 } // namespace akantu
diff --git a/src/model/solid_mechanics/solid_mechanics_model_cohesive/materials/material_cohesive.hh b/src/model/solid_mechanics/solid_mechanics_model_cohesive/materials/material_cohesive.hh
index 2f854eb40..40ad8a6f3 100644
--- a/src/model/solid_mechanics/solid_mechanics_model_cohesive/materials/material_cohesive.hh
+++ b/src/model/solid_mechanics/solid_mechanics_model_cohesive/materials/material_cohesive.hh
@@ -1,238 +1,237 @@
 /**
  * @file   material_cohesive.hh
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  * @author Seyedeh Mohadeseh Taheri Mousavi <mohadeseh.taherimousavi@epfl.ch>
  * @author Marco Vocialta <marco.vocialta@epfl.ch>
  *
  * @date creation: Fri Jun 18 2010
- * @date last modification: Tue Jan 12 2016
+ * @date last modification: Wed Feb 21 2018
  *
  * @brief  Specialization of the material class for cohesive elements
  *
  * @section LICENSE
  *
- * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
- * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
- * Solides)
+ * 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
+ * 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
+ * A PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 #include "material.hh"
 /* -------------------------------------------------------------------------- */
 #include "cohesive_internal_field.hh"
 /* -------------------------------------------------------------------------- */
 
 #ifndef __AKANTU_MATERIAL_COHESIVE_HH__
 #define __AKANTU_MATERIAL_COHESIVE_HH__
 
 /* -------------------------------------------------------------------------- */
 namespace akantu {
 class SolidMechanicsModelCohesive;
 }
 
 namespace akantu {
 
 class MaterialCohesive : public Material {
   /* ------------------------------------------------------------------------ */
   /* Constructors/Destructors                                                 */
   /* ------------------------------------------------------------------------ */
 public:
   using MyFEEngineCohesiveType =
       FEEngineTemplate<IntegratorGauss, ShapeLagrange, _ek_cohesive>;
 
 public:
   MaterialCohesive(SolidMechanicsModel & model, const ID & id = "");
   ~MaterialCohesive() override;
 
   /* ------------------------------------------------------------------------ */
   /* Methods                                                                  */
   /* ------------------------------------------------------------------------ */
 public:
   /// initialize the material computed parameter
   void initMaterial() override;
 
   /// compute tractions (including normals and openings)
   void computeTraction(GhostType ghost_type = _not_ghost);
 
   /// assemble residual
   void assembleInternalForces(GhostType ghost_type = _not_ghost) override;
 
   /// check stress for cohesive elements' insertion, by default it
   /// also updates the cohesive elements' data
   virtual void checkInsertion(bool /*check_only*/ = false) {
     AKANTU_TO_IMPLEMENT();
   }
 
   /// interpolate   stress  on   given   positions  for   each  element   (empty
   /// implemantation to avoid the generic call to be done on cohesive elements)
   virtual void interpolateStress(const ElementType /*type*/,
                                  Array<Real> & /*result*/) {}
 
   /// compute the stresses
   void computeAllStresses(GhostType /*ghost_type*/ = _not_ghost) override{};
 
   // add the facet to be handled by the material
   UInt addFacet(const Element & element);
 
 protected:
   virtual void computeTangentTraction(const ElementType & /*el_type*/,
                                       Array<Real> & /*tangent_matrix*/,
                                       const Array<Real> & /*normal*/,
                                       GhostType /*ghost_type*/ = _not_ghost) {
     AKANTU_TO_IMPLEMENT();
   }
 
   /// compute the normal
   void computeNormal(const Array<Real> & position, Array<Real> & normal,
                      ElementType type, GhostType ghost_type);
 
   /// compute the opening
   void computeOpening(const Array<Real> & displacement, Array<Real> & opening,
                       ElementType type, GhostType ghost_type);
 
   template <ElementType type>
   void computeNormal(const Array<Real> & position, Array<Real> & normal,
                      GhostType ghost_type);
 
   /// assemble stiffness
   void assembleStiffnessMatrix(GhostType ghost_type) override;
 
   /// constitutive law
   virtual void computeTraction(const Array<Real> & normal, ElementType el_type,
                                GhostType ghost_type = _not_ghost) = 0;
 
   /// parallelism functions
   inline UInt getNbDataForElements(const Array<Element> & elements,
                                    SynchronizationTag tag) const;
 
   inline void packElementData(CommunicationBuffer & buffer,
                               const Array<Element> & elements,
                               SynchronizationTag tag) const;
 
   inline void unpackElementData(CommunicationBuffer & buffer,
                                 const Array<Element> & elements,
                                 SynchronizationTag tag);
 
 protected:
   void updateEnergies(ElementType el_type, GhostType ghost_type) override;
 
   /* ------------------------------------------------------------------------ */
   /* Accessors                                                                */
   /* ------------------------------------------------------------------------ */
 public:
   /// get the opening
   AKANTU_GET_MACRO_BY_ELEMENT_TYPE_CONST(Opening, opening, Real);
 
   /// get the traction
   AKANTU_GET_MACRO_BY_ELEMENT_TYPE_CONST(Traction, tractions, Real);
 
   /// get damage
   AKANTU_GET_MACRO_BY_ELEMENT_TYPE_CONST(Damage, damage, Real);
 
   /// get facet filter
   AKANTU_GET_MACRO_BY_ELEMENT_TYPE_CONST(FacetFilter, facet_filter, UInt);
   AKANTU_GET_MACRO_BY_ELEMENT_TYPE(FacetFilter, facet_filter, UInt);
   AKANTU_GET_MACRO(FacetFilter, facet_filter,
                    const ElementTypeMapArray<UInt> &);
   // AKANTU_GET_MACRO(ElementFilter, element_filter, const
   // ElementTypeMapArray<UInt> &);
 
   /// compute reversible energy
   Real getReversibleEnergy();
 
   /// compute dissipated energy
   Real getDissipatedEnergy();
 
   /// compute contact energy
   Real getContactEnergy();
 
   /// get energy
   Real getEnergy(const std::string & type) override;
 
   /// return the energy (identified by id) for the provided element
   Real getEnergy(const std::string & energy_id, ElementType type,
                  UInt index) override {
     return Material::getEnergy(energy_id, type, index);
   }
 
   /* ------------------------------------------------------------------------ */
   /* Class Members                                                            */
   /* ------------------------------------------------------------------------ */
 protected:
   /// list of facets assigned to this material
   ElementTypeMapArray<UInt> facet_filter;
 
   /// Link to the cohesive fem object in the model
   FEEngine & fem_cohesive;
 
 private:
   /// reversible energy by quadrature point
   CohesiveInternalField<Real> reversible_energy;
 
   /// total energy by quadrature point
   CohesiveInternalField<Real> total_energy;
 
 protected:
   /// opening in all elements and quadrature points
   CohesiveInternalField<Real> opening;
 
   /// traction in all elements and quadrature points
   CohesiveInternalField<Real> tractions;
 
   /// traction due to contact
   CohesiveInternalField<Real> contact_tractions;
 
   /// normal openings for contact tractions
   CohesiveInternalField<Real> contact_opening;
 
   /// maximum displacement
   CohesiveInternalField<Real> delta_max;
 
   /// tell if the previous delta_max state is needed (in iterative schemes)
   bool use_previous_delta_max;
 
   /// tell if the previous opening state is needed (in iterative schemes)
   bool use_previous_opening;
 
   /// damage
   CohesiveInternalField<Real> damage;
 
   /// pointer to the solid mechanics model for cohesive elements
   SolidMechanicsModelCohesive * model;
 
   /// critical stress
   RandomInternalField<Real, FacetInternalField> sigma_c;
 
   /// critical displacement
   Real delta_c;
 
   /// array to temporarily store the normals
   Array<Real> normal;
 };
 
 /* -------------------------------------------------------------------------- */
 /* inline functions                                                           */
 /* -------------------------------------------------------------------------- */
 
 #include "material_cohesive_inline_impl.cc"
 
 } // namespace akantu
 
 #include "cohesive_internal_field_tmpl.hh"
 
 #endif /* __AKANTU_MATERIAL_COHESIVE_HH__ */
diff --git a/src/model/solid_mechanics/solid_mechanics_model_cohesive/materials/material_cohesive_includes.hh b/src/model/solid_mechanics/solid_mechanics_model_cohesive/materials/material_cohesive_includes.hh
index 6548a282c..5cd373e11 100644
--- a/src/model/solid_mechanics/solid_mechanics_model_cohesive/materials/material_cohesive_includes.hh
+++ b/src/model/solid_mechanics/solid_mechanics_model_cohesive/materials/material_cohesive_includes.hh
@@ -1,49 +1,48 @@
 /**
  * @file   material_cohesive_includes.hh
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Sun Sep 26 2010
- * @date last modification: Tue Jan 12 2016
+ * @date last modification: Fri Oct 13 2017
  *
  * @brief  List of includes for cohesive elements
  *
  * @section LICENSE
  *
- * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
- * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
- * Solides)
+ * 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
+ * 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
+ * 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_CMAKE_LIST_MATERIALS
 #include "material_cohesive.hh"
 #include "material_cohesive_bilinear.hh"
 #include "material_cohesive_exponential.hh"
 #include "material_cohesive_linear.hh"
 #include "material_cohesive_linear_fatigue.hh"
 #include "material_cohesive_linear_friction.hh"
 #include "material_cohesive_linear_uncoupled.hh"
 #endif
 
 #define AKANTU_COHESIVE_MATERIAL_LIST                                          \
   ((2, (cohesive_linear, MaterialCohesiveLinear)))(                            \
       (2, (cohesive_linear_fatigue, MaterialCohesiveLinearFatigue)))(          \
       (2, (cohesive_linear_friction, MaterialCohesiveLinearFriction)))(        \
       (2, (cohesive_linear_uncoupled, MaterialCohesiveLinearUncoupled)))(      \
       (2, (cohesive_bilinear, MaterialCohesiveBilinear)))(                     \
       (2, (cohesive_exponential, MaterialCohesiveExponential)))
diff --git a/src/model/solid_mechanics/solid_mechanics_model_cohesive/materials/material_cohesive_inline_impl.cc b/src/model/solid_mechanics/solid_mechanics_model_cohesive/materials/material_cohesive_inline_impl.cc
index 5e6a2cf69..469d804e8 100644
--- a/src/model/solid_mechanics/solid_mechanics_model_cohesive/materials/material_cohesive_inline_impl.cc
+++ b/src/model/solid_mechanics/solid_mechanics_model_cohesive/materials/material_cohesive_inline_impl.cc
@@ -1,102 +1,101 @@
 /**
  * @file   material_cohesive_inline_impl.cc
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  * @author Marco Vocialta <marco.vocialta@epfl.ch>
  *
  * @date creation: Wed Aug 04 2010
- * @date last modification: Thu Oct 15 2015
+ * @date last modification: Mon Feb 19 2018
  *
  * @brief  MaterialCohesive inline implementation
  *
  * @section LICENSE
  *
- * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
- * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
- * Solides)
+ * 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
+ * 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
+ * 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/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 inline UInt MaterialCohesive::addFacet(const Element & element) {
   Array<UInt> & f_filter = facet_filter(element.type, element.ghost_type);
   f_filter.push_back(element.element);
   return f_filter.size() - 1;
 }
 
 /* -------------------------------------------------------------------------- */
 template <ElementType type>
 void MaterialCohesive::computeNormal(const Array<Real> & /*position*/,
                                      Array<Real> & /*normal*/,
                                      GhostType /*ghost_type*/) {}
 
 /* -------------------------------------------------------------------------- */
 inline UInt
 MaterialCohesive::getNbDataForElements(const Array<Element> & elements,
                                        SynchronizationTag tag) const {
 
   switch (tag) {
   case _gst_smm_stress: {
     return 2 * spatial_dimension * sizeof(Real) *
            this->getModel().getNbIntegrationPoints(elements,
                                                    "CohesiveFEEngine");
   }
   case _gst_smmc_damage: {
     return sizeof(Real) *
            this->getModel().getNbIntegrationPoints(elements,
                                                    "CohesiveFEEngine");
   }
   default: {}
   }
 
   return 0;
 }
 
 /* -------------------------------------------------------------------------- */
 inline void MaterialCohesive::packElementData(CommunicationBuffer & buffer,
                                               const Array<Element> & elements,
                                               SynchronizationTag tag) const {
   switch (tag) {
   case _gst_smm_stress: {
     packElementDataHelper(tractions, buffer, elements, "CohesiveFEEngine");
     packElementDataHelper(contact_tractions, buffer, elements,
                           "CohesiveFEEngine");
     break;
   }
   case _gst_smmc_damage:
     packElementDataHelper(damage, buffer, elements, "CohesiveFEEngine");
     break;
   default: {}
   }
 }
 
 /* -------------------------------------------------------------------------- */
 inline void MaterialCohesive::unpackElementData(CommunicationBuffer & buffer,
                                                 const Array<Element> & elements,
                                                 SynchronizationTag tag) {
   switch (tag) {
   case _gst_smm_stress: {
     unpackElementDataHelper(tractions, buffer, elements, "CohesiveFEEngine");
     unpackElementDataHelper(contact_tractions, buffer, elements,
                             "CohesiveFEEngine");
     break;
   }
   case _gst_smmc_damage:
     unpackElementDataHelper(damage, buffer, elements, "CohesiveFEEngine");
     break;
   default: {}
   }
 }
diff --git a/src/model/solid_mechanics/solid_mechanics_model_cohesive/solid_mechanics_model_cohesive.cc b/src/model/solid_mechanics/solid_mechanics_model_cohesive/solid_mechanics_model_cohesive.cc
index 9e2a9eb12..b6b1bc5cd 100644
--- a/src/model/solid_mechanics/solid_mechanics_model_cohesive/solid_mechanics_model_cohesive.cc
+++ b/src/model/solid_mechanics/solid_mechanics_model_cohesive/solid_mechanics_model_cohesive.cc
@@ -1,713 +1,714 @@
 /**
  * @file   solid_mechanics_model_cohesive.cc
  *
+ * @author Fabian Barras <fabian.barras@epfl.ch>
  * @author Mauro Corrado <mauro.corrado@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  * @author Marco Vocialta <marco.vocialta@epfl.ch>
  *
  * @date creation: Tue May 08 2012
- * @date last modification: Wed Jan 13 2016
+ * @date last modification: Wed Feb 21 2018
  *
  * @brief  Solid mechanics model for cohesive elements
  *
  * @section LICENSE
  *
- * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
- * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
- * Solides)
+ * 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
+ * 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
+ * A PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
+
 /* -------------------------------------------------------------------------- */
 #include "solid_mechanics_model_cohesive.hh"
 #include "aka_iterators.hh"
 #include "cohesive_element_inserter.hh"
 #include "element_synchronizer.hh"
 #include "facet_synchronizer.hh"
 #include "fe_engine_template.hh"
 #include "integrator_gauss.hh"
 #include "material_cohesive.hh"
 #include "parser.hh"
 #include "shape_cohesive.hh"
 
 #include "dumpable_inline_impl.hh"
 #ifdef AKANTU_USE_IOHELPER
 #include "dumper_iohelper_paraview.hh"
 #endif
 /* -------------------------------------------------------------------------- */
 #include <algorithm>
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 SolidMechanicsModelCohesive::SolidMechanicsModelCohesive(
     Mesh & mesh, UInt dim, const ID & id, const MemoryID & memory_id)
     : SolidMechanicsModel(mesh, dim, id, memory_id,
                           ModelType::_solid_mechanics_model_cohesive),
       tangents("tangents", id), facet_stress("facet_stress", id),
       facet_material("facet_material", id) {
   AKANTU_DEBUG_IN();
 
   registerFEEngineObject<MyFEEngineCohesiveType>("CohesiveFEEngine", mesh,
                                                  Model::spatial_dimension);
 
   auto && tmp_material_selector =
       std::make_shared<DefaultMaterialCohesiveSelector>(*this);
 
   tmp_material_selector->setFallback(this->material_selector);
   this->material_selector = tmp_material_selector;
 
 #if defined(AKANTU_USE_IOHELPER)
   this->mesh.registerDumper<DumperParaview>("cohesive elements", id);
   this->mesh.addDumpMeshToDumper("cohesive elements", mesh,
                                  Model::spatial_dimension, _not_ghost,
                                  _ek_cohesive);
 #endif
 
   if (this->mesh.isDistributed()) {
     /// create the distributed synchronizer for cohesive elements
     this->cohesive_synchronizer = std::make_unique<ElementSynchronizer>(
         mesh, "cohesive_distributed_synchronizer");
 
     auto & synchronizer = mesh.getElementSynchronizer();
     this->cohesive_synchronizer->split(synchronizer, [](auto && el) {
       return Mesh::getKind(el.type) == _ek_cohesive;
     });
 
     this->registerSynchronizer(*cohesive_synchronizer, _gst_material_id);
     this->registerSynchronizer(*cohesive_synchronizer, _gst_smm_stress);
     this->registerSynchronizer(*cohesive_synchronizer, _gst_smm_boundary);
   }
 
   this->inserter = std::make_unique<CohesiveElementInserter>(
       this->mesh, id + ":cohesive_element_inserter");
 
   registerFEEngineObject<MyFEEngineFacetType>(
       "FacetsFEEngine", mesh.getMeshFacets(), Model::spatial_dimension - 1);
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 SolidMechanicsModelCohesive::~SolidMechanicsModelCohesive() = default;
 
 /* -------------------------------------------------------------------------- */
 void SolidMechanicsModelCohesive::setTimeStep(Real time_step,
                                               const ID & solver_id) {
   SolidMechanicsModel::setTimeStep(time_step, solver_id);
 
 #if defined(AKANTU_USE_IOHELPER)
   this->mesh.getDumper("cohesive elements").setTimeStep(time_step);
 #endif
 }
 
 /* -------------------------------------------------------------------------- */
 void SolidMechanicsModelCohesive::initFullImpl(const ModelOptions & options) {
   AKANTU_DEBUG_IN();
 
   const auto & smmc_options =
       dynamic_cast<const SolidMechanicsModelCohesiveOptions &>(options);
 
   this->is_extrinsic = smmc_options.extrinsic;
 
   inserter->setIsExtrinsic(is_extrinsic);
 
   if (mesh.isDistributed()) {
     auto & mesh_facets = inserter->getMeshFacets();
     auto & synchronizer =
         dynamic_cast<FacetSynchronizer &>(mesh_facets.getElementSynchronizer());
     this->registerSynchronizer(synchronizer, _gst_smmc_facets);
     this->registerSynchronizer(synchronizer, _gst_smmc_facets_conn);
 
     synchronizeGhostFacetsConnectivity();
 
     /// create the facet synchronizer for extrinsic simulations
     if (is_extrinsic) {
       facet_stress_synchronizer = std::make_unique<ElementSynchronizer>(
           synchronizer, id + ":facet_stress_synchronizer");
 
       this->registerSynchronizer(*facet_stress_synchronizer,
                                  _gst_smmc_facets_stress);
     }
 
     inserter->initParallel(*cohesive_synchronizer);
   }
 
   ParserSection section;
   bool is_empty;
   std::tie(section, is_empty) = this->getParserSection();
 
   if (not is_empty) {
     auto inserter_section =
         section.getSubSections(ParserType::_cohesive_inserter);
     if (inserter_section.begin() != inserter_section.end()) {
       inserter->parseSection(*inserter_section.begin());
     }
   }
 
   SolidMechanicsModel::initFullImpl(options);
 
   AKANTU_DEBUG_OUT();
 } // namespace akantu
 
 /* -------------------------------------------------------------------------- */
 void SolidMechanicsModelCohesive::initMaterials() {
   AKANTU_DEBUG_IN();
 
   // make sure the material are instantiated
   if (!are_materials_instantiated)
     instantiateMaterials();
 
   /// find the first cohesive material
   UInt cohesive_index = UInt(-1);
 
   for (auto && material : enumerate(materials)) {
     if (dynamic_cast<MaterialCohesive *>(std::get<1>(material).get())) {
       cohesive_index = std::get<0>(material);
       break;
     }
   }
 
   if (cohesive_index == UInt(-1))
     AKANTU_EXCEPTION("No cohesive materials in the material input file");
 
   material_selector->setFallback(cohesive_index);
 
   // set the facet information in the material in case of dynamic insertion
   // to know what material to call for stress checks
   if (is_extrinsic) {
     this->initExtrinsicMaterials();
   } else {
     this->initIntrinsicMaterials();
   }
 
   AKANTU_DEBUG_OUT();
 } // namespace akantu
 
 /* -------------------------------------------------------------------------- */
 void SolidMechanicsModelCohesive::initExtrinsicMaterials() {
   const Mesh & mesh_facets = inserter->getMeshFacets();
   facet_material.initialize(
       mesh_facets, _spatial_dimension = spatial_dimension - 1,
       _with_nb_element = true,
       _default_value = material_selector->getFallbackValue());
 
   for_each_element(
       mesh_facets,
       [&](auto && element) {
         auto mat_index = (*material_selector)(element);
         auto & mat = dynamic_cast<MaterialCohesive &>(*materials[mat_index]);
         facet_material(element) = mat_index;
         mat.addFacet(element);
       },
       _spatial_dimension = spatial_dimension - 1, _ghost_type = _not_ghost);
 
   SolidMechanicsModel::initMaterials();
 
   this->initAutomaticInsertion();
 }
 
 /* -------------------------------------------------------------------------- */
 #if 0
 void SolidMechanicsModelCohesive::initIntrinsicCohesiveMaterials(
     const std::string & cohesive_surfaces) {
 
   AKANTU_DEBUG_IN();
 
 #if defined(AKANTU_PARALLEL_COHESIVE_ELEMENT)
   if (facet_synchronizer != nullptr)
     inserter->initParallel(facet_synchronizer, cohesive_element_synchronizer);
 //    inserter->initParallel(facet_synchronizer, synch_parallel);
 #endif
   std::istringstream split(cohesive_surfaces);
   std::string physname;
   while (std::getline(split, physname, ',')) {
     AKANTU_DEBUG_INFO(
         "Pre-inserting cohesive elements along facets from physical surface: "
         << physname);
     insertElementsFromMeshData(physname);
   }
 
   synchronizeInsertionData();
 
   SolidMechanicsModel::initMaterials();
 
   auto && tmp = std::make_shared<MeshDataMaterialCohesiveSelector>(*this);
   tmp->setFallback(material_selector->getFallbackValue());
   tmp->setFallback(material_selector->getFallbackSelector());
   material_selector = tmp;
 
   // UInt nb_new_elements =
   inserter->insertElements();
   // if (nb_new_elements > 0) {
   //   this->reinitializeSolver();
   // }
 
   AKANTU_DEBUG_OUT();
 }
 #endif
 /* -------------------------------------------------------------------------- */
 void SolidMechanicsModelCohesive::synchronizeInsertionData() {
   if (inserter->getMeshFacets().isDistributed()) {
     inserter->getMeshFacets().getElementSynchronizer().synchronizeOnce(
         *inserter, _gst_ce_groups);
   }
 }
 
 /* -------------------------------------------------------------------------- */
 void SolidMechanicsModelCohesive::initIntrinsicMaterials() {
   AKANTU_DEBUG_IN();
 
   SolidMechanicsModel::initMaterials();
 
   this->insertIntrinsicElements();
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 /**
  * Initialize the model,basically it  pre-compute the shapes, shapes derivatives
  * and jacobian
  */
 void SolidMechanicsModelCohesive::initModel() {
   AKANTU_DEBUG_IN();
 
   SolidMechanicsModel::initModel();
 
   /// add cohesive type connectivity
   ElementType type = _not_defined;
   for (auto && type_ghost : ghost_types) {
     for (const auto & tmp_type :
          mesh.elementTypes(spatial_dimension, type_ghost)) {
       const auto & connectivity = mesh.getConnectivity(tmp_type, type_ghost);
       if (connectivity.size() == 0)
         continue;
 
       type = tmp_type;
       auto type_facet = Mesh::getFacetType(type);
       auto type_cohesive = FEEngine::getCohesiveElementType(type_facet);
       mesh.addConnectivityType(type_cohesive, type_ghost);
     }
   }
   AKANTU_DEBUG_ASSERT(type != _not_defined, "No elements in the mesh");
 
   getFEEngine("CohesiveFEEngine").initShapeFunctions(_not_ghost);
   getFEEngine("CohesiveFEEngine").initShapeFunctions(_ghost);
 
   if (is_extrinsic) {
     getFEEngine("FacetsFEEngine").initShapeFunctions(_not_ghost);
     getFEEngine("FacetsFEEngine").initShapeFunctions(_ghost);
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void SolidMechanicsModelCohesive::insertIntrinsicElements() {
   AKANTU_DEBUG_IN();
   inserter->insertIntrinsicElements();
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void SolidMechanicsModelCohesive::initAutomaticInsertion() {
   AKANTU_DEBUG_IN();
 
   this->inserter->limitCheckFacets();
   this->updateFacetStressSynchronizer();
   this->resizeFacetStress();
 
   /// compute normals on facets
   this->computeNormals();
 
   this->initStressInterpolation();
 }
 
 /* -------------------------------------------------------------------------- */
 void SolidMechanicsModelCohesive::updateAutomaticInsertion() {
   AKANTU_DEBUG_IN();
 
   this->inserter->limitCheckFacets();
   this->updateFacetStressSynchronizer();
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void SolidMechanicsModelCohesive::initStressInterpolation() {
   Mesh & mesh_facets = inserter->getMeshFacets();
 
   /// compute quadrature points coordinates on facets
   Array<Real> & position = mesh.getNodes();
 
   ElementTypeMapArray<Real> quad_facets("quad_facets", id);
   quad_facets.initialize(mesh_facets, _nb_component = Model::spatial_dimension,
                          _spatial_dimension = Model::spatial_dimension - 1);
   // mesh_facets.initElementTypeMapArray(quad_facets, Model::spatial_dimension,
   //                                     Model::spatial_dimension - 1);
 
   getFEEngine("FacetsFEEngine")
       .interpolateOnIntegrationPoints(position, quad_facets);
 
   /// compute elements quadrature point positions and build
   /// element-facet quadrature points data structure
   ElementTypeMapArray<Real> elements_quad_facets("elements_quad_facets", id);
 
   elements_quad_facets.initialize(
       mesh, _nb_component = Model::spatial_dimension,
       _spatial_dimension = Model::spatial_dimension);
   // mesh.initElementTypeMapArray(elements_quad_facets,
   // Model::spatial_dimension,
   //                              Model::spatial_dimension);
 
   for (auto elem_gt : ghost_types) {
     for (auto & type : mesh.elementTypes(Model::spatial_dimension, elem_gt)) {
       UInt nb_element = mesh.getNbElement(type, elem_gt);
       if (nb_element == 0)
         continue;
 
       /// compute elements' quadrature points and list of facet
       /// quadrature points positions by element
       const auto & facet_to_element =
           mesh_facets.getSubelementToElement(type, elem_gt);
       auto & el_q_facet = elements_quad_facets(type, elem_gt);
 
       auto facet_type = Mesh::getFacetType(type);
       auto nb_quad_per_facet =
           getFEEngine("FacetsFEEngine").getNbIntegrationPoints(facet_type);
       auto nb_facet_per_elem = facet_to_element.getNbComponent();
 
       // small hack in the loop to skip boundary elements, they are silently
       // initialized to NaN to see if this causes problems
       el_q_facet.resize(nb_element * nb_facet_per_elem * nb_quad_per_facet,
                         std::numeric_limits<Real>::quiet_NaN());
 
       for (auto && data :
            zip(make_view(facet_to_element),
                make_view(el_q_facet, spatial_dimension, nb_quad_per_facet))) {
         const auto & global_facet = std::get<0>(data);
         auto & el_q = std::get<1>(data);
 
         if (global_facet == ElementNull)
           continue;
 
         Matrix<Real> quad_f =
             make_view(quad_facets(global_facet.type, global_facet.ghost_type),
                       spatial_dimension, nb_quad_per_facet)
                 .begin()[global_facet.element];
 
         el_q = quad_f;
 
         // for (UInt q = 0; q < nb_quad_per_facet; ++q) {
         //   for (UInt s = 0; s < Model::spatial_dimension; ++s) {
         //     el_q_facet(el * nb_facet_per_elem * nb_quad_per_facet +
         //                    f * nb_quad_per_facet + q,
         //                s) = quad_f(global_facet * nb_quad_per_facet + q,
         //                s);
         //   }
         // }
         //}
       }
     }
   }
 
   /// loop over non cohesive materials
   for (auto && material : materials) {
     if (dynamic_cast<MaterialCohesive *>(material.get()))
       continue;
     /// initialize the interpolation function
     material->initElementalFieldInterpolation(elements_quad_facets);
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void SolidMechanicsModelCohesive::assembleInternalForces() {
   AKANTU_DEBUG_IN();
 
   // f_int += f_int_cohe
   for (auto & material : this->materials) {
     try {
       auto & mat = dynamic_cast<MaterialCohesive &>(*material);
       mat.computeTraction(_not_ghost);
     } catch (std::bad_cast & bce) {
     }
   }
 
   SolidMechanicsModel::assembleInternalForces();
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void SolidMechanicsModelCohesive::computeNormals() {
   AKANTU_DEBUG_IN();
 
   Mesh & mesh_facets = this->inserter->getMeshFacets();
   this->getFEEngine("FacetsFEEngine")
       .computeNormalsOnIntegrationPoints(_not_ghost);
 
   /**
    *  @todo store tangents while computing normals instead of
    *  recomputing them as follows:
    */
   /* ------------------------------------------------------------------------ */
   UInt tangent_components =
       Model::spatial_dimension * (Model::spatial_dimension - 1);
 
   tangents.initialize(mesh_facets, _nb_component = tangent_components,
                       _spatial_dimension = Model::spatial_dimension - 1);
   // mesh_facets.initElementTypeMapArray(tangents, tangent_components,
   //                                     Model::spatial_dimension - 1);
 
   for (auto facet_type :
        mesh_facets.elementTypes(Model::spatial_dimension - 1)) {
     const Array<Real> & normals =
         this->getFEEngine("FacetsFEEngine")
             .getNormalsOnIntegrationPoints(facet_type);
 
     Array<Real> & tangents = this->tangents(facet_type);
 
     Math::compute_tangents(normals, tangents);
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void SolidMechanicsModelCohesive::interpolateStress() {
 
   ElementTypeMapArray<Real> by_elem_result("temporary_stress_by_facets", id);
 
   for (auto & material : materials) {
     auto * mat = dynamic_cast<MaterialCohesive *>(material.get());
     if (mat == nullptr)
       /// interpolate stress on facet quadrature points positions
       material->interpolateStressOnFacets(facet_stress, by_elem_result);
   }
 
 #if defined(AKANTU_DEBUG_TOOLS)
   debug::element_manager.printData(
       debug::_dm_model_cohesive, "Interpolated stresses before", facet_stress);
 #endif
 
   this->synchronize(_gst_smmc_facets_stress);
 
 #if defined(AKANTU_DEBUG_TOOLS)
   debug::element_manager.printData(debug::_dm_model_cohesive,
                                    "Interpolated stresses", facet_stress);
 #endif
 }
 
 /* -------------------------------------------------------------------------- */
 UInt SolidMechanicsModelCohesive::checkCohesiveStress() {
   AKANTU_DEBUG_IN();
 
   interpolateStress();
 
   for (auto & mat : materials) {
     auto * mat_cohesive = dynamic_cast<MaterialCohesive *>(mat.get());
     if (mat_cohesive) {
       /// check which not ghost cohesive elements are to be created
       mat_cohesive->checkInsertion();
     }
   }
 
   /// communicate data among processors
   this->synchronize(_gst_smmc_facets);
 
   /// insert cohesive elements
   UInt nb_new_elements = inserter->insertElements();
 
   // if (nb_new_elements > 0) {
   //   this->reinitializeSolver();
   // }
 
   AKANTU_DEBUG_OUT();
 
   return nb_new_elements;
 }
 
 /* -------------------------------------------------------------------------- */
 void SolidMechanicsModelCohesive::onElementsAdded(
     const Array<Element> & element_list, const NewElementsEvent & event) {
   AKANTU_DEBUG_IN();
 
   updateCohesiveSynchronizers();
 
   SolidMechanicsModel::onElementsAdded(element_list, event);
 
   if (cohesive_synchronizer != nullptr)
     cohesive_synchronizer->computeAllBufferSizes(*this);
 
   if (is_extrinsic)
     resizeFacetStress();
 
   ///  if (method != _explicit_lumped_mass) {
   ///    this->initSolver();
   ///  }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void SolidMechanicsModelCohesive::onNodesAdded(const Array<UInt> & new_nodes,
                                                const NewNodesEvent & event) {
   AKANTU_DEBUG_IN();
 
   // Array<UInt> nodes_list(nb_new_nodes);
 
   // for (UInt n = 0; n < nb_new_nodes; ++n)
   //   nodes_list(n) = doubled_nodes(n, 1);
   SolidMechanicsModel::onNodesAdded(new_nodes, event);
 
   UInt new_node, old_node;
 
   try {
     const auto & cohesive_event =
         dynamic_cast<const CohesiveNewNodesEvent &>(event);
     const auto & old_nodes = cohesive_event.getOldNodesList();
 
     auto copy = [this, &new_node, &old_node](auto & arr) {
       for (UInt s = 0; s < spatial_dimension; ++s) {
         arr(new_node, s) = arr(old_node, s);
       }
     };
 
     for (auto && pair : zip(new_nodes, old_nodes)) {
       std::tie(new_node, old_node) = pair;
 
       copy(*displacement);
       copy(*blocked_dofs);
 
       if (velocity)
         copy(*velocity);
 
       if (acceleration)
         copy(*acceleration);
 
       if (current_position)
         copy(*current_position);
 
       if (previous_displacement)
         copy(*previous_displacement);
     }
 
     // if (this->getDOFManager().hasMatrix("M")) {
     //   this->assembleMass(old_nodes);
     // }
 
     // if (this->getDOFManager().hasLumpedMatrix("M")) {
     //   this->assembleMassLumped(old_nodes);
     // }
 
   } catch (std::bad_cast &) {
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void SolidMechanicsModelCohesive::onEndSolveStep(const AnalysisMethod &) {
 
   AKANTU_DEBUG_IN();
 
   /*
    * This is required because the Cauchy stress is the stress measure that
    * is used to check the insertion of cohesive elements
    */
   for (auto & mat : materials) {
     if (mat->isFiniteDeformation())
       mat->computeAllCauchyStresses(_not_ghost);
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void SolidMechanicsModelCohesive::printself(std::ostream & stream,
                                             int indent) const {
   std::string space;
   for (Int i = 0; i < indent; i++, space += AKANTU_INDENT)
     ;
 
   stream << space << "SolidMechanicsModelCohesive [" << std::endl;
 
   SolidMechanicsModel::printself(stream, indent + 1);
 
   stream << space << "]" << std::endl;
 }
 
 /* -------------------------------------------------------------------------- */
 void SolidMechanicsModelCohesive::resizeFacetStress() {
   AKANTU_DEBUG_IN();
 
   this->facet_stress.initialize(getFEEngine("FacetsFEEngine"),
                                 _nb_component =
                                     2 * spatial_dimension * spatial_dimension,
                                 _spatial_dimension = spatial_dimension - 1);
 
   // for (auto && ghost_type : ghost_types) {
   //   for (const auto & type :
   //        mesh_facets.elementTypes(spatial_dimension - 1, ghost_type)) {
   //     UInt nb_facet = mesh_facets.getNbElement(type, ghost_type);
 
   //     UInt nb_quadrature_points = getFEEngine("FacetsFEEngine")
   //                                     .getNbIntegrationPoints(type,
   //                                     ghost_type);
 
   //     UInt new_size = nb_facet * nb_quadrature_points;
 
   //     facet_stress(type, ghost_type).resize(new_size);
   //   }
   // }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void SolidMechanicsModelCohesive::addDumpGroupFieldToDumper(
     const std::string & dumper_name, const std::string & field_id,
     const std::string & group_name, const ElementKind & element_kind,
     bool padding_flag) {
   AKANTU_DEBUG_IN();
 
   UInt spatial_dimension = Model::spatial_dimension;
   ElementKind _element_kind = element_kind;
   if (dumper_name == "cohesive elements") {
     _element_kind = _ek_cohesive;
   } else if (dumper_name == "facets") {
     spatial_dimension = Model::spatial_dimension - 1;
   }
   SolidMechanicsModel::addDumpGroupFieldToDumper(dumper_name, field_id,
                                                  group_name, spatial_dimension,
                                                  _element_kind, padding_flag);
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 
 void SolidMechanicsModelCohesive::onDump() {
   this->flattenAllRegisteredInternals(_ek_cohesive);
   SolidMechanicsModel::onDump();
 }
 
 /* -------------------------------------------------------------------------- */
 
 } // namespace akantu
diff --git a/src/model/solid_mechanics/solid_mechanics_model_cohesive/solid_mechanics_model_cohesive.hh b/src/model/solid_mechanics/solid_mechanics_model_cohesive/solid_mechanics_model_cohesive.hh
index cf149d7b2..49abaabff 100644
--- a/src/model/solid_mechanics/solid_mechanics_model_cohesive/solid_mechanics_model_cohesive.hh
+++ b/src/model/solid_mechanics/solid_mechanics_model_cohesive/solid_mechanics_model_cohesive.hh
@@ -1,320 +1,320 @@
 /**
  * @file   solid_mechanics_model_cohesive.hh
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  * @author Marco Vocialta <marco.vocialta@epfl.ch>
  *
  * @date creation: Tue May 08 2012
- * @date last modification: Mon Dec 14 2015
+ * @date last modification: Mon Feb 05 2018
  *
  * @brief  Solid mechanics model for cohesive elements
  *
  * @section LICENSE
  *
- * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
- * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
- * Solides)
+ * 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
+ * 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
+ * A PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
+
 /* -------------------------------------------------------------------------- */
 #include "cohesive_element_inserter.hh"
 #include "material_selector_cohesive.hh"
 #include "random_internal_field.hh" // included to have the specialization of
 #include "solid_mechanics_model.hh"
 #include "solid_mechanics_model_event_handler.hh"
 // ParameterTyped::operator Real()
 /* -------------------------------------------------------------------------- */
 
 #ifndef __AKANTU_SOLID_MECHANICS_MODEL_COHESIVE_HH__
 #define __AKANTU_SOLID_MECHANICS_MODEL_COHESIVE_HH__
 
 /* -------------------------------------------------------------------------- */
 namespace akantu {
 class FacetSynchronizer;
 class FacetStressSynchronizer;
 class ElementSynchronizer;
 } // namespace akantu
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 struct FacetsCohesiveIntegrationOrderFunctor {
   template <ElementType type,
             ElementType cohesive_type =
                 CohesiveFacetProperty<type>::cohesive_type>
   struct _helper {
     static constexpr int get() {
       return ElementClassProperty<cohesive_type>::polynomial_degree;
     }
   };
 
   template <ElementType type> struct _helper<type, _not_defined> {
     static constexpr int get() {
       return ElementClassProperty<type>::polynomial_degree;
     }
   };
 
   template <ElementType type> static inline constexpr int getOrder() {
     return _helper<type>::get();
   }
 };
 
 /* -------------------------------------------------------------------------- */
 /* Solid Mechanics Model for Cohesive elements                                */
 /* -------------------------------------------------------------------------- */
 class SolidMechanicsModelCohesive : public SolidMechanicsModel,
                                     public SolidMechanicsModelEventHandler {
   /* ------------------------------------------------------------------------ */
   /* Constructors/Destructors                                                 */
   /* ------------------------------------------------------------------------ */
 public:
   class NewCohesiveNodesEvent : public NewNodesEvent {
   public:
     AKANTU_GET_MACRO_NOT_CONST(OldNodesList, old_nodes, Array<UInt> &);
     AKANTU_GET_MACRO(OldNodesList, old_nodes, const Array<UInt> &);
 
   protected:
     Array<UInt> old_nodes;
   };
 
   using MyFEEngineCohesiveType =
       FEEngineTemplate<IntegratorGauss, ShapeLagrange, _ek_cohesive>;
   using MyFEEngineFacetType =
       FEEngineTemplate<IntegratorGauss, ShapeLagrange, _ek_regular,
                        FacetsCohesiveIntegrationOrderFunctor>;
 
   SolidMechanicsModelCohesive(Mesh & mesh,
                               UInt spatial_dimension = _all_dimensions,
                               const ID & id = "solid_mechanics_model_cohesive",
                               const MemoryID & memory_id = 0);
 
   ~SolidMechanicsModelCohesive() override;
 
   /* ------------------------------------------------------------------------ */
   /* Methods                                                                  */
   /* ------------------------------------------------------------------------ */
 protected:
   /// initialize the cohesive model
   void initFullImpl(const ModelOptions & options) override;
 
 public:
   /// set the value of the time step
   void setTimeStep(Real time_step, const ID & solver_id = "") override;
 
   /// assemble the residual for the explicit scheme
   void assembleInternalForces() override;
 
   /// function to perform a stress check on each facet and insert
   /// cohesive elements if needed (returns the number of new cohesive
   /// elements)
   UInt checkCohesiveStress();
 
   /// interpolate stress on facets
   void interpolateStress();
 
   /// update automatic insertion after a change in the element inserter
   void updateAutomaticInsertion();
 
   /// insert intrinsic cohesive elements
   void insertIntrinsicElements();
 
   // template <SolveConvergenceMethod cmethod, SolveConvergenceCriteria
   // criteria> bool solveStepCohesive(Real tolerance, Real & error, UInt
   // max_iteration = 100,
   //                        bool load_reduction = false,
   //                        Real tol_increase_factor = 1.0,
   //                        bool do_not_factorize = false);
 
 protected:
   /// initialize stress interpolation
   void initStressInterpolation();
 
   /// initialize the model
   void initModel() override;
 
   /// initialize cohesive material
   void initMaterials() override;
 
   /// init facet filters for cohesive materials
   void initFacetFilter();
 
   // synchronize facets physical data before insertion along physical surfaces
   void synchronizeInsertionData();
 
   /// function to print the contain of the class
   void printself(std::ostream & stream, int indent = 0) const override;
 
 private:
   /// initialize cohesive material with extrinsic insertion
   void initExtrinsicMaterials();
 
   /// initialize cohesive material with intrinsic insertion
   void initIntrinsicMaterials();
 
   /// insert cohesive elements along a given physical surface of the mesh
   void insertElementsFromMeshData(const std::string & physical_name);
 
   /// initialize completely the model for extrinsic elements
   void initAutomaticInsertion();
 
   /// compute facets' normals
   void computeNormals();
 
   /// resize facet stress
   void resizeFacetStress();
 
   /// init facets_check array
   void initFacetsCheck();
 
   /* ------------------------------------------------------------------------ */
   /* Mesh Event Handler inherited members                                     */
   /* ------------------------------------------------------------------------ */
 
 protected:
   void onNodesAdded(const Array<UInt> & nodes_list,
                     const NewNodesEvent & event) override;
   void onElementsAdded(const Array<Element> & nodes_list,
                        const NewElementsEvent & event) override;
 
   /* ------------------------------------------------------------------------ */
   /* SolidMechanicsModelEventHandler inherited members                        */
   /* ------------------------------------------------------------------------ */
 public:
   void onEndSolveStep(const AnalysisMethod & method) override;
 
   /* ------------------------------------------------------------------------ */
   /* Dumpable interface                                                       */
   /* ------------------------------------------------------------------------ */
 public:
   void onDump() override;
 
   void addDumpGroupFieldToDumper(const std::string & dumper_name,
                                  const std::string & field_id,
                                  const std::string & group_name,
                                  const ElementKind & element_kind,
                                  bool padding_flag) override;
 
 public:
   /// register the tags associated with the parallel synchronizer for
   /// cohesive elements
   // void initParallel(MeshPartition * partition,
   //                DataAccessor * data_accessor = NULL,
   //                bool extrinsic = false);
 
 protected:
   void synchronizeGhostFacetsConnectivity();
 
   void updateCohesiveSynchronizers();
   void updateFacetStressSynchronizer();
 
   /* ------------------------------------------------------------------------ */
   /* Data Accessor inherited members                                          */
   /* ------------------------------------------------------------------------ */
 public:
   UInt getNbData(const Array<Element> & elements,
                  const SynchronizationTag & tag) const override;
 
   void packData(CommunicationBuffer & buffer, const Array<Element> & elements,
                 const SynchronizationTag & tag) const override;
 
   void unpackData(CommunicationBuffer & buffer, const Array<Element> & elements,
                   const SynchronizationTag & tag) override;
 
 protected:
   UInt getNbQuadsForFacetCheck(const Array<Element> & elements) const;
 
   template <typename T>
   void packFacetStressDataHelper(const ElementTypeMapArray<T> & data_to_pack,
                                  CommunicationBuffer & buffer,
                                  const Array<Element> & elements) const;
 
   template <typename T>
   void unpackFacetStressDataHelper(ElementTypeMapArray<T> & data_to_unpack,
                                    CommunicationBuffer & buffer,
                                    const Array<Element> & elements) const;
 
   template <typename T, bool pack_helper>
   void packUnpackFacetStressDataHelper(ElementTypeMapArray<T> & data_to_pack,
                                        CommunicationBuffer & buffer,
                                        const Array<Element> & element) const;
 
   /* ------------------------------------------------------------------------ */
   /* Accessors                                                                */
   /* ------------------------------------------------------------------------ */
 public:
   /// get facet mesh
   AKANTU_GET_MACRO(MeshFacets, mesh.getMeshFacets(), const Mesh &);
 
   /// get stress on facets vector
   AKANTU_GET_MACRO_BY_ELEMENT_TYPE_CONST(StressOnFacets, facet_stress, Real);
 
   /// get facet material
   AKANTU_GET_MACRO_BY_ELEMENT_TYPE(FacetMaterial, facet_material, UInt);
 
   /// get facet material
   AKANTU_GET_MACRO_BY_ELEMENT_TYPE_CONST(FacetMaterial, facet_material, UInt);
 
   /// get facet material
   AKANTU_GET_MACRO(FacetMaterial, facet_material,
                    const ElementTypeMapArray<UInt> &);
 
   /// @todo THIS HAS TO BE CHANGED
   AKANTU_GET_MACRO_BY_ELEMENT_TYPE_CONST(Tangents, tangents, Real);
 
   /// get element inserter
   AKANTU_GET_MACRO_NOT_CONST(ElementInserter, *inserter,
                              CohesiveElementInserter &);
 
   /// get is_extrinsic boolean
   AKANTU_GET_MACRO(IsExtrinsic, is_extrinsic, bool);
 
   /// get cohesive elements synchronizer
   AKANTU_GET_MACRO(CohesiveSynchronizer, *cohesive_synchronizer,
                    const ElementSynchronizer &);
 
   /* ------------------------------------------------------------------------ */
   /* Class Members                                                            */
   /* ------------------------------------------------------------------------ */
 private:
   /// @todo store tangents when normals are computed:
   ElementTypeMapArray<Real> tangents;
 
   /// stress on facets on the two sides by quadrature point
   ElementTypeMapArray<Real> facet_stress;
 
   /// material to use if a cohesive element is created on a facet
   ElementTypeMapArray<UInt> facet_material;
 
   bool is_extrinsic;
 
   /// cohesive element inserter
   std::unique_ptr<CohesiveElementInserter> inserter;
 
   /// facet stress synchronizer
   std::unique_ptr<ElementSynchronizer> facet_stress_synchronizer;
 
   /// cohesive elements synchronizer
   std::unique_ptr<ElementSynchronizer> cohesive_synchronizer;
 
   /// global connectivity
   ElementTypeMapArray<UInt> * global_connectivity;
 };
 
 } // namespace akantu
 
 #include "solid_mechanics_model_cohesive_inline_impl.cc"
 
 #endif /* __AKANTU_SOLID_MECHANICS_MODEL_COHESIVE_HH__ */
diff --git a/src/model/solid_mechanics/solid_mechanics_model_cohesive/solid_mechanics_model_cohesive_inline_impl.cc b/src/model/solid_mechanics/solid_mechanics_model_cohesive/solid_mechanics_model_cohesive_inline_impl.cc
index bf3a809e3..43403bf43 100644
--- a/src/model/solid_mechanics/solid_mechanics_model_cohesive/solid_mechanics_model_cohesive_inline_impl.cc
+++ b/src/model/solid_mechanics/solid_mechanics_model_cohesive/solid_mechanics_model_cohesive_inline_impl.cc
@@ -1,305 +1,306 @@
 /**
  * @file   solid_mechanics_model_cohesive_inline_impl.cc
  *
  * @author Mauro Corrado <mauro.corrado@epfl.ch>
+ * @author Nicolas Richart <nicolas.richart@epfl.ch>
  * @author Marco Vocialta <marco.vocialta@epfl.ch>
  *
  * @date creation: Fri Jan 18 2013
- * @date last modification: Thu Jan 14 2016
+ * @date last modification: Tue Feb 20 2018
  *
  * @brief  Implementation of inline functions for the Cohesive element model
  *
  * @section LICENSE
  *
- * Copyright  (©)  2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de Lausanne)
+ * 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
+ * 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
+ * A PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 #include "material_cohesive.hh"
 /* -------------------------------------------------------------------------- */
 #include <algorithm>
 /* -------------------------------------------------------------------------- */
 
 #ifndef __AKANTU_SOLID_MECHANICS_MODEL_COHESIVE_INLINE_IMPL_CC__
 #define __AKANTU_SOLID_MECHANICS_MODEL_COHESIVE_INLINE_IMPL_CC__
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 // template <SolveConvergenceMethod cmethod, SolveConvergenceCriteria criteria>
 // bool SolidMechanicsModelCohesive::solveStepCohesive(
 //     Real tolerance, Real & error, UInt max_iteration, bool load_reduction,
 //     Real tol_increase_factor, bool do_not_factorize) {
 
 // // EventManager::sendEvent(
 // //     SolidMechanicsModelEvent::BeforeSolveStepEvent(method));
 // // this->implicitPred();
 
 // // bool insertion_new_element = true;
 // // bool converged = false;
 // // Array<Real> * displacement_tmp = NULL;
 // // Array<Real> * velocity_tmp = NULL;
 // // Array<Real> * acceleration_tmp = NULL;
 // // StaticCommunicator & comm = StaticCommunicator::getStaticCommunicator();
 // // Int prank = comm.whoAmI();
 
 // // /// Loop for the insertion of new cohesive elements
 // // while (insertion_new_element) {
 
 // //   if (is_extrinsic) {
 // //     /**
 // //      * If in extrinsic the solution of the previous incremental step
 // //      * is saved in temporary arrays created for displacements,
 // //      * velocities and accelerations. Such arrays are used to find
 // //      * the solution with the Newton-Raphson scheme (this is done by
 // //      * pointing the pointer "displacement" to displacement_tmp). In
 // //      * this way, inside the array "displacement" is kept the
 // //      * solution of the previous incremental step, and in
 // //      * "displacement_tmp" is saved the current solution.
 // //      */
 
 // //     if (!displacement_tmp)
 // //       displacement_tmp = new Array<Real>(0, spatial_dimension);
 
 // //     displacement_tmp->copy(*(this->displacement));
 
 // //     if (!velocity_tmp)
 // //       velocity_tmp = new Array<Real>(0, spatial_dimension);
 
 // //     velocity_tmp->copy(*(this->velocity));
 
 // //     if (!acceleration_tmp) {
 // //       acceleration_tmp = new Array<Real>(0, spatial_dimension);
 // //     }
 
 // //     acceleration_tmp->copy(*(this->acceleration));
 
 // //     std::swap(displacement, displacement_tmp);
 // //     std::swap(velocity, velocity_tmp);
 // //     std::swap(acceleration, acceleration_tmp);
 // //   }
 
 // //   this->updateResidual();
 
 // //   AKANTU_DEBUG_ASSERT(stiffness_matrix != NULL,
 // //                       "You should first initialize the implicit solver and
 // "
 // //                       "assemble the stiffness matrix");
 
 // //   bool need_factorize = !do_not_factorize;
 
 // //   if (method == _implicit_dynamic) {
 // //     AKANTU_DEBUG_ASSERT(mass_matrix != NULL, "You should first initialize
 // "
 // //                                              "the implicit solver and "
 // //                                              "assemble the mass matrix");
 // //   }
 
 // //   switch (cmethod) {
 // //   case _scm_newton_raphson_tangent:
 // //   case _scm_newton_raphson_tangent_not_computed:
 // //     break;
 // //   case _scm_newton_raphson_tangent_modified:
 // //     this->assembleStiffnessMatrix();
 // //     break;
 // //   default:
 // //     AKANTU_ERROR("The resolution method "
 // //                        << cmethod << " has not been implemented!");
 // //   }
 
 // //   UInt iter = 0;
 // //   converged = false;
 // //   error = 0.;
 // //   if (criteria == _scc_residual) {
 // //     converged = this->testConvergence<criteria>(tolerance, error);
 // //     if (converged)
 // //       return converged;
 // //   }
 
 // //   /// Loop to solve the nonlinear system
 // //   do {
 // //     if (cmethod == _scm_newton_raphson_tangent)
 // //       this->assembleStiffnessMatrix();
 
 // //     solve<NewmarkBeta::_displacement_corrector>(*increment, 1.,
 // //                                                 need_factorize);
 
 // //     this->implicitCorr();
 
 // //     this->updateResidual();
 
 // //     converged = this->testConvergence<criteria>(tolerance, error);
 
 // //     iter++;
 // //     AKANTU_DEBUG_INFO("[" << criteria << "] Convergence iteration "
 // //                           << std::setw(std::log10(max_iteration)) << iter
 // //                           << ": error " << error
 // //                           << (converged ? " < " : " > ") << tolerance);
 
 // //     switch (cmethod) {
 // //     case _scm_newton_raphson_tangent:
 // //       need_factorize = true;
 // //       break;
 // //     case _scm_newton_raphson_tangent_not_computed:
 // //     case _scm_newton_raphson_tangent_modified:
 // //       need_factorize = false;
 // //       break;
 // //     default:
 // //       AKANTU_ERROR("The resolution method "
 // //                          << cmethod << " has not been implemented!");
 // //     }
 
 // //   } while (!converged && iter < max_iteration);
 
 // //   /**
 // //    * This is to save the obtained result and proceed with the
 // //    * simulation even if the error is higher than the pre-fixed
 // //    * tolerance. This is done only after loading reduction
 // //    * (load_reduction = true).
 // //    */
 // //   //    if (load_reduction && (error < tolerance * tol_increase_factor))
 // //   //    converged = true;
 // //   if ((error < tolerance * tol_increase_factor))
 // //     converged = true;
 
 // //   if (converged) {
 
 // //   } else if (iter == max_iteration) {
 // //     if (prank == 0) {
 // //       AKANTU_DEBUG_WARNING(
 // //           "[" << criteria << "] Convergence not reached after "
 // //               << std::setw(std::log10(max_iteration)) << iter << "
 // iteration"
 // //               << (iter == 1 ? "" : "s") << "!" << std::endl);
 // //     }
 // //   }
 
 // //   if (is_extrinsic) {
 // //     /**
 // //      * If is extrinsic the pointer "displacement" is moved back to
 // //      * the array displacement. In this way, the array displacement is
 // //      * correctly resized during the checkCohesiveStress function (in
 // //      * case new cohesive elements are added). This is possible
 // //      * because the procedure called by checkCohesiveStress does not
 // //      * use the displacement field (the correct one is now stored in
 // //      * displacement_tmp), but directly the stress field that is
 // //      * already computed.
 // //      */
 // //     Array<Real> * tmp_swap;
 
 // //     tmp_swap = displacement_tmp;
 // //     displacement_tmp = this->displacement;
 // //     this->displacement = tmp_swap;
 
 // //     tmp_swap = velocity_tmp;
 // //     velocity_tmp = this->velocity;
 // //     this->velocity = tmp_swap;
 
 // //     tmp_swap = acceleration_tmp;
 // //     acceleration_tmp = this->acceleration;
 // //     this->acceleration = tmp_swap;
 
 // //     /// If convergence is reached, call checkCohesiveStress in order
 // //     /// to check if cohesive elements have to be introduced
 // //     if (converged) {
 
 // //       UInt new_cohesive_elements = checkCohesiveStress();
 
 // //       if (new_cohesive_elements == 0) {
 // //         insertion_new_element = false;
 // //       } else {
 // //         insertion_new_element = true;
 // //       }
 // //     }
 // //   }
 
 // //   if (!converged && load_reduction)
 // //     insertion_new_element = false;
 
 // //   /**
 // //    * If convergence is not reached, there is the possibility to
 // //    * return back to the main file and reduce the load. Before doing
 // //    * this, a pre-fixed value as to be defined for the parameter
 // //    * delta_max of the cohesive elements introduced in the current
 // //    * incremental step. This is done by calling the function
 // //    * checkDeltaMax.
 // //    */
 // //   if (!converged) {
 // //     insertion_new_element = false;
 
 // //     for (UInt m = 0; m < materials.size(); ++m) {
 // //       try {
 // //         MaterialCohesive & mat =
 // //             dynamic_cast<MaterialCohesive &>(*materials[m]);
 // //         mat.checkDeltaMax(_not_ghost);
 // //       } catch (std::bad_cast &) {
 // //       }
 // //     }
 // //   }
 
 // // } // end loop for the insertion of new cohesive elements
 
 // // /**
 // //  * When the solution to the current incremental step is computed (no
 // //  * more cohesive elements have to be introduced), call the function
 // //  * to compute the energies.
 // //  */
 // // if ((is_extrinsic && converged)) {
 
 // //   for (UInt m = 0; m < materials.size(); ++m) {
 // //     try {
 // //       MaterialCohesive & mat =
 // //           dynamic_cast<MaterialCohesive &>(*materials[m]);
 // //       mat.computeEnergies();
 // //     } catch (std::bad_cast & bce) {
 // //     }
 // //   }
 
 // //   EventManager::sendEvent(
 // //       SolidMechanicsModelEvent::AfterSolveStepEvent(method));
 
 // //   /**
 // //    * The function resetVariables is necessary to correctly set a
 // //    * variable that permit to decrease locally the penalty parameter
 // //    * for compression.
 // //    */
 // //   for (UInt m = 0; m < materials.size(); ++m) {
 // //     try {
 // //       MaterialCohesive & mat =
 // //           dynamic_cast<MaterialCohesive &>(*materials[m]);
 // //       mat.resetVariables(_not_ghost);
 // //     } catch (std::bad_cast &) {
 // //     }
 // //   }
 
 // //   /// The correct solution is saved
 // //   this->displacement->copy(*displacement_tmp);
 // //   this->velocity->copy(*velocity_tmp);
 // //   this->acceleration->copy(*acceleration_tmp);
 // // }
 
 // // delete displacement_tmp;
 // // delete velocity_tmp;
 // // delete acceleration_tmp;
 
 // // return insertion_new_element;
 //}
 
 } // akantu
 
 #endif /* __AKANTU_SOLID_MECHANICS_MODEL_COHESIVE_INLINE_IMPL_CC__ */
diff --git a/src/model/solid_mechanics/solid_mechanics_model_cohesive/solid_mechanics_model_cohesive_parallel.cc b/src/model/solid_mechanics/solid_mechanics_model_cohesive/solid_mechanics_model_cohesive_parallel.cc
index da79875ba..7735e5e55 100644
--- a/src/model/solid_mechanics/solid_mechanics_model_cohesive/solid_mechanics_model_cohesive_parallel.cc
+++ b/src/model/solid_mechanics/solid_mechanics_model_cohesive/solid_mechanics_model_cohesive_parallel.cc
@@ -1,488 +1,505 @@
 /**
  * @file   solid_mechanics_model_cohesive_parallel.cc
  *
+ * @author Nicolas Richart <nicolas.richart@epfl.ch>
  * @author Marco Vocialta <marco.vocialta@epfl.ch>
  *
+ * @date creation: Wed Nov 05 2014
+ * @date last modification: Tue Feb 20 2018
  *
  * @brief  Functions for parallel cohesive elements
  *
  * @section LICENSE
  *
- * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * Copyright (©) 2015-2018 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
+ * Akantu is free  software: you can redistribute it and/or  modify it under the
+ * terms  of the  GNU Lesser  General Public  License as published by  the Free
+ * Software Foundation, either version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * Akantu is  distributed in the  hope that it  will be useful, but  WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
+ * details.
+ *
+ * You should  have received  a copy  of the GNU  Lesser General  Public License
+ * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
+ *
  */
+
 /* -------------------------------------------------------------------------- */
 #include "communicator.hh"
 #include "element_synchronizer.hh"
 #include "material_cohesive.hh"
 #include "solid_mechanics_model_cohesive.hh"
 #include "solid_mechanics_model_tmpl.hh"
 /* -------------------------------------------------------------------------- */
 #include <type_traits>
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 void SolidMechanicsModelCohesive::synchronizeGhostFacetsConnectivity() {
   AKANTU_DEBUG_IN();
 
   const Communicator & comm = mesh.getCommunicator();
   Int psize = comm.getNbProc();
 
   if (psize > 1) {
     /// get global connectivity for not ghost facets
     global_connectivity =
         new ElementTypeMapArray<UInt>("global_connectivity", id);
 
     auto & mesh_facets = inserter->getMeshFacets();
 
     global_connectivity->initialize(
         mesh_facets, _spatial_dimension = spatial_dimension - 1,
         _with_nb_element = true, _with_nb_nodes_per_element = true,
         _element_kind = _ek_regular);
 
     mesh_facets.getGlobalConnectivity(*global_connectivity);
 
     /// communicate
     synchronize(_gst_smmc_facets_conn);
 
     /// flip facets
     MeshUtils::flipFacets(mesh_facets, *global_connectivity, _ghost);
 
     delete global_connectivity;
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void SolidMechanicsModelCohesive::updateCohesiveSynchronizers() {
   /// update synchronizers if needed
 
   if (not mesh.isDistributed())
     return;
 
   auto & mesh_facets = inserter->getMeshFacets();
   auto & facet_synchronizer = mesh_facets.getElementSynchronizer();
   const auto & cfacet_synchronizer = facet_synchronizer;
 
   // update the cohesive element synchronizer
   cohesive_synchronizer->updateSchemes([&](auto && scheme, auto && proc,
                                            auto && direction) {
     auto & facet_scheme =
         cfacet_synchronizer.getCommunications().getScheme(proc, direction);
 
     for (auto && facet : facet_scheme) {
       const auto & connected_elements = mesh_facets.getElementToSubelement(
           facet.type,
           facet.ghost_type)(facet.element); // slow access here
       const auto & cohesive_element = connected_elements[1];
 
       if (cohesive_element == ElementNull or
           cohesive_element.kind() == _ek_cohesive)
         continue;
 
       auto && cohesive_type = FEEngine::getCohesiveElementType(facet.type);
       auto old_nb_cohesive_elements =
           mesh.getNbElement(cohesive_type, facet.ghost_type);
       old_nb_cohesive_elements -=
           mesh_facets
               .getData<UInt>("facet_to_double", facet.type, facet.ghost_type)
               .size();
 
       if (cohesive_element.element >= old_nb_cohesive_elements) {
         scheme.push_back(cohesive_element);
       }
     }
   });
 
   const auto & comm = mesh.getCommunicator();
   auto && my_rank = comm.whoAmI();
 
   // update the facet stress synchronizer
   if (facet_stress_synchronizer)
     facet_stress_synchronizer->updateSchemes([&](auto && scheme, auto && proc,
                                                  auto && /*direction*/) {
       auto it_element = scheme.begin();
       for (auto && element : scheme) {
         auto && facet_check = inserter->getCheckFacets(
             element.type, element.ghost_type)(element.element); // slow access
                                                                 // here
 
         if (facet_check) {
           auto && connected_elements = mesh_facets.getElementToSubelement(
               element.type, element.ghost_type)(element.element); // slow access
                                                                   // here
           auto && rank_left = facet_synchronizer.getRank(connected_elements[0]);
           auto && rank_right =
               facet_synchronizer.getRank(connected_elements[1]);
 
           // keep element if the element is still a boundary element between two
           // processors
           if ((rank_left == Int(proc) and rank_right == my_rank) or
               (rank_left == my_rank and rank_right == Int(proc))) {
             *it_element = element;
             ++it_element;
           }
         }
       }
       scheme.resize(it_element - scheme.begin());
     });
 }
 
 /* -------------------------------------------------------------------------- */
 void SolidMechanicsModelCohesive::updateFacetStressSynchronizer() {
   if (facet_stress_synchronizer != nullptr) {
     const auto & rank_to_element =
         mesh.getElementSynchronizer().getElementToRank();
     const auto & facet_checks = inserter->getCheckFacets();
     const auto & mesh_facets = inserter->getMeshFacets();
     const auto & element_to_facet = mesh_facets.getElementToSubelement();
     UInt rank = mesh.getCommunicator().whoAmI();
 
     facet_stress_synchronizer->updateSchemes(
         [&](auto & scheme, auto & proc, auto & /*direction*/) {
           UInt el = 0;
           for (auto && element : scheme) {
             if (not facet_checks(element))
               continue;
 
             const auto & next_el = element_to_facet(element);
             UInt rank_left = rank_to_element(next_el[0]);
             UInt rank_right = rank_to_element(next_el[1]);
 
             if ((rank_left == rank and rank_right == proc) or
                 (rank_left == proc and rank_right == rank)) {
               scheme[el] = element;
               ++el;
             }
           }
           scheme.resize(el);
         });
   }
 }
 
 /* -------------------------------------------------------------------------- */
 template <typename T>
 void SolidMechanicsModelCohesive::packFacetStressDataHelper(
     const ElementTypeMapArray<T> & data_to_pack, CommunicationBuffer & buffer,
     const Array<Element> & elements) const {
   packUnpackFacetStressDataHelper<T, true>(
       const_cast<ElementTypeMapArray<T> &>(data_to_pack), buffer, elements);
 }
 
 /* -------------------------------------------------------------------------- */
 template <typename T>
 void SolidMechanicsModelCohesive::unpackFacetStressDataHelper(
     ElementTypeMapArray<T> & data_to_unpack, CommunicationBuffer & buffer,
     const Array<Element> & elements) const {
   packUnpackFacetStressDataHelper<T, false>(data_to_unpack, buffer, elements);
 }
 
 /* -------------------------------------------------------------------------- */
 template <typename T, bool pack_helper>
 void SolidMechanicsModelCohesive::packUnpackFacetStressDataHelper(
     ElementTypeMapArray<T> & data_to_pack, CommunicationBuffer & buffer,
     const Array<Element> & elements) const {
   ElementType current_element_type = _not_defined;
   GhostType current_ghost_type = _casper;
   UInt nb_quad_per_elem = 0;
   UInt sp2 = spatial_dimension * spatial_dimension;
   UInt nb_component = sp2 * 2;
   bool element_rank = false;
   Mesh & mesh_facets = inserter->getMeshFacets();
 
   Array<T> * vect = nullptr;
   Array<std::vector<Element>> * element_to_facet = nullptr;
 
   auto & fe_engine = this->getFEEngine("FacetsFEEngine");
   for (auto && el : elements) {
     if (el.type == _not_defined)
       AKANTU_EXCEPTION(
           "packUnpackFacetStressDataHelper called with wrong inputs");
 
     if (el.type != current_element_type ||
         el.ghost_type != current_ghost_type) {
       current_element_type = el.type;
       current_ghost_type = el.ghost_type;
       vect = &data_to_pack(el.type, el.ghost_type);
 
       element_to_facet =
           &(mesh_facets.getElementToSubelement(el.type, el.ghost_type));
 
       nb_quad_per_elem =
           fe_engine.getNbIntegrationPoints(el.type, el.ghost_type);
     }
 
     if (pack_helper)
       element_rank =
           (*element_to_facet)(el.element)[0].ghost_type != _not_ghost;
     else
       element_rank =
           (*element_to_facet)(el.element)[0].ghost_type == _not_ghost;
 
     for (UInt q = 0; q < nb_quad_per_elem; ++q) {
       Vector<T> data(vect->storage() +
                          (el.element * nb_quad_per_elem + q) * nb_component +
                          element_rank * sp2,
                      sp2);
 
       if (pack_helper)
         buffer << data;
       else
         buffer >> data;
     }
   }
 }
 
 /* -------------------------------------------------------------------------- */
 UInt SolidMechanicsModelCohesive::getNbQuadsForFacetCheck(
     const Array<Element> & elements) const {
   UInt nb_quads = 0;
   UInt nb_quad_per_facet = 0;
 
   ElementType current_element_type = _not_defined;
   GhostType current_ghost_type = _casper;
   auto & fe_engine = this->getFEEngine("FacetsFEEngine");
   for (auto & el : elements) {
     if (el.type != current_element_type ||
         el.ghost_type != current_ghost_type) {
       current_element_type = el.type;
       current_ghost_type = el.ghost_type;
 
       nb_quad_per_facet =
           fe_engine.getNbIntegrationPoints(el.type, el.ghost_type);
     }
 
     nb_quads += nb_quad_per_facet;
   }
 
   return nb_quads;
 }
 
 /* -------------------------------------------------------------------------- */
 UInt SolidMechanicsModelCohesive::getNbData(
     const Array<Element> & elements, const SynchronizationTag & tag) const {
   AKANTU_DEBUG_IN();
 
   UInt size = 0;
   if (elements.size() == 0)
     return 0;
 
   /// regular element case
   if (elements(0).kind() == _ek_regular) {
 
     switch (tag) {
     case _gst_smmc_facets: {
       size += elements.size() * sizeof(bool);
       break;
     }
     case _gst_smmc_facets_conn: {
       UInt nb_nodes = Mesh::getNbNodesPerElementList(elements);
       size += nb_nodes * sizeof(UInt);
       break;
     }
     case _gst_smmc_facets_stress: {
       UInt nb_quads = getNbQuadsForFacetCheck(elements);
       size += nb_quads * spatial_dimension * spatial_dimension * sizeof(Real);
       break;
     }
     case _gst_material_id: {
       for (auto && element : elements) {
         if (Mesh::getSpatialDimension(element.type) == (spatial_dimension - 1))
           size += sizeof(UInt);
       }
 
       size += SolidMechanicsModel::getNbData(elements, tag);
       break;
     }
 
     default: { size += SolidMechanicsModel::getNbData(elements, tag); }
     }
   }
   /// cohesive element case
   else if (elements(0).kind() == _ek_cohesive) {
 
     switch (tag) {
     case _gst_material_id: {
       size += elements.size() * sizeof(UInt);
       break;
     }
     case _gst_smm_boundary: {
       UInt nb_nodes_per_element = 0;
 
       for (auto && el : elements) {
         nb_nodes_per_element += Mesh::getNbNodesPerElement(el.type);
       }
 
       // force, displacement, boundary
       size += nb_nodes_per_element * spatial_dimension *
               (2 * sizeof(Real) + sizeof(bool));
       break;
     }
     default:
       break;
     }
 
     if (tag != _gst_material_id && tag != _gst_smmc_facets) {
       splitByMaterial(elements, [&](auto && mat, auto && elements) {
         size += mat.getNbData(elements, tag);
       });
     }
   }
 
   AKANTU_DEBUG_OUT();
   return size;
 }
 
 /* -------------------------------------------------------------------------- */
 void SolidMechanicsModelCohesive::packData(
     CommunicationBuffer & buffer, const Array<Element> & elements,
     const SynchronizationTag & tag) const {
   AKANTU_DEBUG_IN();
 
   if (elements.size() == 0)
     return;
 
   if (elements(0).kind() == _ek_regular) {
     switch (tag) {
     case _gst_smmc_facets: {
       packElementalDataHelper(inserter->getInsertionFacetsByElement(), buffer,
                               elements, false, getFEEngine());
       break;
     }
     case _gst_smmc_facets_conn: {
       packElementalDataHelper(*global_connectivity, buffer, elements, false,
                               getFEEngine());
       break;
     }
     case _gst_smmc_facets_stress: {
       packFacetStressDataHelper(facet_stress, buffer, elements);
       break;
     }
     case _gst_material_id: {
       for (auto && element : elements) {
         if (Mesh::getSpatialDimension(element.type) != (spatial_dimension - 1))
           continue;
         buffer << material_index(element);
       }
 
       SolidMechanicsModel::packData(buffer, elements, tag);
       break;
     }
     default: { SolidMechanicsModel::packData(buffer, elements, tag); }
     }
 
     AKANTU_DEBUG_OUT();
     return;
   }
 
   if (elements(0).kind() == _ek_cohesive) {
     switch (tag) {
     case _gst_material_id: {
       packElementalDataHelper(material_index, buffer, elements, false,
                               getFEEngine("CohesiveFEEngine"));
       break;
     }
     case _gst_smm_boundary: {
       packNodalDataHelper(*internal_force, buffer, elements, mesh);
       packNodalDataHelper(*velocity, buffer, elements, mesh);
       packNodalDataHelper(*blocked_dofs, buffer, elements, mesh);
       break;
     }
     default: {}
     }
 
     if (tag != _gst_material_id && tag != _gst_smmc_facets) {
       splitByMaterial(elements, [&](auto && mat, auto && elements) {
         mat.packData(buffer, elements, tag);
       });
     }
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void SolidMechanicsModelCohesive::unpackData(CommunicationBuffer & buffer,
                                              const Array<Element> & elements,
                                              const SynchronizationTag & tag) {
   AKANTU_DEBUG_IN();
 
   if (elements.size() == 0)
     return;
 
   if (elements(0).kind() == _ek_regular) {
     switch (tag) {
     case _gst_smmc_facets: {
       unpackElementalDataHelper(inserter->getInsertionFacetsByElement(), buffer,
                                 elements, false, getFEEngine());
       break;
     }
     case _gst_smmc_facets_conn: {
       unpackElementalDataHelper(*global_connectivity, buffer, elements, false,
                                 getFEEngine());
       break;
     }
     case _gst_smmc_facets_stress: {
       unpackFacetStressDataHelper(facet_stress, buffer, elements);
       break;
     }
     case _gst_material_id: {
       for (auto && element : elements) {
         if (Mesh::getSpatialDimension(element.type) != (spatial_dimension - 1))
           continue;
 
         UInt recv_mat_index;
         buffer >> recv_mat_index;
         UInt & mat_index = material_index(element);
         if (mat_index != UInt(-1))
           continue;
 
         // add ghosts element to the correct material
         mat_index = recv_mat_index;
         auto & mat = dynamic_cast<MaterialCohesive &>(*materials[mat_index]);
         mat.addFacet(element);
         facet_material(element) = recv_mat_index;
       }
       SolidMechanicsModel::unpackData(buffer, elements, tag);
       break;
     }
     default: { SolidMechanicsModel::unpackData(buffer, elements, tag); }
     }
 
     AKANTU_DEBUG_OUT();
     return;
   }
 
   if (elements(0).kind() == _ek_cohesive) {
     switch (tag) {
     case _gst_material_id: {
       unpackElementalDataHelper(material_index, buffer, elements, false,
                                 getFEEngine("CohesiveFEEngine"));
       break;
     }
     case _gst_smm_boundary: {
       unpackNodalDataHelper(*internal_force, buffer, elements, mesh);
       unpackNodalDataHelper(*velocity, buffer, elements, mesh);
       unpackNodalDataHelper(*blocked_dofs, buffer, elements, mesh);
       break;
     }
     default: {}
     }
 
     if (tag != _gst_material_id && tag != _gst_smmc_facets) {
       splitByMaterial(elements, [&](auto && mat, auto && elements) {
         mat.unpackData(buffer, elements, tag);
       });
     }
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 
 } // namespace akantu
diff --git a/src/model/solid_mechanics/solid_mechanics_model_embedded_interface/embedded_interface_intersector.cc b/src/model/solid_mechanics/solid_mechanics_model_embedded_interface/embedded_interface_intersector.cc
index f961c7a7c..a422e9b0d 100644
--- a/src/model/solid_mechanics/solid_mechanics_model_embedded_interface/embedded_interface_intersector.cc
+++ b/src/model/solid_mechanics/solid_mechanics_model_embedded_interface/embedded_interface_intersector.cc
@@ -1,179 +1,179 @@
 /**
  * @file   embedded_interface_intersector.cc
  *
  * @author Lucas Frerot <lucas.frerot@epfl.ch>
  *
  * @date creation: Fri May 01 2015
- * @date last modification: Mon Jan 04 2016
+ * @date last modification: Tue Feb 20 2018
  *
  * @brief  Class that loads the interface from mesh and computes intersections
  *
  * @section LICENSE
  *
- * Copyright (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne) Laboratory
- * (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * Copyright (©) 2015-2018 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
- * terms  of the  GNU Lesser  General Public  License as  published by  the Free
+ * 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
+ * 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 "embedded_interface_intersector.hh"
 #include "mesh_segment_intersector.hh"
 
 /// Helper macro for types in the mesh. Creates an intersector and computes
 /// intersection queries
 #define INTERFACE_INTERSECTOR_CASE(dim, type)                                  \
   do {                                                                         \
     MeshSegmentIntersector<dim, type> intersector(this->mesh, interface_mesh); \
     name_to_primitives_it = name_to_primitives_map.begin();                    \
     for (; name_to_primitives_it != name_to_primitives_end;                    \
          ++name_to_primitives_it) {                                            \
       intersector.setPhysicalName(name_to_primitives_it->first);               \
       intersector.buildResultFromQueryList(name_to_primitives_it->second);     \
     }                                                                          \
   } while (0)
 
 #define INTERFACE_INTERSECTOR_CASE_2D(type) INTERFACE_INTERSECTOR_CASE(2, type)
 #define INTERFACE_INTERSECTOR_CASE_3D(type) INTERFACE_INTERSECTOR_CASE(3, type)
 
 namespace akantu {
 
 EmbeddedInterfaceIntersector::EmbeddedInterfaceIntersector(
     Mesh & mesh, const Mesh & primitive_mesh)
     : MeshGeomAbstract(mesh),
       interface_mesh(mesh.getSpatialDimension(), "interface_mesh"),
       primitive_mesh(primitive_mesh) {
   // Initiating mesh connectivity and data
   interface_mesh.addConnectivityType(_segment_2, _not_ghost);
   interface_mesh.addConnectivityType(_segment_2, _ghost);
   interface_mesh.registerData<Element>("associated_element")
       .alloc(0, 1, _segment_2);
   interface_mesh.registerData<std::string>("physical_names")
       .alloc(0, 1, _segment_2);
 }
 
 EmbeddedInterfaceIntersector::~EmbeddedInterfaceIntersector() {}
 
 void EmbeddedInterfaceIntersector::constructData(GhostType /*ghost_type*/) {
   AKANTU_DEBUG_IN();
 
   const UInt dim = this->mesh.getSpatialDimension();
 
   if (dim == 1)
     AKANTU_ERROR(
         "No embedded model in 1D. Deactivate intersection initialization");
 
   Array<std::string> * physical_names = NULL;
 
   try {
     physical_names = &const_cast<Array<std::string> &>(
         this->primitive_mesh.getData<std::string>("physical_names",
                                                   _segment_2));
   } catch (debug::Exception & e) {
     AKANTU_ERROR("You must define physical names to reinforcements in "
                  "order to use the embedded model");
     throw e;
   }
 
   const UInt nb_nodes_per_element = Mesh::getNbNodesPerElement(_segment_2);
   Array<UInt>::const_vector_iterator connectivity =
       primitive_mesh.getConnectivity(_segment_2).begin(nb_nodes_per_element);
 
   Array<std::string>::scalar_iterator names_it = physical_names->begin(),
                                       names_end = physical_names->end();
 
   std::map<std::string, std::list<K::Segment_3>> name_to_primitives_map;
 
   // Loop over the physical names and register segment lists in
   // name_to_primitives_map
   for (; names_it != names_end; ++names_it) {
     UInt element_id = names_it - physical_names->begin();
     const Vector<UInt> el_connectivity = connectivity[element_id];
 
     K::Segment_3 segment = this->createSegment(el_connectivity);
     name_to_primitives_map[*names_it].push_back(segment);
   }
 
   // Loop over the background types of the mesh
   Mesh::type_iterator type_it = this->mesh.firstType(dim, _not_ghost),
                       type_end = this->mesh.lastType(dim, _not_ghost);
 
   std::map<std::string, std::list<K::Segment_3>>::iterator
       name_to_primitives_it,
       name_to_primitives_end = name_to_primitives_map.end();
 
   for (; type_it != type_end; ++type_it) {
     // Used in AKANTU_BOOST_ELEMENT_SWITCH
     ElementType type = *type_it;
 
     AKANTU_DEBUG_INFO("Computing intersections with background element type "
                       << type);
 
     switch (dim) {
     case 1:
       break;
 
     case 2:
       // Compute intersections for supported 2D elements
       AKANTU_BOOST_ELEMENT_SWITCH(INTERFACE_INTERSECTOR_CASE_2D,
                                   (_triangle_3)(_triangle_6));
       break;
 
     case 3:
       // Compute intersections for supported 3D elements
       AKANTU_BOOST_ELEMENT_SWITCH(INTERFACE_INTERSECTOR_CASE_3D,
                                   (_tetrahedron_4));
       break;
     }
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 K::Segment_3
 EmbeddedInterfaceIntersector::createSegment(const Vector<UInt> & connectivity) {
   AKANTU_DEBUG_IN();
 
   K::Point_3 *source = NULL, *target = NULL;
   const Array<Real> & nodes = this->primitive_mesh.getNodes();
 
   if (this->mesh.getSpatialDimension() == 2) {
     source = new K::Point_3(nodes(connectivity(0), 0),
                             nodes(connectivity(0), 1), 0.);
     target = new K::Point_3(nodes(connectivity(1), 0),
                             nodes(connectivity(1), 1), 0.);
   } else if (this->mesh.getSpatialDimension() == 3) {
     source =
         new K::Point_3(nodes(connectivity(0), 0), nodes(connectivity(0), 1),
                        nodes(connectivity(0), 2));
     target =
         new K::Point_3(nodes(connectivity(1), 0), nodes(connectivity(1), 1),
                        nodes(connectivity(1), 2));
   }
 
   K::Segment_3 segment(*source, *target);
   delete source;
   delete target;
 
   AKANTU_DEBUG_OUT();
   return segment;
 }
 
 } // namespace akantu
 
 #undef INTERFACE_INTERSECTOR_CASE
 #undef INTERFACE_INTERSECTOR_CASE_2D
 #undef INTERFACE_INTERSECTOR_CASE_3D
diff --git a/src/model/solid_mechanics/solid_mechanics_model_embedded_interface/embedded_interface_intersector.hh b/src/model/solid_mechanics/solid_mechanics_model_embedded_interface/embedded_interface_intersector.hh
index 03bf41fb0..9552e178b 100644
--- a/src/model/solid_mechanics/solid_mechanics_model_embedded_interface/embedded_interface_intersector.hh
+++ b/src/model/solid_mechanics/solid_mechanics_model_embedded_interface/embedded_interface_intersector.hh
@@ -1,98 +1,98 @@
 /**
  * @file   embedded_interface_intersector.hh
  *
  * @author Lucas Frerot <lucas.frerot@epfl.ch>
  *
  * @date creation: Fri May 01 2015
- * @date last modification: Mon Dec 14 2015
+ * @date last modification: Wed Jan 31 2018
  *
  * @brief  Class that loads the interface from mesh and computes intersections
  *
  * @section LICENSE
  *
- * Copyright (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne) Laboratory
- * (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * Copyright (©) 2015-2018 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
- * terms  of the  GNU Lesser  General Public  License as  published by  the Free
+ * 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
+ * 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_EMBEDDED_INTERFACE_INTERSECTOR_HH__
 #define __AKANTU_EMBEDDED_INTERFACE_INTERSECTOR_HH__
 
 #include "aka_common.hh"
 #include "mesh_geom_abstract.hh"
 #include "mesh_geom_common.hh"
 #include "mesh_segment_intersector.hh"
 
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 
 namespace {
   using K = cgal::Cartesian;
 }
 
 /**
  * @brief Computes the intersections of the reinforcements defined in the
  * primitive mesh
  *
  * The purpose of this class is to look for reinforcements in the primitive
  * mesh, which
  * should be defined by physical groups with the same names as the reinforcement
  * materials
  * in the model.
  *
  * It then constructs the CGAL primitives from the elements of those
  * reinforcements
  * and computes the intersections with the background mesh, to create an
  * `interface_mesh`,
  * which is in turn used by the EmbeddedInterfaceModel.
  *
  * @see MeshSegmentIntersector, MeshGeomAbstract
  * @see EmbeddedInterfaceModel
  */
 class EmbeddedInterfaceIntersector : public MeshGeomAbstract {
 
 public:
   /// Construct from mesh and a reinforcement mesh
   explicit EmbeddedInterfaceIntersector(Mesh & mesh,
                                         const Mesh & primitive_mesh);
 
   /// Destructor
   virtual ~EmbeddedInterfaceIntersector();
 
 public:
   /// Generate the interface mesh
   virtual void constructData(GhostType ghost_type = _not_ghost);
 
   /// Create a segment with an element connectivity
   K::Segment_3 createSegment(const Vector<UInt> & connectivity);
 
   /// Getter for interface mesh
   AKANTU_GET_MACRO_NOT_CONST(InterfaceMesh, interface_mesh, Mesh &);
 
 protected:
   /// Resulting mesh of intersection
   Mesh interface_mesh;
 
   /// Mesh used for primitive construction
   const Mesh & primitive_mesh;
 };
 
 } // akantu
 
 #endif // __AKANTU_EMBEDDED_INTERFACE_INTERSECTOR_HH__
diff --git a/src/model/solid_mechanics/solid_mechanics_model_embedded_interface/embedded_interface_model.cc b/src/model/solid_mechanics/solid_mechanics_model_embedded_interface/embedded_interface_model.cc
index c951110c8..4c260b2df 100644
--- a/src/model/solid_mechanics/solid_mechanics_model_embedded_interface/embedded_interface_model.cc
+++ b/src/model/solid_mechanics/solid_mechanics_model_embedded_interface/embedded_interface_model.cc
@@ -1,173 +1,173 @@
 /**
  * @file   embedded_interface_model.cc
  *
  * @author Lucas Frerot <lucas.frerot@epfl.ch>
  *
  * @date creation: Fri Mar 13 2015
- * @date last modification: Mon Dec 14 2015
+ * @date last modification: Wed Feb 14 2018
  *
  * @brief  Model of Solid Mechanics with embedded interfaces
  *
  * @section LICENSE
  *
- * Copyright (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne) Laboratory
- * (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * Copyright (©) 2015-2018 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
- * terms  of the  GNU Lesser  General Public  License as  published by  the Free
+ * 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
+ * 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 "embedded_interface_model.hh"
 #include "integrator_gauss.hh"
 #include "material_elastic.hh"
 #include "material_reinforcement.hh"
 #include "mesh_iterators.hh"
 #include "shape_lagrange.hh"
 
 #ifdef AKANTU_USE_IOHELPER
 #include "dumpable_inline_impl.hh"
 #include "dumper_iohelper_paraview.hh"
 #endif
 
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 EmbeddedInterfaceModel::EmbeddedInterfaceModel(Mesh & mesh,
                                                Mesh & primitive_mesh,
                                                UInt spatial_dimension,
                                                const ID & id,
                                                const MemoryID & memory_id)
     : SolidMechanicsModel(mesh, spatial_dimension, id, memory_id),
       intersector(mesh, primitive_mesh), interface_mesh(nullptr),
       primitive_mesh(primitive_mesh), interface_material_selector(nullptr) {
   this->model_type = ModelType::_embedded_model;
 
   // This pointer should be deleted by ~SolidMechanicsModel()
   auto mat_sel_pointer =
       std::make_shared<MeshDataMaterialSelector<std::string>>("physical_names",
                                                               *this);
 
   this->setMaterialSelector(mat_sel_pointer);
 
   interface_mesh = &(intersector.getInterfaceMesh());
 
   // Create 1D FEEngine on the interface mesh
   registerFEEngineObject<MyFEEngineType>("EmbeddedInterfaceFEEngine",
                                          *interface_mesh, 1);
 
   // Registering allocator for material reinforcement
   MaterialFactory::getInstance().registerAllocator(
       "reinforcement",
       [&](UInt dim, const ID & constitutive, SolidMechanicsModel &,
           const ID & id) -> std::unique_ptr<Material> {
         if (constitutive == "elastic") {
           using mat = MaterialElastic<1>;
           switch (dim) {
           case 2:
             return std::make_unique<MaterialReinforcement<mat, 2>>(*this, id);
           case 3:
             return std::make_unique<MaterialReinforcement<mat, 3>>(*this, id);
           default:
             AKANTU_EXCEPTION("Dimension 1 is invalid for reinforcements");
           }
         } else {
           AKANTU_EXCEPTION("Reinforcement type" << constitutive
                                                 << " is not recognized");
         }
       });
 }
 
 /* -------------------------------------------------------------------------- */
 EmbeddedInterfaceModel::~EmbeddedInterfaceModel() {
   delete interface_material_selector;
 }
 
 /* -------------------------------------------------------------------------- */
 void EmbeddedInterfaceModel::initFullImpl(const ModelOptions & options) {
   const auto & eim_options =
       dynamic_cast<const EmbeddedInterfaceModelOptions &>(options);
 
   // Do no initialize interface_mesh if told so
   if (eim_options.has_intersections)
     intersector.constructData();
 
   SolidMechanicsModel::initFullImpl(options);
 
 #if defined(AKANTU_USE_IOHELPER)
   this->mesh.registerDumper<DumperParaview>("reinforcement", id);
   this->mesh.addDumpMeshToDumper("reinforcement", *interface_mesh, 1,
                                  _not_ghost, _ek_regular);
 #endif
 }
 
 void EmbeddedInterfaceModel::initModel() {
   // Initialize interface FEEngine
   SolidMechanicsModel::initModel();
   FEEngine & engine = getFEEngine("EmbeddedInterfaceFEEngine");
   engine.initShapeFunctions(_not_ghost);
   engine.initShapeFunctions(_ghost);
 }
 
 /* -------------------------------------------------------------------------- */
 void EmbeddedInterfaceModel::assignMaterialToElements(
     const ElementTypeMapArray<UInt> * filter) {
   delete interface_material_selector;
   interface_material_selector =
       new InterfaceMeshDataMaterialSelector<std::string>("physical_names",
                                                          *this);
 
   for_each_element(getInterfaceMesh(),
                    [&](auto && element) {
                      auto mat_index = (*interface_material_selector)(element);
                      // material_index(element) = mat_index;
                      materials[mat_index]->addElement(element);
                      // this->material_local_numbering(element) = index;
                    },
                    _element_filter = filter, _spatial_dimension = 1);
 
   SolidMechanicsModel::assignMaterialToElements(filter);
 }
 
 /* -------------------------------------------------------------------------- */
 void EmbeddedInterfaceModel::addDumpGroupFieldToDumper(
     const std::string & dumper_name, const std::string & field_id,
     const std::string & group_name, const ElementKind & element_kind,
     bool padding_flag) {
 #ifdef AKANTU_USE_IOHELPER
   dumper::Field * field = NULL;
 
   // If dumper is reinforcement, create a 1D elemental field
   if (dumper_name == "reinforcement")
     field = this->createElementalField(field_id, group_name, padding_flag, 1,
                                        element_kind);
   else {
     try {
       SolidMechanicsModel::addDumpGroupFieldToDumper(
           dumper_name, field_id, group_name, element_kind, padding_flag);
     } catch (...) {
     }
   }
   if (field) {
     DumperIOHelper & dumper = mesh.getGroupDumper(dumper_name, group_name);
     Model::addDumpGroupFieldToDumper(field_id, field, dumper);
   }
 
 #endif
 }
 
 } // akantu
diff --git a/src/model/solid_mechanics/solid_mechanics_model_embedded_interface/embedded_interface_model.hh b/src/model/solid_mechanics/solid_mechanics_model_embedded_interface/embedded_interface_model.hh
index 836661b31..42db35d34 100644
--- a/src/model/solid_mechanics/solid_mechanics_model_embedded_interface/embedded_interface_model.hh
+++ b/src/model/solid_mechanics/solid_mechanics_model_embedded_interface/embedded_interface_model.hh
@@ -1,154 +1,153 @@
 /**
  * @file   embedded_interface_model.hh
  *
  * @author Lucas Frerot <lucas.frerot@epfl.ch>
  *
  * @date creation: Fri Jun 18 2010
- * @date last modification: Mon Dec 14 2015
+ * @date last modification: Wed Jan 31 2018
  *
  * @brief  Model of Solid Mechanics with embedded interfaces
  *
  * @section LICENSE
  *
- * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
- * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
- * Solides)
+ * 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
+ * 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
+ * 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_EMBEDDED_INTERFACE_MODEL_HH__
 #define __AKANTU_EMBEDDED_INTERFACE_MODEL_HH__
 
 #include "aka_common.hh"
 
 #include "mesh.hh"
 #include "solid_mechanics_model.hh"
 
 #include "embedded_interface_intersector.hh"
 
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 
 /**
  * @brief Solid mechanics model using the embedded model.
  *
  * This SolidMechanicsModel subclass implements the embedded model,
  * a method used to represent 1D elements in a finite elements model
  * (eg. reinforcements in concrete).
  *
  * In addition to the SolidMechanicsModel properties, this model has
  * a mesh of the 1D elements embedded in the model, and an instance of the
  * EmbeddedInterfaceIntersector class for the computation of the intersections
  * of the
  * 1D elements with the background (bulk) mesh.
  *
  * @see MaterialReinforcement
  */
 class EmbeddedInterfaceModel : public SolidMechanicsModel {
 
   using MyFEEngineType = SolidMechanicsModel::MyFEEngineType;
 
   /* ------------------------------------------------------------------------ */
   /* Constructors/Destructors                                                 */
   /* ------------------------------------------------------------------------ */
 public:
   /**
    * @brief Constructor
    *
    * @param mesh main mesh (concrete)
    * @param primitive_mesh mesh of the embedded reinforcement
    */
   EmbeddedInterfaceModel(Mesh & mesh, Mesh & primitive_mesh,
                          UInt spatial_dimension = _all_dimensions,
                          const ID & id = "embedded_interface_model",
                          const MemoryID & memory_id = 0);
 
   /// Destructor
   ~EmbeddedInterfaceModel() override;
 
   /* ------------------------------------------------------------------------ */
   /* Methods                                                                  */
   /* ------------------------------------------------------------------------ */
 public:
   /// Initialise the model
   void initFullImpl(
       const ModelOptions & options = EmbeddedInterfaceModelOptions()) override;
 
   /// Initialise the materials
   void
   assignMaterialToElements(const ElementTypeMapArray<UInt> * filter) override;
 
   /// Initialize the embedded shape functions
   void initModel() override;
 
   /// Allows filtering of dump fields which need to be dumpes on interface mesh
   void addDumpGroupFieldToDumper(const std::string & dumper_name,
                                  const std::string & field_id,
                                  const std::string & group_name,
                                  const ElementKind & element_kind,
                                  bool padding_flag) override;
 
   // virtual ElementTypeMap<UInt> getInternalDataPerElem(const std::string &
   // field_name,
   //                                                     const ElementKind &
   //                                                     kind);
   /* ------------------------------------------------------------------------ */
   /* Accessors                                                                */
   /* ------------------------------------------------------------------------ */
 public:
   /// Get interface mesh
   AKANTU_GET_MACRO(InterfaceMesh, *interface_mesh, Mesh &);
 
   /// Get associated elements
   AKANTU_GET_MACRO_BY_ELEMENT_TYPE(
       InterfaceAssociatedElements,
       interface_mesh->getData<Element>("associated_element"), Element);
 
   /* ------------------------------------------------------------------------ */
   /* Class Members                                                            */
   /* ------------------------------------------------------------------------ */
 protected:
   /// Intersector object to build the interface mesh
   EmbeddedInterfaceIntersector intersector;
 
   /// Interface mesh (weak reference)
   Mesh * interface_mesh;
 
   /// Mesh used to create the CGAL primitives for intersections
   Mesh & primitive_mesh;
 
   /// Material selector for interface
   MaterialSelector * interface_material_selector;
 };
 
 /// Material selector based on mesh data for interface elements
 template <typename T>
 class InterfaceMeshDataMaterialSelector
     : public ElementDataMaterialSelector<T> {
 public:
   InterfaceMeshDataMaterialSelector(const std::string & name,
                                     const EmbeddedInterfaceModel & model,
                                     UInt first_index = 1)
       : ElementDataMaterialSelector<T>(
             model.getInterfaceMesh().getData<T>(name), model, first_index) {}
 };
 
 } // akantu
 
 #endif // __AKANTU_EMBEDDED_INTERFACE_MODEL_HH__
diff --git a/src/model/solid_mechanics/solid_mechanics_model_event_handler.hh b/src/model/solid_mechanics/solid_mechanics_model_event_handler.hh
index ff5d8538c..6f1214c96 100644
--- a/src/model/solid_mechanics/solid_mechanics_model_event_handler.hh
+++ b/src/model/solid_mechanics/solid_mechanics_model_event_handler.hh
@@ -1,127 +1,126 @@
 /**
  * @file   solid_mechanics_model_event_handler.hh
  *
  * @author Daniel Pino Muñoz <daniel.pinomunoz@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Fri Jun 18 2010
- * @date last modification: Fri Dec 18 2015
+ * @date last modification: Wed Nov 08 2017
  *
  * @brief  EventHandler implementation for SolidMechanicsEvents
  *
  * @section LICENSE
  *
- * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
- * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
- * Solides)
+ * 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
+ * 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
+ * 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_SOLID_MECHANICS_MODEL_EVENT_HANDLER_HH__
 #define __AKANTU_SOLID_MECHANICS_MODEL_EVENT_HANDLER_HH__
 
 namespace akantu {
 
 /// akantu::SolidMechanicsModelEvent is the base event for model
 namespace SolidMechanicsModelEvent {
   struct BeforeSolveStepEvent {
     BeforeSolveStepEvent(AnalysisMethod & method) : method(method) {}
     AnalysisMethod method;
   };
   struct AfterSolveStepEvent {
     AfterSolveStepEvent(AnalysisMethod & method) : method(method) {}
     AnalysisMethod method;
   };
   struct BeforeDumpEvent {
     BeforeDumpEvent() = default;
   };
   struct BeginningOfDamageIterationEvent {
     BeginningOfDamageIterationEvent() = default;
   };
   struct AfterDamageEvent {
     AfterDamageEvent() = default;
   };
 }
 
 /// akantu::SolidMechanicsModelEvent
 class SolidMechanicsModelEventHandler {
   /* ------------------------------------------------------------------------ */
   /* Constructors/Destructors                                                 */
   /* ------------------------------------------------------------------------ */
 public:
   virtual ~SolidMechanicsModelEventHandler() = default;
 
   /* ------------------------------------------------------------------------ */
   /* Methods                                                                  */
   /* ------------------------------------------------------------------------ */
 protected:
   /// Send what is before the solve step to the beginning of solve step through
   /// EventManager
   inline void
   sendEvent(const SolidMechanicsModelEvent::BeforeSolveStepEvent & event) {
     onBeginningSolveStep(event.method);
   }
   /// Send what is after the solve step to the end of solve step through
   /// EventManager
   inline void
   sendEvent(const SolidMechanicsModelEvent::AfterSolveStepEvent & event) {
     onEndSolveStep(event.method);
   }
   /// Send what is before dump to current dump through EventManager
   inline void
   sendEvent(__attribute__((unused))
             const SolidMechanicsModelEvent::BeforeDumpEvent & event) {
     onDump();
   }
   /// Send what is at the beginning of damage iteration to Damage iteration
   /// through EventManager
   inline void sendEvent(
       __attribute__((unused))
       const SolidMechanicsModelEvent::BeginningOfDamageIterationEvent & event) {
     onDamageIteration();
   }
   /// Send what is after damage for the damage update through EventManager
   inline void
   sendEvent(__attribute__((unused))
             const SolidMechanicsModelEvent::AfterDamageEvent & event) {
     onDamageUpdate();
   }
 
   template <class EventHandler> friend class EventHandlerManager;
 
   /* ------------------------------------------------------------------------ */
   /* Interface                                                                */
   /* ------------------------------------------------------------------------ */
 public:
   /// function to implement to react on akantu::BeforeSolveStepEvent
   virtual void onBeginningSolveStep(__attribute__((unused))
                                     const AnalysisMethod & method) {}
   /// function to implement to react on akantu::AfterSolveStepEvent
   virtual void onEndSolveStep(__attribute__((unused))
                               const AnalysisMethod & method) {}
   /// function to implement to react on akantu::BeforeDumpEvent
   virtual void onDump() {}
   /// function to implement to react on akantu::BeginningOfDamageIterationEvent
   virtual void onDamageIteration() {}
   /// function to implement to react on akantu::AfterDamageEvent
   virtual void onDamageUpdate() {}
 };
 
 } // akantu
 
 #endif /* __AKANTU_SOLID_MECHANICS_MODEL_EVENT_HANDLER_HH__ */
diff --git a/src/model/solid_mechanics/solid_mechanics_model_inline_impl.cc b/src/model/solid_mechanics/solid_mechanics_model_inline_impl.cc
index 322a480da..1ae4784cc 100644
--- a/src/model/solid_mechanics/solid_mechanics_model_inline_impl.cc
+++ b/src/model/solid_mechanics/solid_mechanics_model_inline_impl.cc
@@ -1,102 +1,102 @@
 /**
  * @file   solid_mechanics_model_inline_impl.cc
  *
  * @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
  * @author Daniel Pino Muñoz <daniel.pinomunoz@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Wed Aug 04 2010
- * @date last modification: Wed Nov 18 2015
+ * @date last modification: Tue Dec 05 2017
  *
  * @brief  Implementation of the inline functions of the SolidMechanicsModel
  * class
  *
  * @section LICENSE
  *
- * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
- * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
- * Solides)
+ * 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
+ * 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
+ * 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_named_argument.hh"
 #include "material_selector.hh"
 #include "material_selector_tmpl.hh"
 #include "solid_mechanics_model.hh"
 /* -------------------------------------------------------------------------- */
 
 #ifndef __AKANTU_SOLID_MECHANICS_MODEL_INLINE_IMPL_CC__
 #define __AKANTU_SOLID_MECHANICS_MODEL_INLINE_IMPL_CC__
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 inline Material & SolidMechanicsModel::getMaterial(UInt mat_index) {
   AKANTU_DEBUG_IN();
   AKANTU_DEBUG_ASSERT(mat_index < materials.size(),
                       "The model " << id << " has no material no "
                                    << mat_index);
   AKANTU_DEBUG_OUT();
   return *materials[mat_index];
 }
 
 /* -------------------------------------------------------------------------- */
 inline const Material & SolidMechanicsModel::getMaterial(UInt mat_index) const {
   AKANTU_DEBUG_IN();
   AKANTU_DEBUG_ASSERT(mat_index < materials.size(),
                       "The model " << id << " has no material no "
                                    << mat_index);
   AKANTU_DEBUG_OUT();
   return *materials[mat_index];
 }
 
 /* -------------------------------------------------------------------------- */
 inline Material & SolidMechanicsModel::getMaterial(const std::string & name) {
   AKANTU_DEBUG_IN();
   std::map<std::string, UInt>::const_iterator it =
       materials_names_to_id.find(name);
   AKANTU_DEBUG_ASSERT(it != materials_names_to_id.end(),
                       "The model " << id << " has no material named " << name);
   AKANTU_DEBUG_OUT();
   return *materials[it->second];
 }
 
 /* -------------------------------------------------------------------------- */
 inline UInt
 SolidMechanicsModel::getMaterialIndex(const std::string & name) const {
   AKANTU_DEBUG_IN();
   auto it = materials_names_to_id.find(name);
   AKANTU_DEBUG_ASSERT(it != materials_names_to_id.end(),
                       "The model " << id << " has no material named " << name);
   AKANTU_DEBUG_OUT();
   return it->second;
 }
 
 /* -------------------------------------------------------------------------- */
 inline const Material &
 SolidMechanicsModel::getMaterial(const std::string & name) const {
   AKANTU_DEBUG_IN();
   auto it = materials_names_to_id.find(name);
   AKANTU_DEBUG_ASSERT(it != materials_names_to_id.end(),
                       "The model " << id << " has no material named " << name);
   AKANTU_DEBUG_OUT();
   return *materials[it->second];
 }
 
 /* -------------------------------------------------------------------------- */
 } // namespace akantu
 
 #endif /* __AKANTU_SOLID_MECHANICS_MODEL_INLINE_IMPL_CC__ */
diff --git a/src/model/solid_mechanics/solid_mechanics_model_io.cc b/src/model/solid_mechanics/solid_mechanics_model_io.cc
index 71d9ff521..ba29a79ca 100644
--- a/src/model/solid_mechanics/solid_mechanics_model_io.cc
+++ b/src/model/solid_mechanics/solid_mechanics_model_io.cc
@@ -1,324 +1,326 @@
 /**
  * @file   solid_mechanics_model_io.cc
  *
- * @author Nicolas Richart <nicolas.richart@epfl.ch>
  * @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
  * @author David Simon Kammer <david.kammer@epfl.ch>
+ * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
- * @date creation  Fri Jul 07 2017
+ * @date creation: Sun Jul 09 2017
+ * @date last modification: Sun Dec 03 2017
  *
- * @brief Dumpable part of the SolidMechnicsModel
+ * @brief  Dumpable part of the SolidMechnicsModel
  *
  * @section LICENSE
  *
- * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * 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
+ * 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
+ * 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.cc"
 
 #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,
                                      const 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,
                                             const 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,
                                      const ElementKind & kind,
                                      const GhostType ghost_type) {
   std::pair<std::string, ElementKind> key(field_name, kind);
   if (this->registered_internals.count(key) == 0) {
     this->registered_internals[key] =
         new ElementTypeMapArray<Real>(field_name, this->id, this->memory_id);
   }
 
   ElementTypeMapArray<Real> * internal_flat = this->registered_internals[key];
 
   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.clear();
       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(
     const 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
 dumper::Field * SolidMechanicsModel::createElementalField(
     const std::string & field_name, const std::string & group_name,
     bool padding_flag, const UInt & spatial_dimension,
     const ElementKind & kind) {
 
   dumper::Field * field = nullptr;
 
   if (field_name == "partitions")
     field = mesh.createElementalField<UInt, dumper::ElementPartitionField>(
         mesh.getConnectivities(), group_name, spatial_dimension, kind);
   else if (field_name == "material_index")
     field = mesh.createElementalField<UInt, Vector, dumper::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) {
       ElementTypeMap<UInt> nb_data_per_elem =
           this->getInternalDataPerElem(field_name_copy, kind);
       ElementTypeMapArray<Real> & internal_flat =
           this->flattenInternal(field_name_copy, kind);
       field = mesh.createElementalField<Real, dumper::InternalMaterialField>(
           internal_flat, group_name, spatial_dimension, kind, nb_data_per_elem);
       if (field_name == "strain") {
         auto * foo = new dumper::ComputeStrain<false>(*this);
         field = dumper::FieldComputeProxy::createFieldCompute(field, *foo);
       } else if (field_name == "Von Mises stress") {
         auto * foo = new dumper::ComputeVonMisesStress(*this);
         field = dumper::FieldComputeProxy::createFieldCompute(field, *foo);
       } else if (field_name == "Green strain") {
         auto * foo = new dumper::ComputeStrain<true>(*this);
         field = dumper::FieldComputeProxy::createFieldCompute(field, *foo);
       } else if (field_name == "principal strain") {
         auto * foo = new dumper::ComputePrincipalStrain<false>(*this);
         field = dumper::FieldComputeProxy::createFieldCompute(field, *foo);
       } else if (field_name == "principal Green strain") {
         auto * foo = new dumper::ComputePrincipalStrain<true>(*this);
         field = dumper::FieldComputeProxy::createFieldCompute(field, *foo);
       }
 
       // treat the paddings
       if (padding_flag) {
         if (field_name == "stress") {
           if (spatial_dimension == 2) {
             auto * foo = new dumper::StressPadder<2>(*this);
             field = dumper::FieldComputeProxy::createFieldCompute(field, *foo);
           }
         } else if (field_name == "strain" || field_name == "Green strain") {
           if (spatial_dimension == 2) {
             auto * foo = new dumper::StrainPadder<2>(*this);
             field = dumper::FieldComputeProxy::createFieldCompute(field, *foo);
           }
         }
       }
 
       // homogenize the field
       dumper::ComputeFunctorInterface * foo =
           dumper::HomogenizerProxy::createHomogenizer(*field);
 
       field = dumper::FieldComputeProxy::createFieldCompute(field, *foo);
     }
   }
   return field;
 }
 
 /* -------------------------------------------------------------------------- */
 dumper::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;
   real_nodal_fields["mass"] = this->mass;
   real_nodal_fields["velocity"] = this->velocity;
   real_nodal_fields["acceleration"] = this->acceleration;
   real_nodal_fields["external_force"] = this->external_force;
   real_nodal_fields["internal_force"] = this->internal_force;
   real_nodal_fields["increment"] = this->displacement_increment;
 
   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'");
   }
 
   dumper::Field * field = nullptr;
   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;
 }
 
 /* -------------------------------------------------------------------------- */
 dumper::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;
 
   dumper::Field * field = nullptr;
   field = mesh.createNodalField(uint_nodal_fields[field_name], group_name);
   return field;
 }
 /* -------------------------------------------------------------------------- */
 #else
 /* -------------------------------------------------------------------------- */
 dumper::Field * SolidMechanicsModel::createElementalField(const std::string &,
                                                           const std::string &,
                                                           bool, const UInt &,
                                                           const ElementKind &) {
   return nullptr;
 }
 /* --------------------------------------------------------------------------
  */
 dumper::Field * SolidMechanicsModel::createNodalFieldReal(const std::string &,
                                                           const std::string &,
                                                           bool) {
   return nullptr;
 }
 
 /* --------------------------------------------------------------------------
  */
 dumper::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
diff --git a/src/model/solid_mechanics/solid_mechanics_model_mass.cc b/src/model/solid_mechanics/solid_mechanics_model_mass.cc
index e0f5392a6..66ddd6ac6 100644
--- a/src/model/solid_mechanics/solid_mechanics_model_mass.cc
+++ b/src/model/solid_mechanics/solid_mechanics_model_mass.cc
@@ -1,159 +1,158 @@
 /**
  * @file   solid_mechanics_model_mass.cc
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Tue Oct 05 2010
- * @date last modification: Fri Oct 16 2015
+ * @date last modification: Wed Nov 08 2017
  *
  * @brief  function handling mass computation
  *
  * @section LICENSE
  *
- * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
- * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
- * Solides)
+ * 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
+ * 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
+ * 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 "integrator_gauss.hh"
 #include "material.hh"
 #include "model_solver.hh"
 #include "shape_lagrange.hh"
 #include "solid_mechanics_model.hh"
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 
 class ComputeRhoFunctor {
 public:
   explicit ComputeRhoFunctor(const SolidMechanicsModel & model)
       : model(model){};
 
   void operator()(Matrix<Real> & rho, const Element & element) const {
     const Array<UInt> & mat_indexes =
         model.getMaterialByElement(element.type, element.ghost_type);
     Real mat_rho =
         model.getMaterial(mat_indexes(element.element)).getParam("rho");
     rho.set(mat_rho);
   }
 
 private:
   const SolidMechanicsModel & model;
 };
 
 /* -------------------------------------------------------------------------- */
 void SolidMechanicsModel::assembleMassLumped() {
   AKANTU_DEBUG_IN();
 
   if (not need_to_reassemble_lumped_mass)
     return;
 
   UInt nb_nodes = mesh.getNbNodes();
 
   if (this->mass == nullptr) {
     std::stringstream sstr_mass;
     sstr_mass << id << ":mass";
     mass =
         &(alloc<Real>(sstr_mass.str(), nb_nodes, Model::spatial_dimension, 0));
   } else {
     mass->clear();
   }
 
   if (!this->getDOFManager().hasLumpedMatrix("M")) {
     this->getDOFManager().getNewLumpedMatrix("M");
   }
 
   this->getDOFManager().clearLumpedMatrix("M");
 
   assembleMassLumped(_not_ghost);
   assembleMassLumped(_ghost);
 
   this->getDOFManager().getLumpedMatrixPerDOFs("displacement", "M",
                                                *(this->mass));
 
 /// for not connected nodes put mass to one in order to avoid
 #if !defined(AKANTU_NDEBUG)
   bool has_unconnected_nodes = false;
   auto mass_it = mass->begin_reinterpret(mass->size() * mass->getNbComponent());
   auto mass_end = mass->end_reinterpret(mass->size() * mass->getNbComponent());
   for (; mass_it != mass_end; ++mass_it) {
     if (std::abs(*mass_it) < std::numeric_limits<Real>::epsilon() ||
         Math::isnan(*mass_it)) {
       has_unconnected_nodes = true;
       break;
     }
   }
 
   if (has_unconnected_nodes)
     AKANTU_DEBUG_WARNING("There are nodes that seem to not be connected to any "
                          "elements, beware that they have lumped mass of 0.");
 #endif
 
   this->synchronize(_gst_smm_mass);
 
   need_to_reassemble_lumped_mass = false;
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void SolidMechanicsModel::assembleMass() {
   AKANTU_DEBUG_IN();
 
   if (not need_to_reassemble_mass)
     return;
 
   this->getDOFManager().clearMatrix("M");
   assembleMass(_not_ghost);
 
   need_to_reassemble_mass = false;
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void SolidMechanicsModel::assembleMassLumped(GhostType ghost_type) {
   AKANTU_DEBUG_IN();
 
   auto & fem = getFEEngineClass<MyFEEngineType>();
   ComputeRhoFunctor compute_rho(*this);
 
   for (auto type : mesh.elementTypes(Model::spatial_dimension, ghost_type)) {
     fem.assembleFieldLumped(compute_rho, "M", "displacement",
                             this->getDOFManager(), type, ghost_type);
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void SolidMechanicsModel::assembleMass(GhostType ghost_type) {
   AKANTU_DEBUG_IN();
 
   auto & fem = getFEEngineClass<MyFEEngineType>();
   ComputeRhoFunctor compute_rho(*this);
 
   for (auto type : mesh.elementTypes(Model::spatial_dimension, ghost_type)) {
     fem.assembleFieldMatrix(compute_rho, "M", "displacement",
                             this->getDOFManager(), type, ghost_type);
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 } // namespace akantu
diff --git a/src/model/solid_mechanics/solid_mechanics_model_material.cc b/src/model/solid_mechanics/solid_mechanics_model_material.cc
index 74ce922a9..d21eb55e3 100644
--- a/src/model/solid_mechanics/solid_mechanics_model_material.cc
+++ b/src/model/solid_mechanics/solid_mechanics_model_material.cc
@@ -1,254 +1,253 @@
 /**
  * @file   solid_mechanics_model_material.cc
  *
  * @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Fri Nov 26 2010
- * @date last modification: Mon Nov 16 2015
+ * @date last modification: Tue Feb 20 2018
  *
  * @brief  instatiation of materials
  *
  * @section LICENSE
  *
- * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
- * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
- * Solides)
+ * 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
+ * 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
+ * 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_factory.hh"
 #include "aka_math.hh"
 #include "material_non_local.hh"
 #include "mesh_iterators.hh"
 #include "non_local_manager.hh"
 #include "solid_mechanics_model.hh"
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 Material &
 SolidMechanicsModel::registerNewMaterial(const ParserSection & section) {
   std::string mat_name;
   std::string mat_type = section.getName();
   std::string opt_param = section.getOption();
 
   try {
     std::string tmp = section.getParameter("name");
     mat_name = tmp; /** this can seam 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 material of type \'"
                  << mat_type
                  << "\' in the input file has been defined without a name!");
   }
   Material & mat = this->registerNewMaterial(mat_name, mat_type, opt_param);
 
   mat.parseSection(section);
 
   return mat;
 }
 
 /* -------------------------------------------------------------------------- */
 Material & SolidMechanicsModel::registerNewMaterial(const ID & mat_name,
                                                     const ID & mat_type,
                                                     const ID & opt_param) {
   AKANTU_DEBUG_ASSERT(materials_names_to_id.find(mat_name) ==
                           materials_names_to_id.end(),
                       "A material with this name '"
                           << mat_name << "' has already been registered. "
                           << "Please use unique names for materials");
 
   UInt mat_count = materials.size();
   materials_names_to_id[mat_name] = mat_count;
 
   std::stringstream sstr_mat;
   sstr_mat << this->id << ":" << mat_count << ":" << mat_type;
   ID mat_id = sstr_mat.str();
 
   std::unique_ptr<Material> material = MaterialFactory::getInstance().allocate(
       mat_type, spatial_dimension, opt_param, *this, mat_id);
 
   materials.push_back(std::move(material));
 
   return *(materials.back());
 }
 
 /* -------------------------------------------------------------------------- */
 void SolidMechanicsModel::instantiateMaterials() {
   ParserSection model_section;
   bool is_empty;
   std::tie(model_section, is_empty) = this->getParserSection();
 
   if (not is_empty) {
     auto model_materials = model_section.getSubSections(ParserType::_material);
     for (const auto & section : model_materials) {
       this->registerNewMaterial(section);
     }
   }
 
   auto sub_sections = this->parser.getSubSections(ParserType::_material);
   for (const auto & section : sub_sections) {
     this->registerNewMaterial(section);
   }
 
 #ifdef AKANTU_DAMAGE_NON_LOCAL
   for (auto & material : materials) {
     if (dynamic_cast<MaterialNonLocalInterface *>(material.get()) == nullptr)
       continue;
 
     this->non_local_manager = std::make_unique<NonLocalManager>(
         *this, *this, id + ":non_local_manager", memory_id);
     break;
   }
 #endif
 
   if (materials.empty())
     AKANTU_EXCEPTION("No materials where instantiated for the model"
                      << getID());
   are_materials_instantiated = true;
 }
 
 /* -------------------------------------------------------------------------- */
 void SolidMechanicsModel::assignMaterialToElements(
     const ElementTypeMapArray<UInt> * filter) {
 
   for_each_element(
       mesh,
       [&](auto && element) {
         UInt mat_index = (*material_selector)(element);
         AKANTU_DEBUG_ASSERT(
             mat_index < materials.size(),
             "The material selector returned an index that does not exists");
         material_index(element) = mat_index;
       },
       _element_filter = filter, _ghost_type = _not_ghost);
 
   if (non_local_manager)
     non_local_manager->synchronize(*this, _gst_material_id);
 
   for_each_element(mesh,
                    [&](auto && element) {
                      auto mat_index = material_index(element);
                      auto index = materials[mat_index]->addElement(element);
                      material_local_numbering(element) = index;
                    },
                    _element_filter = filter, _ghost_type = _not_ghost);
 }
 
 /* -------------------------------------------------------------------------- */
 void SolidMechanicsModel::initMaterials() {
   AKANTU_DEBUG_ASSERT(materials.size() != 0, "No material to initialize !");
 
   if (!are_materials_instantiated)
     instantiateMaterials();
 
   this->assignMaterialToElements();
   // synchronize the element material arrays
   this->synchronize(_gst_material_id);
 
   for (auto & material : materials) {
     /// init internals properties
     material->initMaterial();
   }
 
   this->synchronize(_gst_smm_init_mat);
 
   if (this->non_local_manager) {
     this->non_local_manager->initialize();
   }
 }
 
 /* -------------------------------------------------------------------------- */
 Int SolidMechanicsModel::getInternalIndexFromID(const ID & id) const {
   AKANTU_DEBUG_IN();
 
   auto it = materials.begin();
   auto end = materials.end();
 
   for (; it != end; ++it)
     if ((*it)->getID() == id) {
       AKANTU_DEBUG_OUT();
       return (it - materials.begin());
     }
 
   AKANTU_DEBUG_OUT();
   return -1;
 }
 
 /* -------------------------------------------------------------------------- */
 void SolidMechanicsModel::reassignMaterial() {
   AKANTU_DEBUG_IN();
 
   std::vector<Array<Element>> element_to_add(materials.size());
   std::vector<Array<Element>> element_to_remove(materials.size());
 
   Element element;
   for (auto ghost_type : ghost_types) {
     element.ghost_type = ghost_type;
 
     for (auto type :
          mesh.elementTypes(spatial_dimension, ghost_type, _ek_not_defined)) {
       element.type = type;
 
       UInt nb_element = mesh.getNbElement(type, ghost_type);
       Array<UInt> & mat_indexes = material_index(type, ghost_type);
 
       for (UInt el = 0; el < nb_element; ++el) {
         element.element = el;
 
         UInt old_material = mat_indexes(el);
         UInt new_material = (*material_selector)(element);
 
         if (old_material != new_material) {
           element_to_add[new_material].push_back(element);
           element_to_remove[old_material].push_back(element);
         }
       }
     }
   }
 
   UInt mat_index = 0;
   for (auto mat_it = materials.begin(); mat_it != materials.end();
        ++mat_it, ++mat_index) {
     (*mat_it)->removeElements(element_to_remove[mat_index]);
     (*mat_it)->addElements(element_to_add[mat_index]);
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void SolidMechanicsModel::applyEigenGradU(
     const Matrix<Real> & prescribed_eigen_grad_u, const ID & material_name,
     const GhostType ghost_type) {
 
   AKANTU_DEBUG_ASSERT(prescribed_eigen_grad_u.size() ==
                           spatial_dimension * spatial_dimension,
                       "The prescribed grad_u is not of the good size");
   for (auto & material : materials) {
     if (material->getName() == material_name)
       material->applyEigenGradU(prescribed_eigen_grad_u, ghost_type);
   }
 }
 
 /* -------------------------------------------------------------------------- */
 
 } // namespace akantu
diff --git a/src/model/solid_mechanics/solid_mechanics_model_tmpl.hh b/src/model/solid_mechanics/solid_mechanics_model_tmpl.hh
index afb0de79a..c749da2dd 100644
--- a/src/model/solid_mechanics/solid_mechanics_model_tmpl.hh
+++ b/src/model/solid_mechanics/solid_mechanics_model_tmpl.hh
@@ -1,62 +1,62 @@
 /**
  * @file   solid_mechanics_model_tmpl.hh
  *
  * @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
  * @author Dana Christen <dana.christen@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Fri Jun 18 2010
- * @date last modification: Fri Nov 13 2015
+ * @date last modification: Tue Nov 07 2017
  *
  * @brief  template part of solid mechanics model
  *
  * @section LICENSE
  *
- * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
- * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
- * Solides)
+ * 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
+ * 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
+ * A PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
+
 /* -------------------------------------------------------------------------- */
 #include "material.hh"
 #include "solid_mechanics_model.hh"
 /* -------------------------------------------------------------------------- */
 
 #ifndef __AKANTU_SOLID_MECHANICS_MODEL_TMPL_HH__
 #define __AKANTU_SOLID_MECHANICS_MODEL_TMPL_HH__
 
 namespace akantu {
 
 #define FWD(...) ::std::forward<decltype(__VA_ARGS__)>(__VA_ARGS__)
 
 /* -------------------------------------------------------------------------- */
 template <typename Operation>
 void SolidMechanicsModel::splitByMaterial(const Array<Element> & elements,
                                           Operation && op) const {
   std::vector<Array<Element>> elements_per_mat(materials.size());
   this->splitElementByMaterial(elements, elements_per_mat);
 
   for (auto && mat : zip(materials, elements_per_mat)) {
     FWD(op)(FWD(*std::get<0>(mat)), FWD(std::get<1>(mat)));
   }
 }
 
 #undef FWD
 /* -------------------------------------------------------------------------- */
 
 } // namespace akantu
 
 #endif /* __AKANTU_SOLID_MECHANICS_MODEL_TMPL_HH__ */
diff --git a/src/model/solver_callback.cc b/src/model/solver_callback.cc
index 82b50e404..92728eb9d 100644
--- a/src/model/solver_callback.cc
+++ b/src/model/solver_callback.cc
@@ -1,53 +1,54 @@
 /**
  * @file   solver_callback.cc
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
- * @date   Wed Mar  2 12:47:17 2016
+ * @date creation: Tue Jul 20 2010
+ * @date last modification: Wed Jan 31 2018
  *
  * @brief  Default behavior of solver_callbacks
  *
  * @section LICENSE
  *
- * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * 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
+ * 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
+ * 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 "solver_callback.hh"
 #include "dof_manager.hh"
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 SolverCallback::SolverCallback(DOFManager & dof_manager)
     : sc_dof_manager(&dof_manager) {}
 
 /* -------------------------------------------------------------------------- */
 SolverCallback::SolverCallback() = default;
 
 /* -------------------------------------------------------------------------- */
 SolverCallback::~SolverCallback() = default;
 
 /* -------------------------------------------------------------------------- */
 void SolverCallback::setDOFManager(DOFManager & dof_manager) {
   this->sc_dof_manager = &dof_manager;
 }
 
 /* -------------------------------------------------------------------------- */
 
 } // namespace akantu
diff --git a/src/model/solver_callback.hh b/src/model/solver_callback.hh
index f986d9908..c282dcec2 100644
--- a/src/model/solver_callback.hh
+++ b/src/model/solver_callback.hh
@@ -1,108 +1,109 @@
 /**
  * @file   solver_callback.hh
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
- * @date   Tue Sep 15 22:45:27 2015
+ * @date creation: Fri Jun 18 2010
+ * @date last modification: Wed Feb 21 2018
  *
  * @brief  Class defining the interface for non_linear_solver callbacks
  *
  * @section LICENSE
  *
- * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * 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
+ * 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
+ * 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"
 /* -------------------------------------------------------------------------- */
 
 #ifndef __AKANTU_SOLVER_CALLBACK_HH__
 #define __AKANTU_SOLVER_CALLBACK_HH__
 
 namespace akantu {
 class DOFManager;
 }
 
 namespace akantu {
 
 class SolverCallback {
   /* ------------------------------------------------------------------------ */
   /* Constructors/Destructors                                                 */
   /* ------------------------------------------------------------------------ */
 public:
   explicit SolverCallback(DOFManager & dof_manager);
   explicit SolverCallback();
   /* ------------------------------------------------------------------------ */
   virtual ~SolverCallback();
 
 protected:
   void setDOFManager(DOFManager & dof_manager);
   /* ------------------------------------------------------------------------ */
   /* Methods                                                                  */
   /* ------------------------------------------------------------------------ */
 public:
   /// get the type of matrix needed
   virtual MatrixType getMatrixType(const ID &) = 0;
 
   /// callback to assemble a Matrix
   virtual void assembleMatrix(const ID &) = 0;
 
   /// callback to assemble a lumped Matrix
   virtual void assembleLumpedMatrix(const ID &) = 0;
 
   /// callback to assemble the residual (rhs)
   virtual void assembleResidual() = 0;
 
   /// callback to assemble the rhs parts, (e.g. internal_forces +
   /// external_forces)
   virtual void assembleResidual(const ID & /*residual_part*/) {}
 
   /* ------------------------------------------------------------------------ */
   /* Dynamic simulations part                                                 */
   /* ------------------------------------------------------------------------ */
   /// callback for the predictor (in case of dynamic simulation)
   virtual void predictor() {}
 
   /// callback for the corrector (in case of dynamic simulation)
   virtual void corrector() {}
 
   /// tells if the residual can be computed in separated parts
   virtual bool canSplitResidual() { return false; }
 
   /* ------------------------------------------------------------------------ */
   /* management callbacks                                                     */
   /* ------------------------------------------------------------------------ */
   virtual void beforeSolveStep(){};
   virtual void afterSolveStep(){};
 
 protected:
   /// DOFManager prefixed to avoid collision in multiple inheritance cases
   DOFManager * sc_dof_manager{nullptr};
 };
 
 namespace debug {
   class SolverCallbackResidualPartUnknown : public Exception {
   public:
     SolverCallbackResidualPartUnknown(const ID & residual_part)
         : Exception(residual_part + " is not known here.") {}
   };
 }
 
 } // namespace akantu
 
 #endif /* __AKANTU_SOLVER_CALLBACK_HH__ */
diff --git a/src/model/structural_mechanics/structural_elements/structural_element_bernoulli_beam_2.hh b/src/model/structural_mechanics/structural_elements/structural_element_bernoulli_beam_2.hh
index d59f608e5..53300ae7e 100644
--- a/src/model/structural_mechanics/structural_elements/structural_element_bernoulli_beam_2.hh
+++ b/src/model/structural_mechanics/structural_elements/structural_element_bernoulli_beam_2.hh
@@ -1,134 +1,137 @@
 /**
  * @file   structural_element_bernoulli_beam_2.hh
  *
  * @author Fabian Barras <fabian.barras@epfl.ch>
+ * @author Lucas Frerot <lucas.frerot@epfl.ch>
  * @author Sébastien Hartmann <sebastien.hartmann@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
- * @date creation  Tue Sep 19 2017
+ * @date creation: Wed Oct 11 2017
+ * @date last modification: Wed Jan 10 2018
  *
- * @brief Specific functions for bernoulli beam 2d
+ * @brief  Specific functions for bernoulli beam 2d
  *
  * @section LICENSE
  *
- * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * 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
+ * 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
+ * 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 "structural_mechanics_model.hh"
 /* -------------------------------------------------------------------------- */
 
 #ifndef __AKANTU_STRUCTURAL_ELEMENT_BERNOULLI_BEAM_2_HH__
 #define __AKANTU_STRUCTURAL_ELEMENT_BERNOULLI_BEAM_2_HH__
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 template <>
 inline void StructuralMechanicsModel::assembleMass<_bernoulli_beam_2>() {
   AKANTU_DEBUG_IN();
   constexpr ElementType type = _bernoulli_beam_2;
 
   auto & fem = getFEEngineClass<MyFEEngineType>();
   auto nb_element = mesh.getNbElement(type);
   auto nb_nodes_per_element = mesh.getNbNodesPerElement(type);
   auto nb_quadrature_points = fem.getNbIntegrationPoints(type);
   auto nb_fields_to_interpolate = ElementClass<type>::getNbStressComponents();
   auto nt_n_field_size = nb_degree_of_freedom * nb_nodes_per_element;
 
   Array<Real> n(nb_element * nb_quadrature_points,
                 nb_fields_to_interpolate * nt_n_field_size, "N");
 
   Array<Real> * rho_field =
       new Array<Real>(nb_element * nb_quadrature_points, 1, "Rho");
   rho_field->clear();
   computeRho(*rho_field, type, _not_ghost);
 
 #if 0
   bool sign = true;
 
   for (auto && ghost_type : ghost_types) {
     fem.computeShapesMatrix(type, nb_degree_of_freedom, nb_nodes_per_element, n,
                             0, 0, 0, sign, ghost_type); // Ni ui -> u
     fem.computeShapesMatrix(type, nb_degree_of_freedom, nb_nodes_per_element, n,
                             1, 1, 1, sign, ghost_type); // Mi vi -> v
     fem.computeShapesMatrix(type, nb_degree_of_freedom, nb_nodes_per_element, n,
                             2, 2, 1, sign, ghost_type); // Li Theta_i -> v
     fem.assembleFieldMatrix(*rho_field, nb_degree_of_freedom, *mass_matrix, n,
                             rotation_matrix, type, ghost_type);
   }
 #endif
 
   delete rho_field;
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <>
 void StructuralMechanicsModel::computeRotationMatrix<_bernoulli_beam_2>(
     Array<Real> & rotations) {
   auto type = _bernoulli_beam_2;
   auto nodes_it = mesh.getNodes().begin(this->spatial_dimension);
 
   for (auto && tuple :
        zip(make_view(mesh.getConnectivity(type), 2),
            make_view(rotations, nb_degree_of_freedom, nb_degree_of_freedom))) {
 
     auto & connec = std::get<0>(tuple);
     auto & R = std::get<1>(tuple);
 
     Vector<Real> x2 = nodes_it[connec(1)]; // X2
     Vector<Real> x1 = nodes_it[connec(0)]; // X1
 
     auto le = x1.distance(x2);
     auto c = (x2(0) - x1(0)) / le;
     auto s = (x2(1) - x1(1)) / le;
 
     /// Definition of the rotation matrix
     R = {{c, s, 0.}, {-s, c, 0.}, {0., 0., 1.}};
   }
 }
 
 /* -------------------------------------------------------------------------- */
 template <>
 void StructuralMechanicsModel::computeTangentModuli<_bernoulli_beam_2>(
     Array<Real> & tangent_moduli) {
   // auto nb_element = getFEEngine().getMesh().getNbElement(_bernoulli_beam_2);
   auto nb_quadrature_points =
       getFEEngine().getNbIntegrationPoints(_bernoulli_beam_2);
   auto tangent_size = 2;
 
   tangent_moduli.clear();
   auto D_it = tangent_moduli.begin(tangent_size, tangent_size);
   auto el_mat = element_material(_bernoulli_beam_2, _not_ghost).begin();
 
   for (auto & mat : element_material(_bernoulli_beam_2, _not_ghost)) {
     auto E = materials[mat].E;
     auto A = materials[mat].A;
     auto I = materials[mat].I;
     for (UInt q = 0; q < nb_quadrature_points; ++q, ++D_it) {
       auto & D = *D_it;
       D(0, 0) = E * A;
       D(1, 1) = E * I;
     }
   }
 }
 
 } // namespace akantu
 
 #endif /* __AKANTU_STRUCTURAL_ELEMENT_BERNOULLI_BEAM_2_HH__ */
diff --git a/src/model/structural_mechanics/structural_elements/structural_element_bernoulli_beam_3.hh b/src/model/structural_mechanics/structural_elements/structural_element_bernoulli_beam_3.hh
index 16616689c..b00cbd1cd 100644
--- a/src/model/structural_mechanics/structural_elements/structural_element_bernoulli_beam_3.hh
+++ b/src/model/structural_mechanics/structural_elements/structural_element_bernoulli_beam_3.hh
@@ -1,187 +1,190 @@
 /**
  * @file   structural_element_bernoulli_beam_3.hh
  *
  * @author Fabian Barras <fabian.barras@epfl.ch>
+ * @author Lucas Frerot <lucas.frerot@epfl.ch>
  * @author Sébastien Hartmann <sebastien.hartmann@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  * @author Damien Spielmann <damien.spielmann@epfl.ch>
  *
- * @date creation  Tue Sep 19 2017
+ * @date creation: Wed Oct 11 2017
+ * @date last modification: Tue Feb 20 2018
  *
- * @brief Specific functions for bernoulli beam 3d
+ * @brief  Specific functions for bernoulli beam 3d
  *
  * @section LICENSE
  *
- * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * 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
+ * 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
+ * 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_STRUCTURAL_ELEMENT_BERNOULLI_BEAM_3_HH__
 #define __AKANTU_STRUCTURAL_ELEMENT_BERNOULLI_BEAM_3_HH__
 
 #include "structural_mechanics_model.hh"
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 template <>
 inline void StructuralMechanicsModel::assembleMass<_bernoulli_beam_3>() {
   AKANTU_DEBUG_IN();
 #if 0
   GhostType ghost_type = _not_ghost;
   ElementType type = _bernoulli_beam_3;
   MyFEEngineType & fem = getFEEngineClass<MyFEEngineType>();
   UInt nb_element = getFEEngine().getMesh().getNbElement(type);
   UInt nb_nodes_per_element = Mesh::getNbNodesPerElement(type);
   UInt nb_quadrature_points = getFEEngine().getNbIntegrationPoints(type);
   UInt nb_fields_to_interpolate =
       getTangentStiffnessVoigtSize<_bernoulli_beam_3>();
 
   UInt nt_n_field_size = nb_degree_of_freedom * nb_nodes_per_element;
 
   Array<Real> * n =
       new Array<Real>(nb_element * nb_quadrature_points,
                       nb_fields_to_interpolate * nt_n_field_size, "N");
   n->clear();
   Array<Real> * rho_field =
       new Array<Real>(nb_element * nb_quadrature_points, "Rho");
   rho_field->clear();
   computeRho(*rho_field, type, _not_ghost);
 
   /* --------------------------------------------------------------------------
    */
   fem.computeShapesMatrix(type, nb_degree_of_freedom, nb_nodes_per_element, n,
                           0, 0, 0, true, ghost_type); // Ni ui ->         u
 
   fem.computeShapesMatrix(type, nb_degree_of_freedom, nb_nodes_per_element, n,
                           1, 1, 1, true, ghost_type); // Mi vi ->         v
   fem.computeShapesMatrix(type, nb_degree_of_freedom, nb_nodes_per_element, n,
                           2, 5, 1, true, ghost_type); // Li Theta_z_i ->  v
 
   fem.computeShapesMatrix(type, nb_degree_of_freedom, nb_nodes_per_element, n,
                           1, 2, 2, true, ghost_type); // Mi wi ->        w
   fem.computeShapesMatrix(type, nb_degree_of_freedom, nb_nodes_per_element, n,
                           2, 4, 2, false, ghost_type); // -Li Theta_y_i ->  w
 
   fem.computeShapesMatrix(type, nb_degree_of_freedom, nb_nodes_per_element, n,
                           0, 3, 3, true, ghost_type); // Ni Theta_x_i->Theta_x
   /* --------------------------------------------------------------------------
    */
 
   fem.assembleFieldMatrix(*rho_field, nb_degree_of_freedom, *mass_matrix, n,
                           rotation_matrix, type, ghost_type);
 
   delete n;
   delete rho_field;
 #endif
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <>
 void StructuralMechanicsModel::computeRotationMatrix<_bernoulli_beam_3>(
     Array<Real> & rotations) {
   ElementType type = _bernoulli_beam_3;
   Mesh & mesh = getFEEngine().getMesh();
   UInt nb_element = mesh.getNbElement(type);
 
   auto n_it = mesh.getNormals(type).begin(spatial_dimension);
   Array<UInt>::iterator<Vector<UInt>> connec_it =
       mesh.getConnectivity(type).begin(2);
   auto nodes_it = mesh.getNodes().begin(spatial_dimension);
 
   Matrix<Real> Pe(spatial_dimension, spatial_dimension);
   Matrix<Real> Pg(spatial_dimension, spatial_dimension);
   Matrix<Real> inv_Pg(spatial_dimension, spatial_dimension);
   Vector<Real> x_n(spatial_dimension); // x vect n
 
   Array<Real>::matrix_iterator R_it =
       rotations.begin(nb_degree_of_freedom, nb_degree_of_freedom);
 
   for (UInt e = 0; e < nb_element; ++e, ++n_it, ++connec_it, ++R_it) {
     Vector<Real> & n = *n_it;
     Matrix<Real> & R = *R_it;
     Vector<UInt> & connec = *connec_it;
 
     Vector<Real> x;
     x = nodes_it[connec(1)]; // X2
     Vector<Real> y;
     y = nodes_it[connec(0)]; // X1
 
     Real l = x.distance(y);
     x -= y; // X2 - X1
     x_n.crossProduct(x, n);
 
     Pe.eye();
     Pe(0, 0) *= l;
     Pe(1, 1) *= -l;
 
     Pg(0, 0) = x(0);
     Pg(0, 1) = x_n(0);
     Pg(0, 2) = n(0);
     Pg(1, 0) = x(1);
     Pg(1, 1) = x_n(1);
     Pg(1, 2) = n(1);
     Pg(2, 0) = x(2);
     Pg(2, 1) = x_n(2);
     Pg(2, 2) = n(2);
 
     inv_Pg.inverse(Pg);
 
     Pe *= inv_Pg;
     for (UInt i = 0; i < spatial_dimension; ++i) {
       for (UInt j = 0; j < spatial_dimension; ++j) {
         R(i, j) = Pe(i, j);
         R(i + spatial_dimension, j + spatial_dimension) = Pe(i, j);
       }
     }
   }
 }
 
 /* -------------------------------------------------------------------------- */
 template <>
 void StructuralMechanicsModel::computeTangentModuli<_bernoulli_beam_3>(
     Array<Real> & tangent_moduli) {
   UInt nb_element = getFEEngine().getMesh().getNbElement(_bernoulli_beam_3);
   UInt nb_quadrature_points =
       getFEEngine().getNbIntegrationPoints(_bernoulli_beam_3);
   UInt tangent_size = 4;
 
   tangent_moduli.clear();
   Array<Real>::matrix_iterator D_it =
       tangent_moduli.begin(tangent_size, tangent_size);
 
   for (UInt e = 0; e < nb_element; ++e) {
     UInt mat = element_material(_bernoulli_beam_3, _not_ghost)(e);
     Real E = materials[mat].E;
     Real A = materials[mat].A;
     Real Iz = materials[mat].Iz;
     Real Iy = materials[mat].Iy;
     Real GJ = materials[mat].GJ;
     for (UInt q = 0; q < nb_quadrature_points; ++q, ++D_it) {
       Matrix<Real> & D = *D_it;
       D(0, 0) = E * A;
       D(1, 1) = E * Iz;
       D(2, 2) = E * Iy;
       D(3, 3) = GJ;
     }
   }
 }
 
 } // akantu
 
 #endif /* __AKANTU_STRUCTURAL_ELEMENT_BERNOULLI_BEAM_3_HH__ */
diff --git a/src/model/structural_mechanics/structural_elements/structural_element_kirchhoff_shell.hh b/src/model/structural_mechanics/structural_elements/structural_element_kirchhoff_shell.hh
index 30a4d44b4..e5559a345 100644
--- a/src/model/structural_mechanics/structural_elements/structural_element_kirchhoff_shell.hh
+++ b/src/model/structural_mechanics/structural_elements/structural_element_kirchhoff_shell.hh
@@ -1,77 +1,80 @@
 /**
- * @file   structural_element_bernoulli_kirchhoff_shell.hh
+ * @file   structural_element_kirchhoff_shell.hh
  *
  * @author Fabian Barras <fabian.barras@epfl.ch>
+ * @author Lucas Frerot <lucas.frerot@epfl.ch>
  * @author Sébastien Hartmann <sebastien.hartmann@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  * @author Damien Spielmann <damien.spielmann@epfl.ch>
  *
- * @date creation  Tue Sep 19 2017
+ * @date creation: Wed Oct 11 2017
+ * @date last modification: Wed Feb 21 2018
  *
- * @brief Specific functions for bernoulli kirchhoff shell
+ * @brief  Specific functions for bernoulli kirchhoff shell
  *
  * @section LICENSE
  *
- * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * 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
+ * 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
+ * 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_STRUCTURAL_ELEMENT_BERNOULLI_KIRCHHOFF_SHELL_HH__
 #define __AKANTU_STRUCTURAL_ELEMENT_BERNOULLI_KIRCHHOFF_SHELL_HH__
 
 #include "structural_mechanics_model.hh"
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 template <>
 inline void
 StructuralMechanicsModel::assembleMass<_discrete_kirchhoff_triangle_18>() {
   AKANTU_TO_IMPLEMENT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <>
 void StructuralMechanicsModel::computeTangentModuli<
     _discrete_kirchhoff_triangle_18>(Array<Real> & tangent_moduli) {
 
   auto tangent_size =
       ElementClass<_discrete_kirchhoff_triangle_18>::getNbStressComponents();
   auto nb_quad =
       getFEEngine().getNbIntegrationPoints(_discrete_kirchhoff_triangle_18);
 
   auto H_it = tangent_moduli.begin(tangent_size, tangent_size);
 
   for (UInt mat :
        element_material(_discrete_kirchhoff_triangle_18, _not_ghost)) {
     auto & m = materials[mat];
 
     for (UInt q = 0; q < nb_quad; ++q, ++H_it) {
       auto & H = *H_it;
       H.clear();
       Matrix<Real> D = {{1, m.nu, 0}, {m.nu, 1, 0}, {0, 0, (1 - m.nu) / 2}};
       D *= m.E * m.t / (1 - m.nu * m.nu);
       H.block(D, 0, 0);                           // in plane membrane behavior
       H.block(D * Math::pow<3>(m.t) / 12., 3, 3); // bending behavior
     }
   }
 }
 
 } // akantu
 
 #endif /* __AKANTU_STRUCTURAL_ELEMENT_BERNOULLI_DISCRETE_KIRCHHOFF_TRIANGLE_18_HH__ \
           */
diff --git a/src/model/structural_mechanics/structural_mechanics_model.cc b/src/model/structural_mechanics/structural_mechanics_model.cc
index f1ea3fff0..29392c28c 100644
--- a/src/model/structural_mechanics/structural_mechanics_model.cc
+++ b/src/model/structural_mechanics/structural_mechanics_model.cc
@@ -1,483 +1,483 @@
 /**
  * @file   structural_mechanics_model.cc
  *
  * @author Fabian Barras <fabian.barras@epfl.ch>
+ * @author Lucas Frerot <lucas.frerot@epfl.ch>
  * @author Sébastien Hartmann <sebastien.hartmann@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  * @author Damien Spielmann <damien.spielmann@epfl.ch>
  *
  * @date creation: Fri Jul 15 2011
- * @date last modification: Thu Oct 15 2015
+ * @date last modification: Wed Feb 21 2018
  *
  * @brief  Model implementation for StucturalMechanics elements
  *
  * @section LICENSE
  *
- * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
- * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
- * Solides)
+ * 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
+ * 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
+ * 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 "structural_mechanics_model.hh"
 #include "dof_manager.hh"
 #include "integrator_gauss.hh"
 #include "mesh.hh"
 #include "shape_structural.hh"
 #include "sparse_matrix.hh"
 #include "time_step_solver.hh"
 /* -------------------------------------------------------------------------- */
 #ifdef AKANTU_USE_IOHELPER
 #include "dumpable_inline_impl.hh"
 #include "dumper_elemental_field.hh"
 #include "dumper_iohelper_paraview.hh"
 #include "group_manager_inline_impl.cc"
 #endif
 /* -------------------------------------------------------------------------- */
 #include "structural_mechanics_model_inline_impl.cc"
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 StructuralMechanicsModel::StructuralMechanicsModel(Mesh & mesh, UInt dim,
                                                    const ID & id,
                                                    const MemoryID & memory_id)
     : Model(mesh, ModelType::_structural_mechanics_model, dim, id, memory_id),
       time_step(NAN), f_m2a(1.0), stress("stress", id, memory_id),
       element_material("element_material", id, memory_id),
       set_ID("beam sets", id, memory_id),
       rotation_matrix("rotation_matices", id, memory_id) {
   AKANTU_DEBUG_IN();
 
   registerFEEngineObject<MyFEEngineType>("StructuralMechanicsFEEngine", mesh,
                                          spatial_dimension);
 
   if (spatial_dimension == 2)
     nb_degree_of_freedom = 3;
   else if (spatial_dimension == 3)
     nb_degree_of_freedom = 6;
   else {
     AKANTU_TO_IMPLEMENT();
   }
 
 #ifdef AKANTU_USE_IOHELPER
   this->mesh.registerDumper<DumperParaview>("paraview_all", id, true);
 #endif
   this->mesh.addDumpMesh(mesh, spatial_dimension, _not_ghost, _ek_structural);
 
   this->initDOFManager();
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 StructuralMechanicsModel::~StructuralMechanicsModel() = default;
 
 /* -------------------------------------------------------------------------- */
 void StructuralMechanicsModel::initFullImpl(const ModelOptions & options) {
   // <<<< This is the SolidMechanicsModel implementation for future ref >>>>
   // material_index.initialize(mesh, _element_kind = _ek_not_defined,
   //                           _default_value = UInt(-1), _with_nb_element =
   //                           true);
   // material_local_numbering.initialize(mesh, _element_kind = _ek_not_defined,
   //                                     _with_nb_element = true);
 
   // Model::initFullImpl(options);
 
   // // initialize pbc
   // if (this->pbc_pair.size() != 0)
   //   this->initPBC();
 
   // // initialize the materials
   // if (this->parser.getLastParsedFile() != "") {
   //   this->instantiateMaterials();
   // }
 
   // this->initMaterials();
   // this->initBC(*this, *displacement, *displacement_increment,
   // *external_force);
 
   // <<<< END >>>>
 
   Model::initFullImpl(options);
 
   // Initializing stresses
   ElementTypeMap<UInt> stress_components;
 
   /// TODO this is ugly af, maybe add a function to FEEngine
   for (auto & type : mesh.elementTypes(_spatial_dimension = _all_dimensions,
                      _element_kind = _ek_structural)) {
     UInt nb_components = 0;
 
 // Getting number of components for each element type
 #define GET_(type) nb_components = ElementClass<type>::getNbStressComponents()
     AKANTU_BOOST_STRUCTURAL_ELEMENT_SWITCH(GET_);
 #undef GET_
 
     stress_components(nb_components, type);
   }
 
   stress.initialize(getFEEngine(), _spatial_dimension = _all_dimensions,
                     _element_kind = _ek_structural, _all_ghost_types = true,
                     _nb_component = [&stress_components](
                         const ElementType & type, const GhostType &) -> UInt {
                       return stress_components(type);
                     });
 }
 
 /* -------------------------------------------------------------------------- */
 
 void StructuralMechanicsModel::initFEEngineBoundary() {
   /// TODO: this function should not be reimplemented
   /// we're just avoiding a call to Model::initFEEngineBoundary()
 }
 
 /* -------------------------------------------------------------------------- */
 // void StructuralMechanicsModel::setTimeStep(Real time_step) {
 //   this->time_step = time_step;
 
 // #if defined(AKANTU_USE_IOHELPER)
 //   this->mesh.getDumper().setTimeStep(time_step);
 // #endif
 // }
 
 /* -------------------------------------------------------------------------- */
 /* Initialisation                                                             */
 /* -------------------------------------------------------------------------- */
 void StructuralMechanicsModel::initSolver(
     TimeStepSolverType time_step_solver_type, NonLinearSolverType) {
   AKANTU_DEBUG_IN();
 
   this->allocNodalField(displacement_rotation, nb_degree_of_freedom,
                         "displacement");
   this->allocNodalField(external_force, nb_degree_of_freedom, "external_force");
   this->allocNodalField(internal_force, nb_degree_of_freedom, "internal_force");
   this->allocNodalField(blocked_dofs, nb_degree_of_freedom, "blocked_dofs");
 
   auto & dof_manager = this->getDOFManager();
 
   if (!dof_manager.hasDOFs("displacement")) {
     dof_manager.registerDOFs("displacement", *displacement_rotation,
                              _dst_nodal);
     dof_manager.registerBlockedDOFs("displacement", *this->blocked_dofs);
   }
 
   if (time_step_solver_type == _tsst_dynamic ||
       time_step_solver_type == _tsst_dynamic_lumped) {
     this->allocNodalField(velocity, spatial_dimension, "velocity");
     this->allocNodalField(acceleration, spatial_dimension, "acceleration");
 
     if (!dof_manager.hasDOFsDerivatives("displacement", 1)) {
       dof_manager.registerDOFsDerivative("displacement", 1, *this->velocity);
       dof_manager.registerDOFsDerivative("displacement", 2,
                                          *this->acceleration);
     }
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void StructuralMechanicsModel::initModel() {
   for (auto && type : mesh.elementTypes(_element_kind = _ek_structural)) {
     // computeRotationMatrix(type);
     element_material.alloc(mesh.getNbElement(type), 1, type);
   }
 
   getFEEngine().initShapeFunctions(_not_ghost);
   getFEEngine().initShapeFunctions(_ghost);
 }
 
 /* -------------------------------------------------------------------------- */
 void StructuralMechanicsModel::assembleStiffnessMatrix() {
   AKANTU_DEBUG_IN();
 
   getDOFManager().getMatrix("K").clear();
 
   for (auto & type :
        mesh.elementTypes(spatial_dimension, _not_ghost, _ek_structural)) {
 #define ASSEMBLE_STIFFNESS_MATRIX(type) assembleStiffnessMatrix<type>();
 
     AKANTU_BOOST_STRUCTURAL_ELEMENT_SWITCH(ASSEMBLE_STIFFNESS_MATRIX);
 #undef ASSEMBLE_STIFFNESS_MATRIX
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void StructuralMechanicsModel::computeStresses() {
   AKANTU_DEBUG_IN();
 
   for (auto & type :
        mesh.elementTypes(spatial_dimension, _not_ghost, _ek_structural)) {
 #define COMPUTE_STRESS_ON_QUAD(type) computeStressOnQuad<type>();
 
     AKANTU_BOOST_STRUCTURAL_ELEMENT_SWITCH(COMPUTE_STRESS_ON_QUAD);
 #undef COMPUTE_STRESS_ON_QUAD
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void StructuralMechanicsModel::computeRotationMatrix(const ElementType & type) {
   Mesh & mesh = getFEEngine().getMesh();
 
   UInt nb_nodes_per_element = Mesh::getNbNodesPerElement(type);
   UInt nb_element = mesh.getNbElement(type);
 
   if (!rotation_matrix.exists(type)) {
     rotation_matrix.alloc(nb_element,
                           nb_degree_of_freedom * nb_nodes_per_element *
                               nb_degree_of_freedom * nb_nodes_per_element,
                           type);
   } else {
     rotation_matrix(type).resize(nb_element);
   }
   rotation_matrix(type).clear();
 
   Array<Real> rotations(nb_element,
                         nb_degree_of_freedom * nb_degree_of_freedom);
   rotations.clear();
 
 #define COMPUTE_ROTATION_MATRIX(type) computeRotationMatrix<type>(rotations);
 
   AKANTU_BOOST_STRUCTURAL_ELEMENT_SWITCH(COMPUTE_ROTATION_MATRIX);
 #undef COMPUTE_ROTATION_MATRIX
 
   auto R_it = rotations.begin(nb_degree_of_freedom, nb_degree_of_freedom);
   auto T_it =
       rotation_matrix(type).begin(nb_degree_of_freedom * nb_nodes_per_element,
                                   nb_degree_of_freedom * nb_nodes_per_element);
 
   for (UInt el = 0; el < nb_element; ++el, ++R_it, ++T_it) {
     auto & T = *T_it;
     auto & R = *R_it;
     for (UInt k = 0; k < nb_nodes_per_element; ++k) {
       for (UInt i = 0; i < nb_degree_of_freedom; ++i)
         for (UInt j = 0; j < nb_degree_of_freedom; ++j)
           T(k * nb_degree_of_freedom + i, k * nb_degree_of_freedom + j) =
               R(i, j);
     }
   }
 }
 
 /* -------------------------------------------------------------------------- */
 dumper::Field * StructuralMechanicsModel::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;
 
   dumper::Field * field = NULL;
   field = mesh.createNodalField(uint_nodal_fields[field_name], group_name);
   return field;
 }
 
 /* -------------------------------------------------------------------------- */
 dumper::Field *
 StructuralMechanicsModel::createNodalFieldReal(const std::string & field_name,
                                                const std::string & group_name,
                                                bool padding_flag) {
 
   UInt n;
   if (spatial_dimension == 2) {
     n = 2;
   } else {
     n = 3;
   }
 
   if (field_name == "displacement") {
     return mesh.createStridedNodalField(displacement_rotation, group_name, n, 0,
                                         padding_flag);
   }
 
   if (field_name == "rotation") {
     return mesh.createStridedNodalField(displacement_rotation, group_name,
                                         nb_degree_of_freedom - n, n,
                                         padding_flag);
   }
 
   if (field_name == "force") {
     return mesh.createStridedNodalField(external_force, group_name, n, 0,
                                         padding_flag);
   }
 
   if (field_name == "momentum") {
     return mesh.createStridedNodalField(
         external_force, group_name, nb_degree_of_freedom - n, n, padding_flag);
   }
 
   if (field_name == "internal_force") {
     return mesh.createStridedNodalField(internal_force, group_name, n, 0,
                                         padding_flag);
   }
 
   if (field_name == "internal_momentum") {
     return mesh.createStridedNodalField(
         internal_force, group_name, nb_degree_of_freedom - n, n, padding_flag);
   }
 
   return nullptr;
 }
 
 /* -------------------------------------------------------------------------- */
 dumper::Field * StructuralMechanicsModel::createElementalField(
     const std::string & field_name, const std::string & group_name, bool,
     const ElementKind & kind, const std::string &) {
 
   dumper::Field * field = NULL;
 
   if (field_name == "element_index_by_material")
     field = mesh.createElementalField<UInt, Vector, dumper::ElementalField>(
         field_name, group_name, this->spatial_dimension, kind);
 
   return field;
 }
 
 /* -------------------------------------------------------------------------- */
 /* Virtual methods from SolverCallback */
 /* -------------------------------------------------------------------------- */
 /// get the type of matrix needed
 MatrixType StructuralMechanicsModel::getMatrixType(const ID & /*id*/) {
   return _symmetric;
 }
 
 /// callback to assemble a Matrix
 void StructuralMechanicsModel::assembleMatrix(const ID & id) {
   if (id == "K")
     assembleStiffnessMatrix();
 }
 
 /// callback to assemble a lumped Matrix
 void StructuralMechanicsModel::assembleLumpedMatrix(const ID & /*id*/) {}
 
 /// callback to assemble the residual StructuralMechanicsModel::(rhs)
 void StructuralMechanicsModel::assembleResidual() {
   AKANTU_DEBUG_IN();
 
   auto & dof_manager = getDOFManager();
 
   internal_force->clear();
   computeStresses();
   assembleInternalForce();
   dof_manager.assembleToResidual("displacement", *internal_force, -1);
   dof_manager.assembleToResidual("displacement", *external_force, 1);
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 /* Virtual methods from MeshEventHandler */
 /* -------------------------------------------------------------------------- */
 
 /// function to implement to react on  akantu::NewNodesEvent
 void StructuralMechanicsModel::onNodesAdded(const Array<UInt> & /*nodes_list*/,
                                             const NewNodesEvent & /*event*/) {}
 /// function to implement to react on  akantu::RemovedNodesEvent
 void StructuralMechanicsModel::onNodesRemoved(
     const Array<UInt> & /*nodes_list*/, const Array<UInt> & /*new_numbering*/,
     const RemovedNodesEvent & /*event*/) {}
 /// function to implement to react on  akantu::NewElementsEvent
 void StructuralMechanicsModel::onElementsAdded(
     const Array<Element> & /*elements_list*/,
     const NewElementsEvent & /*event*/) {}
 /// function to implement to react on  akantu::RemovedElementsEvent
 void StructuralMechanicsModel::onElementsRemoved(
     const Array<Element> & /*elements_list*/,
     const ElementTypeMapArray<UInt> & /*new_numbering*/,
     const RemovedElementsEvent & /*event*/) {}
 /// function to implement to react on  akantu::ChangedElementsEvent
 void StructuralMechanicsModel::onElementsChanged(
     const Array<Element> & /*old_elements_list*/,
     const Array<Element> & /*new_elements_list*/,
     const ElementTypeMapArray<UInt> & /*new_numbering*/,
     const ChangedElementsEvent & /*event*/) {}
 
 /* -------------------------------------------------------------------------- */
 /* Virtual methods from Model */
 /* -------------------------------------------------------------------------- */
 /// get some default values for derived classes
 std::tuple<ID, TimeStepSolverType>
 StructuralMechanicsModel::getDefaultSolverID(const AnalysisMethod & method) {
   switch (method) {
   case _static: {
     return std::make_tuple("static", _tsst_static);
   }
   case _implicit_dynamic: {
     return std::make_tuple("implicit", _tsst_dynamic);
   }
   default:
     return std::make_tuple("unknown", _tsst_not_defined);
   }
 }
 
 /* ------------------------------------------------------------------------ */
 ModelSolverOptions StructuralMechanicsModel::getDefaultSolverOptions(
     const TimeStepSolverType & type) const {
   ModelSolverOptions options;
 
   switch (type) {
   case _tsst_static: {
     options.non_linear_solver_type = _nls_linear;
     options.integration_scheme_type["displacement"] = _ist_pseudo_time;
     options.solution_type["displacement"] = IntegrationScheme::_not_defined;
     break;
   }
   default:
     AKANTU_EXCEPTION(type << " is not a valid time step solver type");
   }
 
   return options;
 }
 
 /* -------------------------------------------------------------------------- */
 void StructuralMechanicsModel::assembleInternalForce() {
   for (auto type : mesh.elementTypes(_spatial_dimension = _all_dimensions,
                    _element_kind = _ek_structural)) {
     assembleInternalForce(type, _not_ghost);
     // assembleInternalForce(type, _ghost);
   }
 }
 
 /* -------------------------------------------------------------------------- */
 void StructuralMechanicsModel::assembleInternalForce(const ElementType & type,
                                                      GhostType gt) {
   auto & fem = getFEEngine();
   auto & sigma = stress(type, gt);
   auto ndof = getNbDegreeOfFreedom(type);
   auto nb_nodes = mesh.getNbNodesPerElement(type);
   auto ndof_per_elem = ndof * nb_nodes;
 
   Array<Real> BtSigma(fem.getNbIntegrationPoints(type) *
                           mesh.getNbElement(type),
                       ndof_per_elem, "BtSigma");
   fem.computeBtD(sigma, BtSigma, type, gt);
 
   Array<Real> intBtSigma(0, ndof_per_elem, "intBtSigma");
   fem.integrate(BtSigma, intBtSigma, ndof_per_elem, type, gt);
   BtSigma.resize(0);
 
   getDOFManager().assembleElementalArrayLocalArray(intBtSigma, *internal_force,
                                                    type, gt, 1);
 }
 /* -------------------------------------------------------------------------- */
 
 } // namespace akantu
diff --git a/src/model/structural_mechanics/structural_mechanics_model.hh b/src/model/structural_mechanics/structural_mechanics_model.hh
index baa53daa2..e0ef8f284 100644
--- a/src/model/structural_mechanics/structural_mechanics_model.hh
+++ b/src/model/structural_mechanics/structural_mechanics_model.hh
@@ -1,332 +1,333 @@
 /**
  * @file   structural_mechanics_model.hh
  *
  * @author Fabian Barras <fabian.barras@epfl.ch>
+ * @author Lucas Frerot <lucas.frerot@epfl.ch>
  * @author Sébastien Hartmann <sebastien.hartmann@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  * @author Damien Spielmann <damien.spielmann@epfl.ch>
  *
  * @date creation: Fri Jul 15 2011
- * @date last modification: Thu Jan 21 2016
+ * @date last modification: Tue Feb 20 2018
  *
  * @brief  Particular implementation of the structural elements in the
  * StructuralMechanicsModel
  *
  * @section LICENSE
  *
- * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
- * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
- * Solides)
+ * 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
+ * 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
+ * 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_named_argument.hh"
 #include "boundary_condition.hh"
 #include "model.hh"
 /* -------------------------------------------------------------------------- */
 
 #ifndef __AKANTU_STRUCTURAL_MECHANICS_MODEL_HH__
 #define __AKANTU_STRUCTURAL_MECHANICS_MODEL_HH__
 
 /* -------------------------------------------------------------------------- */
 namespace akantu {
 class Material;
 class MaterialSelector;
 class DumperIOHelper;
 class NonLocalManager;
 template <ElementKind kind, class IntegrationOrderFunctor>
 class IntegratorGauss;
 template <ElementKind kind> class ShapeStructural;
 } // namespace akantu
 
 namespace akantu {
 
 struct StructuralMaterial {
   Real E{0};
   Real A{1};
   Real I{0};
   Real Iz{0};
   Real Iy{0};
   Real GJ{0};
   Real rho{0};
   Real t{0};
   Real nu{0};
 };
 
 class StructuralMechanicsModel : public Model {
   /* ------------------------------------------------------------------------ */
   /* Constructors/Destructors                                                 */
   /* ------------------------------------------------------------------------ */
 public:
   using MyFEEngineType =
       FEEngineTemplate<IntegratorGauss, ShapeStructural, _ek_structural>;
 
   StructuralMechanicsModel(Mesh & mesh,
                            UInt spatial_dimension = _all_dimensions,
                            const ID & id = "structural_mechanics_model",
                            const MemoryID & memory_id = 0);
 
   virtual ~StructuralMechanicsModel();
 
   /// Init full model
   void initFullImpl(const ModelOptions & options) override;
 
   /// Init boundary FEEngine
   void initFEEngineBoundary() override;
 
   /* ------------------------------------------------------------------------ */
   /* Virtual methods from SolverCallback */
   /* ------------------------------------------------------------------------ */
   /// get the type of matrix needed
   MatrixType getMatrixType(const ID &) override;
 
   /// callback to assemble a Matrix
   void assembleMatrix(const ID &) override;
 
   /// callback to assemble a lumped Matrix
   void assembleLumpedMatrix(const ID &) override;
 
   /// callback to assemble the residual (rhs)
   void assembleResidual() override;
 
   /* ------------------------------------------------------------------------ */
   /* Virtual methods from MeshEventHandler */
   /* ------------------------------------------------------------------------ */
 
   /// function to implement to react on  akantu::NewNodesEvent
   void onNodesAdded(const Array<UInt> & nodes_list,
                     const NewNodesEvent & event) override;
   /// function to implement to react on  akantu::RemovedNodesEvent
   void onNodesRemoved(const Array<UInt> & nodes_list,
                       const Array<UInt> & new_numbering,
                       const RemovedNodesEvent & event) override;
   /// function to implement to react on  akantu::NewElementsEvent
   void onElementsAdded(const Array<Element> & elements_list,
                        const NewElementsEvent & event) override;
   /// function to implement to react on  akantu::RemovedElementsEvent
   void onElementsRemoved(const Array<Element> & elements_list,
                          const ElementTypeMapArray<UInt> & new_numbering,
                          const RemovedElementsEvent & event) override;
   /// function to implement to react on  akantu::ChangedElementsEvent
   void onElementsChanged(const Array<Element> & old_elements_list,
                          const Array<Element> & new_elements_list,
                          const ElementTypeMapArray<UInt> & new_numbering,
                          const ChangedElementsEvent & event) override;
 
   /* ------------------------------------------------------------------------ */
   /* Virtual methods from Model */
   /* ------------------------------------------------------------------------ */
 protected:
   /// get some default values for derived classes
   std::tuple<ID, TimeStepSolverType>
   getDefaultSolverID(const AnalysisMethod & method) override;
 
   ModelSolverOptions
   getDefaultSolverOptions(const TimeStepSolverType & type) const override;
 
   UInt getNbDegreeOfFreedom(const ElementType & type) const;
 
   /* ------------------------------------------------------------------------ */
   /* Methods                                                                  */
   /* ------------------------------------------------------------------------ */
   void initSolver(TimeStepSolverType, NonLinearSolverType) override;
 
   /// initialize the model
   void initModel() override;
 
   /// compute the stresses per elements
   void computeStresses();
 
   /// compute the nodal forces
   void assembleInternalForce();
 
   /// compute the nodal forces for an element type
   void assembleInternalForce(const ElementType & type, GhostType gt);
 
   /// assemble the stiffness matrix
   void assembleStiffnessMatrix();
 
   /// assemble the mass matrix for consistent mass resolutions
   void assembleMass();
 
   /// TODO remove
   void computeRotationMatrix(const ElementType & type);
 
 protected:
   /// compute Rotation Matrices
   template <const ElementType type>
   void computeRotationMatrix(__attribute__((unused)) Array<Real> & rotations) {}
 
   /* ------------------------------------------------------------------------ */
   /* Mass (structural_mechanics_model_mass.cc) */
   /* ------------------------------------------------------------------------ */
 
   /// assemble the mass matrix for either _ghost or _not_ghost elements
   void assembleMass(GhostType ghost_type);
 
   /// computes rho
   void computeRho(Array<Real> & rho, ElementType type, GhostType ghost_type);
 
   /// finish the computation of residual to solve in increment
   void updateResidualInternal();
 
   /* ------------------------------------------------------------------------ */
 private:
   template <ElementType type> void assembleStiffnessMatrix();
   template <ElementType type> void assembleMass();
   template <ElementType type> void computeStressOnQuad();
   template <ElementType type>
   void computeTangentModuli(Array<Real> & tangent_moduli);
 
   /* ------------------------------------------------------------------------ */
   /* Dumpable interface                                                       */
   /* ------------------------------------------------------------------------ */
 public:
   virtual dumper::Field * createNodalFieldReal(const std::string & field_name,
                                                const std::string & group_name,
                                                bool padding_flag);
 
   virtual dumper::Field * createNodalFieldBool(const std::string & field_name,
                                                const std::string & group_name,
                                                bool padding_flag);
 
   virtual dumper::Field *
   createElementalField(const std::string & field_name,
                        const std::string & group_name, bool padding_flag,
                        const ElementKind & kind,
                        const std::string & fe_engine_id = "");
 
   /* ------------------------------------------------------------------------ */
   /* Accessors                                                                */
   /* ------------------------------------------------------------------------ */
 public:
   /// set the value of the time step
   // void setTimeStep(Real time_step, const ID & solver_id = "") override;
 
   /// return the dimension of the system space
   AKANTU_GET_MACRO(SpatialDimension, spatial_dimension, UInt);
 
   /// get the StructuralMechanicsModel::displacement vector
   AKANTU_GET_MACRO(Displacement, *displacement_rotation, Array<Real> &);
 
   /// get the StructuralMechanicsModel::velocity vector
   AKANTU_GET_MACRO(Velocity, *velocity, Array<Real> &);
 
   /// get    the    StructuralMechanicsModel::acceleration    vector,   updated
   /// by
   /// StructuralMechanicsModel::updateAcceleration
   AKANTU_GET_MACRO(Acceleration, *acceleration, Array<Real> &);
 
   /// get the StructuralMechanicsModel::external_force vector
   AKANTU_GET_MACRO(ExternalForce, *external_force, Array<Real> &);
 
   /// get the StructuralMechanicsModel::internal_force vector (boundary forces)
   AKANTU_GET_MACRO(InternalForce, *internal_force, Array<Real> &);
 
   /// get the StructuralMechanicsModel::boundary vector
   AKANTU_GET_MACRO(BlockedDOFs, *blocked_dofs, Array<bool> &);
 
   AKANTU_GET_MACRO_BY_ELEMENT_TYPE_CONST(RotationMatrix, rotation_matrix, Real);
 
   AKANTU_GET_MACRO_BY_ELEMENT_TYPE_CONST(Stress, stress, Real);
 
   AKANTU_GET_MACRO_BY_ELEMENT_TYPE(ElementMaterial, element_material, UInt);
 
   AKANTU_GET_MACRO_BY_ELEMENT_TYPE(Set_ID, set_ID, UInt);
 
   void addMaterial(StructuralMaterial & material) {
     materials.push_back(material);
   }
 
   const StructuralMaterial & getMaterial(const Element & element) const {
     return materials[element_material(element)];
   }
 
   /* ------------------------------------------------------------------------ */
   /* Boundaries (structural_mechanics_model_boundary.cc)                      */
   /* ------------------------------------------------------------------------ */
 public:
   /// Compute Linear load function set in global axis
   template <ElementType type>
   void computeForcesByGlobalTractionArray(const Array<Real> & tractions);
 
   /// Compute Linear load function set in local axis
   template <ElementType type>
   void computeForcesByLocalTractionArray(const Array<Real> & tractions);
 
   /// compute force vector from a function(x,y,momentum) that describe stresses
   // template <ElementType type>
   // void computeForcesFromFunction(BoundaryFunction in_function,
   //                                BoundaryFunctionType function_type);
 
   /* ------------------------------------------------------------------------ */
   /* Class Members                                                            */
   /* ------------------------------------------------------------------------ */
 private:
   /// time step
   Real time_step;
 
   /// conversion coefficient form force/mass to acceleration
   Real f_m2a;
 
   /// displacements array
   Array<Real> * displacement_rotation{nullptr};
 
   /// velocities array
   Array<Real> * velocity{nullptr};
 
   /// accelerations array
   Array<Real> * acceleration{nullptr};
 
   /// forces array
   Array<Real> * internal_force{nullptr};
 
   /// forces array
   Array<Real> * external_force{nullptr};
 
   /// lumped mass array
   Array<Real> * mass{nullptr};
 
   /// boundaries array
   Array<bool> * blocked_dofs{nullptr};
 
   /// stress array
   ElementTypeMapArray<Real> stress;
 
   ElementTypeMapArray<UInt> element_material;
 
   // Define sets of beams
   ElementTypeMapArray<UInt> set_ID;
 
   /// number of degre of freedom
   UInt nb_degree_of_freedom;
 
   // Rotation matrix
   ElementTypeMapArray<Real> rotation_matrix;
 
   // /// analysis method check the list in akantu::AnalysisMethod
   // AnalysisMethod method;
 
   /// flag defining if the increment must be computed or not
   bool increment_flag;
 
   /* ------------------------------------------------------------------------ */
   std::vector<StructuralMaterial> materials;
 };
 
 } // namespace akantu
 
 #endif /* __AKANTU_STRUCTURAL_MECHANICS_MODEL_HH__ */
diff --git a/src/model/structural_mechanics/structural_mechanics_model_boundary.cc b/src/model/structural_mechanics/structural_mechanics_model_boundary.cc
index 10f0b31f2..8ed826ad6 100644
--- a/src/model/structural_mechanics/structural_mechanics_model_boundary.cc
+++ b/src/model/structural_mechanics/structural_mechanics_model_boundary.cc
@@ -1,47 +1,46 @@
 /**
  * @file   structural_mechanics_model_boundary.cc
  *
  * @author Fabian Barras <fabian.barras@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  * @author Damien Spielmann <damien.spielmann@epfl.ch>
  *
  * @date creation: Fri Jul 15 2011
- * @date last modification: Sun Oct 19 2014
+ * @date last modification: Fri Oct 13 2017
  *
  * @brief  Implementation of the boundary conditions for
  * StructuralMechanicsModel
  *
  * @section LICENSE
  *
- * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
- * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
- * Solides)
+ * 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
+ * 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
+ * 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 "integrator_gauss.hh"
 #include "model.hh"
 #include "shape_structural.hh"
 #include "structural_mechanics_model.hh"
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 /* -------------------------------------------------------------------------- */
 
 } // akantu
diff --git a/src/model/structural_mechanics/structural_mechanics_model_inline_impl.cc b/src/model/structural_mechanics/structural_mechanics_model_inline_impl.cc
index 0a4bd6679..ebf76f302 100644
--- a/src/model/structural_mechanics/structural_mechanics_model_inline_impl.cc
+++ b/src/model/structural_mechanics/structural_mechanics_model_inline_impl.cc
@@ -1,370 +1,371 @@
 /**
  * @file   structural_mechanics_model_inline_impl.cc
  *
  * @author Fabian Barras <fabian.barras@epfl.ch>
+ * @author Lucas Frerot <lucas.frerot@epfl.ch>
  * @author Sébastien Hartmann <sebastien.hartmann@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  * @author Damien Spielmann <damien.spielmann@epfl.ch>
  *
  * @date creation: Fri Jul 15 2011
- * @date last modification: Thu Oct 15 2015
+ * @date last modification: Tue Feb 20 2018
  *
  * @brief  Implementation of inline functions of StructuralMechanicsModel
  *
  * @section LICENSE
  *
- * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
- * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
- * Solides)
+ * 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
+ * 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
+ * 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 "structural_mechanics_model.hh"
 /* -------------------------------------------------------------------------- */
 
 #ifndef __AKANTU_STRUCTURAL_MECHANICS_MODEL_INLINE_IMPL_CC__
 #define __AKANTU_STRUCTURAL_MECHANICS_MODEL_INLINE_IMPL_CC__
 
 namespace akantu {
 /* -------------------------------------------------------------------------- */
 inline UInt
 StructuralMechanicsModel::getNbDegreeOfFreedom(const ElementType & type) const {
   UInt ndof = 0;
 #define GET_(type) ndof = ElementClass<type>::getNbDegreeOfFreedom()
   AKANTU_BOOST_KIND_ELEMENT_SWITCH(GET_, _ek_structural);
 #undef GET_
 
   return ndof;
 }
 
 /* -------------------------------------------------------------------------- */
 template <ElementType type>
 void StructuralMechanicsModel::computeTangentModuli(
     Array<Real> & /*tangent_moduli*/) {
   AKANTU_TO_IMPLEMENT();
 }
 } // namespace akantu
 
 #include "structural_element_bernoulli_beam_2.hh"
 #include "structural_element_bernoulli_beam_3.hh"
 #include "structural_element_kirchhoff_shell.hh"
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 template <ElementType type>
 void StructuralMechanicsModel::assembleStiffnessMatrix() {
   AKANTU_DEBUG_IN();
 
   auto nb_element = getFEEngine().getMesh().getNbElement(type);
   auto nb_nodes_per_element = Mesh::getNbNodesPerElement(type);
   auto nb_quadrature_points = getFEEngine().getNbIntegrationPoints(type);
   auto tangent_size = ElementClass<type>::getNbStressComponents();
 
   auto tangent_moduli = std::make_unique<Array<Real>>(
       nb_element * nb_quadrature_points, tangent_size * tangent_size,
       "tangent_stiffness_matrix");
   computeTangentModuli<type>(*tangent_moduli);
 
   /// compute @f$\mathbf{B}^t * \mathbf{D} * \mathbf{B}@f$
   UInt bt_d_b_size = nb_degree_of_freedom * nb_nodes_per_element;
 
   auto bt_d_b = std::make_unique<Array<Real>>(
       nb_element * nb_quadrature_points, bt_d_b_size * bt_d_b_size, "B^t*D*B");
 
   const auto & b = getFEEngine().getShapesDerivatives(type);
 
   Matrix<Real> BtD(bt_d_b_size, tangent_size);
 
   for (auto && tuple :
        zip(make_view(b, tangent_size, bt_d_b_size),
            make_view(*tangent_moduli, tangent_size, tangent_size),
            make_view(*bt_d_b, bt_d_b_size, bt_d_b_size))) {
     auto & B = std::get<0>(tuple);
     auto & D = std::get<1>(tuple);
     auto & BtDB = std::get<2>(tuple);
     BtD.mul<true, false>(B, D);
     BtDB.template mul<false, false>(BtD, B);
   }
 
   /// compute @f$ k_e = \int_e \mathbf{B}^t * \mathbf{D} * \mathbf{B}@f$
   auto int_bt_d_b = std::make_unique<Array<Real>>(
       nb_element, bt_d_b_size * bt_d_b_size, "int_B^t*D*B");
 
   getFEEngine().integrate(*bt_d_b, *int_bt_d_b, bt_d_b_size * bt_d_b_size,
                           type);
 
   getDOFManager().assembleElementalMatricesToMatrix(
       "K", "displacement", *int_bt_d_b, type, _not_ghost, _symmetric);
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <ElementType type>
 void StructuralMechanicsModel::computeStressOnQuad() {
   AKANTU_DEBUG_IN();
 
   Array<Real> & sigma = stress(type, _not_ghost);
 
   auto nb_element = mesh.getNbElement(type);
   auto nb_nodes_per_element = Mesh::getNbNodesPerElement(type);
   auto nb_quadrature_points = getFEEngine().getNbIntegrationPoints(type);
   auto tangent_size = ElementClass<type>::getNbStressComponents();
 
   auto tangent_moduli = std::make_unique<Array<Real>>(
       nb_element * nb_quadrature_points, tangent_size * tangent_size,
       "tangent_stiffness_matrix");
 
   computeTangentModuli<type>(*tangent_moduli);
 
   /// compute DB
   auto d_b_size = nb_degree_of_freedom * nb_nodes_per_element;
 
   auto d_b = std::make_unique<Array<Real>>(nb_element * nb_quadrature_points,
                                            d_b_size * tangent_size, "D*B");
 
   const auto & b = getFEEngine().getShapesDerivatives(type);
 
   auto B = b.begin(tangent_size, d_b_size);
   auto D = tangent_moduli->begin(tangent_size, tangent_size);
   auto D_B = d_b->begin(tangent_size, d_b_size);
 
   for (UInt e = 0; e < nb_element; ++e) {
     for (UInt q = 0; q < nb_quadrature_points; ++q, ++B, ++D, ++D_B) {
       D_B->template mul<false, false>(*D, *B);
     }
   }
 
   /// compute DBu
   D_B = d_b->begin(tangent_size, d_b_size);
   auto DBu = sigma.begin(tangent_size);
 
   Array<Real> u_el(0, d_b_size);
   FEEngine::extractNodalToElementField(mesh, *displacement_rotation, u_el,
                                        type);
 
   auto ug = u_el.begin(d_b_size);
 
   // No need to rotate because B is post-multiplied
   for (UInt e = 0; e < nb_element; ++e, ++ug) {
     for (UInt q = 0; q < nb_quadrature_points; ++q, ++D_B, ++DBu) {
       DBu->template mul<false>(*D_B, *ug);
     }
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <ElementType type>
 void StructuralMechanicsModel::computeForcesByLocalTractionArray(
     const Array<Real> & tractions) {
   AKANTU_DEBUG_IN();
 
 #if 0
   UInt nb_element = getFEEngine().getMesh().getNbElement(type);
   UInt nb_nodes_per_element =
       getFEEngine().getMesh().getNbNodesPerElement(type);
   UInt nb_quad = getFEEngine().getNbIntegrationPoints(type);
 
   // check dimension match
   AKANTU_DEBUG_ASSERT(
       Mesh::getSpatialDimension(type) == getFEEngine().getElementDimension(),
       "element type dimension does not match the dimension of boundaries : "
           << getFEEngine().getElementDimension()
           << " != " << Mesh::getSpatialDimension(type));
 
   // check size of the vector
   AKANTU_DEBUG_ASSERT(
       tractions.size() == nb_quad * nb_element,
       "the size of the vector should be the total number of quadrature points");
 
   // check number of components
   AKANTU_DEBUG_ASSERT(tractions.getNbComponent() == nb_degree_of_freedom,
                       "the number of components should be the spatial "
                       "dimension of the problem");
 
   Array<Real> Nvoigt(nb_element * nb_quad, nb_degree_of_freedom *
                                                nb_degree_of_freedom *
                                                nb_nodes_per_element);
   transferNMatrixToSymVoigtNMatrix<type>(Nvoigt);
 
   Array<Real>::const_matrix_iterator N_it = Nvoigt.begin(
       nb_degree_of_freedom, nb_degree_of_freedom * nb_nodes_per_element);
   Array<Real>::const_matrix_iterator T_it =
       rotation_matrix(type).begin(nb_degree_of_freedom * nb_nodes_per_element,
                                   nb_degree_of_freedom * nb_nodes_per_element);
   auto te_it =
       tractions.begin(nb_degree_of_freedom);
 
   Array<Real> funct(nb_element * nb_quad,
                     nb_degree_of_freedom * nb_nodes_per_element, 0.);
   Array<Real>::iterator<Vector<Real>> Fe_it =
       funct.begin(nb_degree_of_freedom * nb_nodes_per_element);
 
   Vector<Real> fe(nb_degree_of_freedom * nb_nodes_per_element);
   for (UInt e = 0; e < nb_element; ++e, ++T_it) {
     const Matrix<Real> & T = *T_it;
     for (UInt q = 0; q < nb_quad; ++q, ++N_it, ++te_it, ++Fe_it) {
       const Matrix<Real> & N = *N_it;
       const Vector<Real> & te = *te_it;
       Vector<Real> & Fe = *Fe_it;
 
       // compute N^t tl
       fe.mul<true>(N, te);
       // turn N^t tl back in the global referential
       Fe.mul<true>(T, fe);
     }
   }
 
   // allocate the vector that will contain the integrated values
   std::stringstream name;
   name << id << type << ":integral_boundary";
   Array<Real> int_funct(nb_element, nb_degree_of_freedom * nb_nodes_per_element,
                         name.str());
 
   // do the integration
   getFEEngine().integrate(funct, int_funct,
                           nb_degree_of_freedom * nb_nodes_per_element, type);
 
   // assemble the result into force vector
   getFEEngine().assembleArray(int_funct, *force_momentum,
                               dof_synchronizer->getLocalDOFEquationNumbers(),
                               nb_degree_of_freedom, type);
 #endif
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <ElementType type>
 void StructuralMechanicsModel::computeForcesByGlobalTractionArray(
     const Array<Real> & traction_global) {
   AKANTU_DEBUG_IN();
 #if 0
   UInt nb_element = mesh.getNbElement(type);
   UInt nb_quad = getFEEngine().getNbIntegrationPoints(type);
   UInt nb_nodes_per_element =
       getFEEngine().getMesh().getNbNodesPerElement(type);
 
   std::stringstream name;
   name << id << ":structuralmechanics:imposed_linear_load";
   Array<Real> traction_local(nb_element * nb_quad, nb_degree_of_freedom,
                              name.str());
 
   Array<Real>::const_matrix_iterator T_it =
       rotation_matrix(type).begin(nb_degree_of_freedom * nb_nodes_per_element,
                                   nb_degree_of_freedom * nb_nodes_per_element);
 
   Array<Real>::const_iterator<Vector<Real>> Te_it =
       traction_global.begin(nb_degree_of_freedom);
   Array<Real>::iterator<Vector<Real>> te_it =
       traction_local.begin(nb_degree_of_freedom);
 
   Matrix<Real> R(nb_degree_of_freedom, nb_degree_of_freedom);
   for (UInt e = 0; e < nb_element; ++e, ++T_it) {
     const Matrix<Real> & T = *T_it;
     for (UInt i = 0; i < nb_degree_of_freedom; ++i)
       for (UInt j = 0; j < nb_degree_of_freedom; ++j)
         R(i, j) = T(i, j);
 
     for (UInt q = 0; q < nb_quad; ++q, ++Te_it, ++te_it) {
       const Vector<Real> & Te = *Te_it;
       Vector<Real> & te = *te_it;
       // turn the traction in the local referential
       te.mul<false>(R, Te);
     }
   }
 
   computeForcesByLocalTractionArray<type>(traction_local);
 #endif
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 /**
  * @param myf pointer  to a function that fills a  vector/tensor with respect to
  * passed coordinates
  */
 #if 0
 template <ElementType type>
 inline void StructuralMechanicsModel::computeForcesFromFunction(
     BoundaryFunction myf, BoundaryFunctionType function_type) {
   /** function type is
    ** _bft_forces : linear load is given
    ** _bft_stress : stress function is given -> Not already done for this kind
    *of model
    */
 
   std::stringstream name;
   name << id << ":structuralmechanics:imposed_linear_load";
   Array<Real> lin_load(0, nb_degree_of_freedom, name.str());
   name.clear();
 
   UInt offset = nb_degree_of_freedom;
 
   // prepare the loop over element types
   UInt nb_quad = getFEEngine().getNbIntegrationPoints(type);
   UInt nb_element = getFEEngine().getMesh().getNbElement(type);
 
   name.clear();
   name << id << ":structuralmechanics:quad_coords";
   Array<Real> quad_coords(nb_element * nb_quad, spatial_dimension,
                           "quad_coords");
 
   getFEEngineClass<MyFEEngineType>()
       .getShapeFunctions()
       .interpolateOnIntegrationPoints<type>(getFEEngine().getMesh().getNodes(),
                                             quad_coords, spatial_dimension);
   getFEEngineClass<MyFEEngineType>()
       .getShapeFunctions()
       .interpolateOnIntegrationPoints<type>(
           getFEEngine().getMesh().getNodes(), quad_coords, spatial_dimension,
           _not_ghost, empty_filter, true, 0, 1, 1);
   if (spatial_dimension == 3)
     getFEEngineClass<MyFEEngineType>()
         .getShapeFunctions()
         .interpolateOnIntegrationPoints<type>(
             getFEEngine().getMesh().getNodes(), quad_coords, spatial_dimension,
             _not_ghost, empty_filter, true, 0, 2, 2);
   lin_load.resize(nb_element * nb_quad);
   Real * imposed_val = lin_load.storage();
 
   /// sigma/load on each quadrature points
   Real * qcoord = quad_coords.storage();
   for (UInt el = 0; el < nb_element; ++el) {
     for (UInt q = 0; q < nb_quad; ++q) {
       myf(qcoord, imposed_val, NULL, 0);
       imposed_val += offset;
       qcoord += spatial_dimension;
     }
   }
 
   switch (function_type) {
   case _bft_traction_local:
     computeForcesByLocalTractionArray<type>(lin_load);
     break;
   case _bft_traction:
     computeForcesByGlobalTractionArray<type>(lin_load);
     break;
   default:
     break;
   }
 }
 #endif
 } // namespace akantu
 
 #endif /* __AKANTU_STRUCTURAL_MECHANICS_MODEL_INLINE_IMPL_CC__ */
diff --git a/src/model/structural_mechanics/structural_mechanics_model_mass.cc b/src/model/structural_mechanics/structural_mechanics_model_mass.cc
index b24eeb0d2..d26224be8 100644
--- a/src/model/structural_mechanics/structural_mechanics_model_mass.cc
+++ b/src/model/structural_mechanics/structural_mechanics_model_mass.cc
@@ -1,76 +1,79 @@
 /**
  * @file   structural_mechanics_model_mass.cc
  *
+ * @author Lucas Frerot <lucas.frerot@epfl.ch>
  * @author Sébastien Hartmann <sebastien.hartmann@epfl.ch>
+ * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Mon Jul 07 2014
- * @date last modification: Thu Oct 15 2015
+ * @date last modification: Fri Dec 15 2017
  *
  * @brief  function handling mass computation
  *
  * @section LICENSE
  *
- * Copyright  (©)  2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de Lausanne)
+ * 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
+ * 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
+ * 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 "integrator_gauss.hh"
 #include "material.hh"
 #include "shape_structural.hh"
 #include "structural_mechanics_model.hh"
 
 /* -------------------------------------------------------------------------- */
 namespace akantu {
 
 class ComputeRhoFunctorStruct {
 public:
   explicit ComputeRhoFunctorStruct(const StructuralMechanicsModel & model)
       : model(model){};
 
   void operator()(Matrix<Real> & rho, const Element & element) const {
     Real mat_rho = model.getMaterial(element).rho;
     rho.set(mat_rho);
   }
 
 private:
   const StructuralMechanicsModel & model;
 };
 
 /* -------------------------------------------------------------------------- */
 void StructuralMechanicsModel::assembleMass() {
   AKANTU_DEBUG_IN();
 
   assembleMass(_not_ghost);
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void StructuralMechanicsModel::assembleMass(GhostType ghost_type) {
   AKANTU_DEBUG_IN();
   MyFEEngineType & fem = getFEEngineClass<MyFEEngineType>();
   ComputeRhoFunctorStruct compute_rho(*this);
 
   for (auto type :
        mesh.elementTypes(spatial_dimension, ghost_type, _ek_structural)) {
     fem.assembleFieldMatrix(compute_rho, "M", "displacement",
                             this->getDOFManager(), type, ghost_type);
   }
   AKANTU_DEBUG_OUT();
 }
 
 } // akantu
diff --git a/src/model/time_step_solver.hh b/src/model/time_step_solver.hh
index dfef977ca..4437296ea 100644
--- a/src/model/time_step_solver.hh
+++ b/src/model/time_step_solver.hh
@@ -1,137 +1,138 @@
 /**
  * @file   time_step_solver.hh
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
- * @date   Mon Aug 24 12:42:04 2015
+ * @date creation: Fri Jun 18 2010
+ * @date last modification: Wed Feb 21 2018
  *
  * @brief  This corresponding to the time step evolution solver
  *
  * @section LICENSE
  *
- * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * 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
+ * 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
+ * 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_array.hh"
 #include "aka_memory.hh"
 #include "integration_scheme.hh"
 #include "parameter_registry.hh"
 #include "solver_callback.hh"
 /* -------------------------------------------------------------------------- */
 
 #ifndef __AKANTU_TIME_STEP_SOLVER_HH__
 #define __AKANTU_TIME_STEP_SOLVER_HH__
 
 namespace akantu {
 class DOFManager;
 class NonLinearSolver;
 }
 
 namespace akantu {
 
 class TimeStepSolver : public Memory,
                        public ParameterRegistry,
                        public SolverCallback {
   /* ------------------------------------------------------------------------ */
   /* Constructors/Destructors                                                 */
   /* ------------------------------------------------------------------------ */
 public:
   TimeStepSolver(DOFManager & dof_manager, const TimeStepSolverType & type,
                  NonLinearSolver & non_linear_solver, const ID & id,
                  UInt memory_id);
   ~TimeStepSolver() override;
 
   /* ------------------------------------------------------------------------ */
   /* Methods                                                                  */
   /* ------------------------------------------------------------------------ */
 public:
   /// solves on step
   virtual void solveStep(SolverCallback & solver_callback) = 0;
 
   /// register an integration scheme for a given dof
   virtual void
   setIntegrationScheme(const ID & dof_id, const IntegrationSchemeType & type,
                        IntegrationScheme::SolutionType solution_type =
                            IntegrationScheme::_not_defined) = 0;
 
   /// replies if a integration scheme has been set
   virtual bool hasIntegrationScheme(const ID & dof_id) const = 0;
   /* ------------------------------------------------------------------------ */
   /* Solver Callback interface                                                */
   /* ------------------------------------------------------------------------ */
 public:
   /// implementation of the SolverCallback::getMatrixType()
   MatrixType getMatrixType(const ID &) final { return _mt_not_defined; }
   /// implementation of the SolverCallback::predictor()
   void predictor() override;
   /// implementation of the SolverCallback::corrector()
   void corrector() override;
   /// implementation of the SolverCallback::assembleJacobian()
   void assembleMatrix(const ID & matrix_id) override;
   /// implementation of the SolverCallback::assembleJacobian()
   void assembleLumpedMatrix(const ID & matrix_id) final;
   /// implementation of the SolverCallback::assembleResidual()
   void assembleResidual() override;
   /// implementation of the SolverCallback::assembleResidual()
   void assembleResidual(const ID & residual_part) override;
 
   void beforeSolveStep() override;
   void afterSolveStep() override;
 
   bool canSplitResidual() { return solver_callback->canSplitResidual(); }
   /* ------------------------------------------------------------------------ */
   /* Accessor                                                                 */
   /* ------------------------------------------------------------------------ */
 public:
   AKANTU_GET_MACRO(TimeStep, time_step, Real);
   AKANTU_SET_MACRO(TimeStep, time_step, Real);
 
   AKANTU_GET_MACRO(NonLinearSolver, non_linear_solver, const NonLinearSolver &);
   AKANTU_GET_MACRO_NOT_CONST(NonLinearSolver, non_linear_solver,
                              NonLinearSolver &);
 
 protected:
   MatrixType getCommonMatrixType();
 
   /* ------------------------------------------------------------------------ */
   /* Class Members                                                            */
   /* ------------------------------------------------------------------------ */
 protected:
   /// Underlying dof manager containing the dof to treat
   DOFManager & _dof_manager;
 
   /// Type of solver
   TimeStepSolverType type;
 
   /// The time step for this solver
   Real time_step;
 
   /// Temporary storage for solver callback
   SolverCallback * solver_callback;
 
   /// NonLinearSolver used by this tome step solver
   NonLinearSolver & non_linear_solver;
 
   /// List of required matrices
   std::map<std::string, MatrixType> needed_matrices;
 };
 
 } // akantu
 
 #endif /* __AKANTU_TIME_STEP_SOLVER_HH__ */
diff --git a/src/model/time_step_solvers/time_step_solver.cc b/src/model/time_step_solvers/time_step_solver.cc
index d936db10b..04bb9f871 100644
--- a/src/model/time_step_solvers/time_step_solver.cc
+++ b/src/model/time_step_solvers/time_step_solver.cc
@@ -1,177 +1,177 @@
 /**
  * @file   time_step_solver.cc
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
- * @date   Mon Oct 12 16:56:43 2015
+ * @date creation: Tue Aug 18 2015
+ * @date last modification: Wed Feb 21 2018
  *
  * @brief  Implementation of common part of TimeStepSolvers
  *
  * @section LICENSE
  *
- * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
- * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
- * Solides)
+ * Copyright (©) 2015-2018 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
- * terms  of the  GNU Lesser  General Public  License as  published by  the Free
+ * 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
+ * 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 "time_step_solver.hh"
 #include "dof_manager.hh"
 #include "non_linear_solver.hh"
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 TimeStepSolver::TimeStepSolver(DOFManager & dof_manager,
                                const TimeStepSolverType & type,
                                NonLinearSolver & non_linear_solver,
                                const ID & id, UInt memory_id)
     : Memory(id, memory_id), SolverCallback(dof_manager),
       _dof_manager(dof_manager), type(type), time_step(0.),
       solver_callback(nullptr), non_linear_solver(non_linear_solver) {
   this->registerSubRegistry("non_linear_solver", non_linear_solver);
 }
 
 /* -------------------------------------------------------------------------- */
 TimeStepSolver::~TimeStepSolver() = default;
 
 /* -------------------------------------------------------------------------- */
 MatrixType TimeStepSolver::getCommonMatrixType() {
   MatrixType common_type = _mt_not_defined;
   for (auto & pair : needed_matrices) {
     auto & type = pair.second;
     if (type == _mt_not_defined) {
       type = this->solver_callback->getMatrixType(pair.first);
     }
 
     common_type = std::min(common_type, type);
   }
 
   AKANTU_DEBUG_ASSERT(common_type != _mt_not_defined,
                       "No type defined for the matrices");
 
   return common_type;
 }
 
 /* -------------------------------------------------------------------------- */
 void TimeStepSolver::predictor() {
   AKANTU_DEBUG_ASSERT(
       this->solver_callback != nullptr,
       "This function cannot be called if the solver_callback is not set");
 
   this->solver_callback->predictor();
 }
 
 /* -------------------------------------------------------------------------- */
 void TimeStepSolver::corrector() {
   AKANTU_DEBUG_ASSERT(
       this->solver_callback != nullptr,
       "This function cannot be called if the solver_callback is not set");
 
   this->solver_callback->corrector();
 }
 
 /* -------------------------------------------------------------------------- */
 void TimeStepSolver::beforeSolveStep() {
   AKANTU_DEBUG_ASSERT(
       this->solver_callback != nullptr,
       "This function cannot be called if the solver_callback is not set");
 
   this->solver_callback->beforeSolveStep();
 }
 
 /* -------------------------------------------------------------------------- */
 void TimeStepSolver::afterSolveStep() {
   AKANTU_DEBUG_ASSERT(
       this->solver_callback != nullptr,
       "This function cannot be called if the solver_callback is not set");
 
   this->solver_callback->afterSolveStep();
 }
 
 /* -------------------------------------------------------------------------- */
 void TimeStepSolver::assembleLumpedMatrix(const ID & matrix_id) {
   AKANTU_DEBUG_ASSERT(
       this->solver_callback != nullptr,
       "This function cannot be called if the solver_callback is not set");
 
   if (not _dof_manager.hasLumpedMatrix(matrix_id))
     _dof_manager.getNewLumpedMatrix(matrix_id);
 
   this->solver_callback->assembleLumpedMatrix(matrix_id);
 }
 
 /* -------------------------------------------------------------------------- */
 void TimeStepSolver::assembleMatrix(const ID & matrix_id) {
   AKANTU_DEBUG_ASSERT(
       this->solver_callback != nullptr,
       "This function cannot be called if the solver_callback is not set");
 
   auto common_type = this->getCommonMatrixType();
 
   if (matrix_id != "J") {
     auto type = needed_matrices[matrix_id];
     if (type == _mt_not_defined)
       return;
 
     if (not _dof_manager.hasMatrix(matrix_id)) {
       _dof_manager.getNewMatrix(matrix_id, type);
     }
 
     this->solver_callback->assembleMatrix(matrix_id);
     return;
   }
 
   if (not _dof_manager.hasMatrix("J"))
     _dof_manager.getNewMatrix("J", common_type);
 
   for (auto & pair : needed_matrices) {
     auto type = pair.second;
     if (type == _mt_not_defined)
       continue;
 
     auto name = pair.first;
     if (not _dof_manager.hasMatrix(name))
       _dof_manager.getNewMatrix(name, type);
 
     this->solver_callback->assembleMatrix(name);
   }
 }
 
 /* -------------------------------------------------------------------------- */
 void TimeStepSolver::assembleResidual() {
   AKANTU_DEBUG_ASSERT(
       this->solver_callback != nullptr,
       "This function cannot be called if the solver_callback is not set");
 
   this->_dof_manager.clearResidual();
   this->solver_callback->assembleResidual();
 }
 
 /* -------------------------------------------------------------------------- */
 void TimeStepSolver::assembleResidual(const ID & residual_part) {
   AKANTU_DEBUG_ASSERT(
       this->solver_callback != nullptr,
       "This function cannot be called if the solver_callback is not set");
 
   this->solver_callback->assembleResidual(residual_part);
 }
 
 /* -------------------------------------------------------------------------- */
 
 } // namespace akantu
diff --git a/src/model/time_step_solvers/time_step_solver_default.cc b/src/model/time_step_solvers/time_step_solver_default.cc
index 371050e61..cec055b5a 100644
--- a/src/model/time_step_solvers/time_step_solver_default.cc
+++ b/src/model/time_step_solvers/time_step_solver_default.cc
@@ -1,309 +1,310 @@
 /**
  * @file   time_step_solver_default.cc
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
- * @date   Wed Sep 16 10:20:55 2015
+ * @date creation: Tue Sep 15 2015
+ * @date last modification: Wed Feb 21 2018
  *
  * @brief  Default implementation of the time step solver
  *
  * @section LICENSE
  *
- * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * Copyright (©) 2015-2018 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
- * terms  of the  GNU Lesser  General Public  License as  published by  the Free
+ * 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
+ * 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 "time_step_solver_default.hh"
 #include "dof_manager_default.hh"
 #include "integration_scheme_1st_order.hh"
 #include "integration_scheme_2nd_order.hh"
 #include "mesh.hh"
 #include "non_linear_solver.hh"
 #include "pseudo_time.hh"
 #include "sparse_matrix_aij.hh"
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 TimeStepSolverDefault::TimeStepSolverDefault(
     DOFManagerDefault & dof_manager, const TimeStepSolverType & type,
     NonLinearSolver & non_linear_solver, const ID & id, UInt memory_id)
     : TimeStepSolver(dof_manager, type, non_linear_solver, id, memory_id),
       dof_manager(dof_manager), is_mass_lumped(false) {
   switch (type) {
   case _tsst_dynamic:
     break;
   case _tsst_dynamic_lumped:
     this->is_mass_lumped = true;
     break;
   case _tsst_static:
     /// initialize a static time solver for callback dofs
     break;
   default:
     AKANTU_TO_IMPLEMENT();
   }
 }
 
 /* -------------------------------------------------------------------------- */
 void TimeStepSolverDefault::setIntegrationScheme(
     const ID & dof_id, const IntegrationSchemeType & type,
     IntegrationScheme::SolutionType solution_type) {
   if (this->integration_schemes.find(dof_id) !=
       this->integration_schemes.end()) {
     AKANTU_EXCEPTION("Their DOFs "
                      << dof_id
                      << "  have already an integration scheme associated");
   }
 
   std::unique_ptr<IntegrationScheme> integration_scheme;
   if (this->is_mass_lumped) {
     switch (type) {
     case _ist_forward_euler: {
       integration_scheme = std::make_unique<ForwardEuler>(dof_manager, dof_id);
       break;
     }
     case _ist_central_difference: {
       integration_scheme =
           std::make_unique<CentralDifference>(dof_manager, dof_id);
       break;
     }
     default:
       AKANTU_EXCEPTION(
           "This integration scheme cannot be used in lumped dynamic");
     }
   } else {
     switch (type) {
     case _ist_pseudo_time: {
       integration_scheme = std::make_unique<PseudoTime>(dof_manager, dof_id);
       break;
     }
     case _ist_forward_euler: {
       integration_scheme = std::make_unique<ForwardEuler>(dof_manager, dof_id);
       break;
     }
     case _ist_trapezoidal_rule_1: {
       integration_scheme =
           std::make_unique<TrapezoidalRule1>(dof_manager, dof_id);
       break;
     }
     case _ist_backward_euler: {
       integration_scheme = std::make_unique<BackwardEuler>(dof_manager, dof_id);
       break;
     }
     case _ist_central_difference: {
       integration_scheme =
           std::make_unique<CentralDifference>(dof_manager, dof_id);
       break;
     }
     case _ist_fox_goodwin: {
       integration_scheme = std::make_unique<FoxGoodwin>(dof_manager, dof_id);
       break;
     }
     case _ist_trapezoidal_rule_2: {
       integration_scheme =
           std::make_unique<TrapezoidalRule2>(dof_manager, dof_id);
       break;
     }
     case _ist_linear_acceleration: {
       integration_scheme =
           std::make_unique<LinearAceleration>(dof_manager, dof_id);
       break;
     }
     case _ist_generalized_trapezoidal: {
       integration_scheme =
           std::make_unique<GeneralizedTrapezoidal>(dof_manager, dof_id);
       break;
     }
     case _ist_newmark_beta:
       integration_scheme = std::make_unique<NewmarkBeta>(dof_manager, dof_id);
       break;
     }
   }
 
   AKANTU_DEBUG_ASSERT(integration_scheme,
                       "No integration scheme was found for the provided types");
 
   auto && matrices_names = integration_scheme->getNeededMatrixList();
   for (auto && name : matrices_names) {
     needed_matrices.insert({name, _mt_not_defined});
   }
 
   this->integration_schemes[dof_id] = std::move(integration_scheme);
   this->solution_types[dof_id] = solution_type;
 
   this->integration_schemes_owner.insert(dof_id);
 }
 
 /* -------------------------------------------------------------------------- */
 bool TimeStepSolverDefault::hasIntegrationScheme(const ID & dof_id) const {
   return this->integration_schemes.find(dof_id) !=
          this->integration_schemes.end();
 }
 
 /* -------------------------------------------------------------------------- */
 TimeStepSolverDefault::~TimeStepSolverDefault() = default;
 
 /* -------------------------------------------------------------------------- */
 void TimeStepSolverDefault::solveStep(SolverCallback & solver_callback) {
   this->solver_callback = &solver_callback;
 
   this->solver_callback->beforeSolveStep();
   this->non_linear_solver.solve(*this);
   this->solver_callback->afterSolveStep();
 
   this->solver_callback = nullptr;
 }
 
 /* -------------------------------------------------------------------------- */
 void TimeStepSolverDefault::predictor() {
   AKANTU_DEBUG_IN();
 
   TimeStepSolver::predictor();
 
   for (auto & pair : this->integration_schemes) {
     auto & dof_id = pair.first;
     auto & integration_scheme = pair.second;
 
     if (this->dof_manager.hasPreviousDOFs(dof_id)) {
       this->dof_manager.savePreviousDOFs(dof_id);
     }
 
     /// integrator predictor
     integration_scheme->predictor(this->time_step);
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void TimeStepSolverDefault::corrector() {
   AKANTU_DEBUG_IN();
 
   TimeStepSolver::corrector();
 
   for (auto & pair : this->integration_schemes) {
     auto & dof_id = pair.first;
     auto & integration_scheme = pair.second;
 
     const auto & solution_type = this->solution_types[dof_id];
     integration_scheme->corrector(solution_type, this->time_step);
 
     /// computing the increment of dof if needed
     if (this->dof_manager.hasDOFsIncrement(dof_id)) {
       if (!this->dof_manager.hasPreviousDOFs(dof_id)) {
         AKANTU_DEBUG_WARNING("In order to compute the increment of "
                              << dof_id << " a 'previous' has to be registered");
         continue;
       }
 
       Array<Real> & increment = this->dof_manager.getDOFsIncrement(dof_id);
       Array<Real> & previous = this->dof_manager.getPreviousDOFs(dof_id);
 
       UInt dof_array_comp = this->dof_manager.getDOFs(dof_id).getNbComponent();
 
       auto prev_dof_it = previous.begin(dof_array_comp);
       auto incr_it = increment.begin(dof_array_comp);
       auto incr_end = increment.end(dof_array_comp);
 
       increment.copy(this->dof_manager.getDOFs(dof_id));
       for (; incr_it != incr_end; ++incr_it, ++prev_dof_it) {
         *incr_it -= *prev_dof_it;
       }
     }
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void TimeStepSolverDefault::assembleMatrix(const ID & matrix_id) {
   AKANTU_DEBUG_IN();
 
   TimeStepSolver::assembleMatrix(matrix_id);
 
   if (matrix_id != "J")
     return;
 
   for (auto & pair : this->integration_schemes) {
     auto & dof_id = pair.first;
     auto & integration_scheme = pair.second;
 
     const auto & solution_type = this->solution_types[dof_id];
 
     integration_scheme->assembleJacobian(solution_type, this->time_step);
   }
 
   this->dof_manager.applyBoundary("J");
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void TimeStepSolverDefault::assembleResidual() {
   AKANTU_DEBUG_IN();
 
   if (this->needed_matrices.find("M") != needed_matrices.end()) {
     if (this->is_mass_lumped) {
       this->assembleLumpedMatrix("M");
     } else {
       this->assembleMatrix("M");
     }
   }
 
   TimeStepSolver::assembleResidual();
 
   for (auto & pair : this->integration_schemes) {
     auto & integration_scheme = pair.second;
 
     integration_scheme->assembleResidual(this->is_mass_lumped);
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void TimeStepSolverDefault::assembleResidual(const ID & residual_part) {
   AKANTU_DEBUG_IN();
 
   if (this->needed_matrices.find("M") != needed_matrices.end()) {
     if (this->is_mass_lumped) {
       this->assembleLumpedMatrix("M");
     } else {
       this->assembleMatrix("M");
     }
   }
 
   if (residual_part != "inertial") {
     TimeStepSolver::assembleResidual(residual_part);
   }
 
   if (residual_part == "inertial") {
     for (auto & pair : this->integration_schemes) {
       auto & integration_scheme = pair.second;
 
       integration_scheme->assembleResidual(this->is_mass_lumped);
     }
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 
 } // namespace akantu
diff --git a/src/model/time_step_solvers/time_step_solver_default.hh b/src/model/time_step_solvers/time_step_solver_default.hh
index 9996f657f..8dd17fbea 100644
--- a/src/model/time_step_solvers/time_step_solver_default.hh
+++ b/src/model/time_step_solvers/time_step_solver_default.hh
@@ -1,112 +1,113 @@
 /**
  * @file   time_step_solver_default.hh
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
- * @date   Mon Aug 24 17:10:29 2015
+ * @date creation: Fri Jun 18 2010
+ * @date last modification: Wed Feb 21 2018
  *
  * @brief  Default implementation for the time stepper
  *
  * @section LICENSE
  *
- * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * 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
+ * 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
+ * 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 "integration_scheme.hh"
 #include "time_step_solver.hh"
 /* -------------------------------------------------------------------------- */
 #include <map>
 #include <set>
 /* -------------------------------------------------------------------------- */
 
 #ifndef __AKANTU_TIME_STEP_SOLVER_DEFAULT_HH__
 #define __AKANTU_TIME_STEP_SOLVER_DEFAULT_HH__
 
 namespace akantu {
 class DOFManagerDefault;
 }
 
 namespace akantu {
 
 class TimeStepSolverDefault : public TimeStepSolver {
   /* ------------------------------------------------------------------------ */
   /* Constructors/Destructors                                                 */
   /* ------------------------------------------------------------------------ */
 public:
   TimeStepSolverDefault(DOFManagerDefault & dof_manager,
                         const TimeStepSolverType & type,
                         NonLinearSolver & non_linear_solver, const ID & id,
                         UInt memory_id);
 
   ~TimeStepSolverDefault() override;
 
   /* ------------------------------------------------------------------------ */
   /* Methods                                                                  */
   /* ------------------------------------------------------------------------ */
 public:
   /// registers an integration scheme for a given dof
   void setIntegrationScheme(const ID & dof_id,
                             const IntegrationSchemeType & type,
                             IntegrationScheme::SolutionType solution_type =
                                 IntegrationScheme::_not_defined) override;
   bool hasIntegrationScheme(const ID & dof_id) const override;
 
   /// implementation of the TimeStepSolver::predictor()
   void predictor() override;
   /// implementation of the TimeStepSolver::corrector()
   void corrector() override;
   /// implementation of the TimeStepSolver::assembleMatrix()
   void assembleMatrix(const ID & matrix_id) override;
   /// implementation of the TimeStepSolver::assembleResidual()
   void assembleResidual() override;
   void assembleResidual(const ID & residual_part) override;
 
   /// implementation of the generic TimeStepSolver::solveStep()
   void solveStep(SolverCallback & solver_callback) override;
 
   /* ------------------------------------------------------------------------ */
   /* Class Members                                                            */
   /* ------------------------------------------------------------------------ */
 private:
   using DOFsIntegrationSchemes =
       std::map<ID, std::unique_ptr<IntegrationScheme>>;
   using DOFsIntegrationSchemesSolutionTypes =
       std::map<ID, IntegrationScheme::SolutionType>;
   using DOFsIntegrationSchemesOwner = std::set<ID>;
 
   /// DOFManager with its real type
   DOFManagerDefault & dof_manager;
 
   /// Underlying integration scheme per dof, \todo check what happens in dynamic
   /// in case of coupled equations
   DOFsIntegrationSchemes integration_schemes;
 
   /// defines if the solver is owner of the memory or not
   DOFsIntegrationSchemesOwner integration_schemes_owner;
 
   /// Type of corrector to use
   DOFsIntegrationSchemesSolutionTypes solution_types;
 
   /// define if the mass matrix is lumped or not
   bool is_mass_lumped;
 };
 
 } // namespace akantu
 
 #endif /* __AKANTU_TIME_STEP_SOLVER_DEFAULT_HH__ */
diff --git a/src/model/time_step_solvers/time_step_solver_default_explicit.hh b/src/model/time_step_solvers/time_step_solver_default_explicit.hh
index d23c30d3b..633730538 100644
--- a/src/model/time_step_solvers/time_step_solver_default_explicit.hh
+++ b/src/model/time_step_solvers/time_step_solver_default_explicit.hh
@@ -1,77 +1,78 @@
 /**
  * @file   time_step_solver_default_explicit.hh
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
- * @date   Mon Aug 24 14:21:44 2015
+ * @date creation: Fri Jun 18 2010
+ * @date last modification: Wed Jan 31 2018
  *
  * @brief  Default solver for explicit resolution
  *
  * @section LICENSE
  *
- * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * 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
+ * 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
+ * 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_TIME_STEP_SOLVER_DEFAULT_EXPLICIT_HH__
 #define __AKANTU_TIME_STEP_SOLVER_DEFAULT_EXPLICIT_HH__
 
 namespace akantu {
 
 class TimeStepSolverDefaultExplicit : public TimeStepSolverDefault {
   /* ------------------------------------------------------------------------ */
   /* Constructors/Destructors                                                 */
   /* ------------------------------------------------------------------------ */
 public:
   TimeStepSolverDefaultExplicit();
   virtual ~TimeStepSolverDefaultExplicit();
 
   /* ------------------------------------------------------------------------ */
   /* Methods                                                                  */
   /* ------------------------------------------------------------------------ */
 public:
   void solveStep();
 
   /* ------------------------------------------------------------------------ */
   /* Accessors                                                                */
   /* ------------------------------------------------------------------------ */
 
 public:
   /* ------------------------------------------------------------------------ */
   /* Class Members                                                            */
   /* ------------------------------------------------------------------------ */
 private:
 };
 
 /* -------------------------------------------------------------------------- */
 /* inline functions                                                           */
 /* -------------------------------------------------------------------------- */
 
 #include "time_step_solver_default_explicit_inline_impl.cc"
 
 /// standard output stream operator
 inline std::ostream & operator<<(std::ostream & stream,
                                  const TimeStepSolverDefaultExplicit & _this) {
   _this.printself(stream);
   return stream;
 }
 
 } // akantu
 
 #endif /* __AKANTU_TIME_STEP_SOLVER_DEFAULT_EXPLICIT_HH__ */
diff --git a/src/model/time_step_solvers/time_step_solver_default_solver_callback.hh b/src/model/time_step_solvers/time_step_solver_default_solver_callback.hh
index 9e0552b82..5d4c1d73d 100644
--- a/src/model/time_step_solvers/time_step_solver_default_solver_callback.hh
+++ b/src/model/time_step_solvers/time_step_solver_default_solver_callback.hh
@@ -1,63 +1,64 @@
 /**
  * @file   time_step_solver_default_solver_callback.hh
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
- * @date   Mon Sep 28 18:58:07 2015
+ * @date creation: Fri Jun 18 2010
+ * @date last modification: Wed Jan 31 2018
  *
  * @brief  Implementation of the NonLinearSolverCallback for the time step
  * solver
  *
  * @section LICENSE
  *
- * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * 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
+ * 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
+ * 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 "non_linear_solver_callback.hh"
 /* -------------------------------------------------------------------------- */
 
 #ifndef __AKANTU_TIME_STEP_SOLVER_DEFAULT_SOLVER_CALLBACK_HH__
 #define __AKANTU_TIME_STEP_SOLVER_DEFAULT_SOLVER_CALLBACK_HH__
 
 namespace akantu {
 
 class TimeStepSolverCallback : public NonLinearSolverCallback {
   /* ------------------------------------------------------------------------ */
   /* Methods                                                                  */
   /* ------------------------------------------------------------------------ */
 public:
   /// callback to assemble the Jacobian Matrix
   virtual void assembleJacobian();
 
   /// callback to assemble the residual (rhs)
   virtual void assembleResidual();
 
   /* ------------------------------------------------------------------------ */
   /* Dynamic simulations part                                                 */
   /* ------------------------------------------------------------------------ */
   /// callback for the predictor (in case of dynamic simulation)
   virtual void predictor();
 
   /// callback for the corrector (in case of dynamic simulation)
   virtual void corrector();
 };
 
 } // akantu
 
 #endif /* __AKANTU_TIME_STEP_SOLVER_DEFAULT_SOLVER_CALLBACK_HH__ */
diff --git a/src/python/python_functor.cc b/src/python/python_functor.cc
index 15986dcf1..d4c524ca0 100644
--- a/src/python/python_functor.cc
+++ b/src/python/python_functor.cc
@@ -1,80 +1,80 @@
 /**
  * @file   python_functor.cc
  *
  * @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
  *
  * @date creation: Thu Feb 21 2013
- * @date last modification: Fri Nov 13 2015
+ * @date last modification: Tue Feb 06 2018
  *
  * @brief  Python functor interface
  *
  * @section LICENSE
  *
- * Copyright  (©)  2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de Lausanne)
+ * 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
+ * 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
+ * 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 "python_functor.hh"
 #include "aka_common.hh"
 #include "internal_field.hh"
 #include <vector>
 /* -------------------------------------------------------------------------- */
 namespace akantu {
 /* -------------------------------------------------------------------------- */
 
 PythonFunctor::PythonFunctor(PyObject * obj) : python_obj(obj) {}
 
 /* -------------------------------------------------------------------------- */
 
 PyObject * PythonFunctor::callFunctor(PyObject * functor, PyObject * args,
                                       PyObject * kwargs) const {
   if (!PyCallable_Check(functor))
     AKANTU_EXCEPTION("Provided functor is not a function");
 
   PyObject * pValue = PyObject_Call(functor, args, kwargs);
 
   PyObject * exception_type = PyErr_Occurred();
   if (exception_type) {
     PyObject * exception;
     PyObject * traceback;
     PyErr_Fetch(&exception_type, &exception, &traceback);
 
     PyObject_Print(exception_type, stdout, Py_PRINT_RAW);
     PyObject_Print(exception, stdout, Py_PRINT_RAW);
     std::stringstream sstr;
     sstr << "Exception occured while calling the functor: ";
 
     PyObject * exception_mesg = PyObject_GetAttrString(exception, "message");
 #if PY_MAJOR_VERSION >= 3
     if (exception_mesg && PyUnicode_Check(exception_mesg))
 #else
     if (exception_mesg && PyString_Check(exception_mesg))
 #endif
       sstr << this->convertToAkantu<std::string>(exception_mesg);
     else
       sstr << this->convertToAkantu<std::string>(exception);
 
     AKANTU_EXCEPTION(sstr.str());
   }
 
   return pValue;
 }
 
 /* -------------------------------------------------------------------------- */
 
 } // akantu
diff --git a/src/python/python_functor.hh b/src/python/python_functor.hh
index effa1fc8f..ffda267b9 100644
--- a/src/python/python_functor.hh
+++ b/src/python/python_functor.hh
@@ -1,146 +1,146 @@
 /**
  * @file   python_functor.hh
  *
  * @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
  *
  * @date creation: Fri Jun 18 2010
- * @date last modification: Sun Nov 15 2015
+ * @date last modification: Wed Feb 07 2018
  *
  * @brief  Python Functor interface
  *
  * @section LICENSE
  *
- * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
- * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
- * Solides)
+ * 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
+ * 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
+ * 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 "element_group.hh"
 #include "internal_field.hh"
 /* -------------------------------------------------------------------------- */
 #include <Python.h>
 #include <map>
 #include <vector>
 /* -------------------------------------------------------------------------- */
 
 #ifndef __AKANTU_PYTHON_FUNCTOR_HH__
 #define __AKANTU_PYTHON_FUNCTOR_HH__
 
 namespace akantu {
 
 class PythonFunctor {
   /* ------------------------------------------------------------------------ */
   /* Constructors/Destructors                                                 */
   /* ------------------------------------------------------------------------ */
 public:
   PythonFunctor(PyObject * obj);
 
   /* ------------------------------------------------------------------------ */
   /* Methods                                                                  */
   /* ------------------------------------------------------------------------ */
 
   /// call the python functor
   PyObject * callFunctor(PyObject * functor, PyObject * args,
                          PyObject * kwargs) const;
 
   /// call the python functor from variadic types
   template <typename return_type, typename... Params>
   return_type callFunctor(const std::string & functor_name,
                           Params &... parameters) const;
 
   /// empty function to cose the recursive template loop
   static inline void packArguments(std::vector<PyObject *> & pArgs);
 
   /// get the python function object
   inline PyObject * getPythonFunction(const std::string & functor_name) const;
 
   /// variadic template for unknown number of arguments to unpack
   template <typename T, typename... Args>
   static inline void packArguments(std::vector<PyObject *> & pArgs, T & p,
                                    Args &... params);
 
   /// convert an akantu object to python
   template <typename T>
   static inline PyObject * convertToPython(const T & akantu_obj);
 
   /// convert a stl vector to python
   template <typename T>
   static inline PyObject * convertToPython(const std::vector<T> & akantu_obj);
 
   /// convert a stl vector to python
   template <typename T>
   static inline PyObject *
   convertToPython(const std::vector<Array<T> *> & akantu_obj);
 
   /// convert a stl vector to python
   template <typename T>
   static inline PyObject *
   convertToPython(const std::unique_ptr<T> & akantu_obj);
 
   /// convert a stl vector to python
   template <typename T1, typename T2>
   static inline PyObject * convertToPython(const std::map<T1, T2> & akantu_obj);
 
   /// convert an akantu vector to python
   template <typename T>
   static inline PyObject * convertToPython(const Vector<T> & akantu_obj);
 
   /// convert an akantu internal to python
   template <typename T>
   static inline PyObject * convertToPython(const InternalField<T> & akantu_obj);
 
   /// convert an akantu vector to python
   template <typename T>
   static inline PyObject *
   convertToPython(const ElementTypeMapArray<T> & akantu_obj);
 
   /// convert an akantu vector to python
   template <typename T>
   static inline PyObject * convertToPython(const Array<T> & akantu_obj);
 
   /// convert an akantu vector to python
   template <typename T>
   static inline PyObject * convertToPython(Array<T> * akantu_obj);
 
   /// convert a akantu matrix to python
   template <typename T>
   static inline PyObject * convertToPython(const Matrix<T> & akantu_obj);
 
   /// convert a python object to an akantu object
   template <typename return_type>
   static inline return_type convertToAkantu(PyObject * python_obj);
 
   /// convert a python object to an akantu object
   template <typename T>
   static inline std::vector<T> convertListToAkantu(PyObject * python_obj);
 
   /// returns the numpy data type code
   template <typename T> static inline int getPythonDataTypeCode();
 
   /* ------------------------------------------------------------------------ */
   /* Class Members                                                            */
   /* ------------------------------------------------------------------------ */
 protected:
   PyObject * python_obj;
 };
 
 } // akantu
 
 #endif /* __AKANTU_PYTHON_FUNCTOR_HH__ */
 
 #include "python_functor_inline_impl.cc"
diff --git a/src/python/python_functor_inline_impl.cc b/src/python/python_functor_inline_impl.cc
index e573bdabe..38ccd09da 100644
--- a/src/python/python_functor_inline_impl.cc
+++ b/src/python/python_functor_inline_impl.cc
@@ -1,462 +1,463 @@
 /**
  * @file   python_functor_inline_impl.cc
  *
  * @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
  *
  * @date creation: Fri Nov 13 2015
- * @date last modification: Wed Nov 18 2015
+ * @date last modification: Tue Feb 20 2018
  *
  * @brief  Python functor interface
  *
  * @section LICENSE
  *
- * Copyright (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne) Laboratory
- * (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * Copyright (©) 2015-2018 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
- * terms  of the  GNU Lesser  General Public  License as  published by  the Free
+ * 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
+ * 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 "integration_point.hh"
 #include "internal_field.hh"
 /* -------------------------------------------------------------------------- */
 #define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION
 #include <Python.h>
 #include <numpy/arrayobject.h>
 #include <typeinfo>
 #if PY_MAJOR_VERSION >= 3
 #include <codecvt>
 #endif
 /* -------------------------------------------------------------------------- */
 
 #ifndef __AKANTU_PYTHON_FUNCTOR_INLINE_IMPL_CC__
 #define __AKANTU_PYTHON_FUNCTOR_INLINE_IMPL_CC__
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 template <typename T> inline int PythonFunctor::getPythonDataTypeCode() {
   AKANTU_EXCEPTION("undefined type: " << debug::demangle(typeid(T).name()));
 }
 
 /* -------------------------------------------------------------------------- */
 template <> inline int PythonFunctor::getPythonDataTypeCode<bool>() {
   int data_typecode = NPY_NOTYPE;
   size_t s = sizeof(bool);
   switch (s) {
   case 1:
     data_typecode = NPY_BOOL;
     break;
   case 2:
     data_typecode = NPY_UINT16;
     break;
   case 4:
     data_typecode = NPY_UINT32;
     break;
   case 8:
     data_typecode = NPY_UINT64;
     break;
   }
   return data_typecode;
 }
 
 /* -------------------------------------------------------------------------- */
 template <> inline int PythonFunctor::getPythonDataTypeCode<double>() {
   return NPY_DOUBLE;
 }
 
 /* -------------------------------------------------------------------------- */
 template <> inline int PythonFunctor::getPythonDataTypeCode<UInt>() {
   return NPY_UINT;
 }
 
 /* -------------------------------------------------------------------------- */
 template <>
 inline PyObject *
 PythonFunctor::convertToPython<double>(const double & akantu_object) {
   return PyFloat_FromDouble(akantu_object);
 }
 
 /* -------------------------------------------------------------------------- */
 template <>
 inline PyObject *
 PythonFunctor::convertToPython<UInt>(const UInt & akantu_object) {
 #if PY_MAJOR_VERSION >= 3
   return PyLong_FromLong(akantu_object);
 #else
   return PyInt_FromLong(akantu_object);
 #endif
 }
 
 /* -------------------------------------------------------------------------- */
 
 template <>
 inline PyObject *
 PythonFunctor::convertToPython<int>(const int & akantu_object) {
 #if PY_MAJOR_VERSION >= 3
   return PyLong_FromLong(akantu_object);
 #else
   return PyInt_FromLong(akantu_object);
 #endif
 }
 
 /* -------------------------------------------------------------------------- */
 
 template <>
 inline PyObject *
 PythonFunctor::convertToPython<bool>(const bool & akantu_object) {
   return PyBool_FromLong(long(akantu_object));
 }
 /* -------------------------------------------------------------------------- */
 
 template <>
 inline PyObject *
 PythonFunctor::convertToPython<std::string>(const std::string & str) {
 #if PY_MAJOR_VERSION >= 3
   return PyUnicode_FromString(str.c_str());
 #else
   return PyString_FromString(str.c_str());
 #endif
 }
 
 /* --------------------------------------------------------------------------
  */
 
 template <>
 inline PyObject *
 PythonFunctor::convertToPython<NodeGroup>(const NodeGroup & group) {
   return PythonFunctor::convertToPython(group.getNodes());
 }
 
 /* --------------------------------------------------------------------------
  */
 
 template <>
 inline PyObject *
 PythonFunctor::convertToPython<ElementGroup>(const ElementGroup & group) {
 
   PyObject * res = PyDict_New();
 
   PyDict_SetItem(res,
                  PythonFunctor::convertToPython(std::string("element_group")),
                  PythonFunctor::convertToPython(group.getElements()));
 
   PyDict_SetItem(res, PythonFunctor::convertToPython(std::string("node_group")),
                  PythonFunctor::convertToPython(group.getNodeGroup()));
 
   return res;
 }
 
 /* --------------------------------------------------------------------------
  */
 
 template <>
 inline PyObject *
 PythonFunctor::convertToPython<ElementGroup *>(ElementGroup * const & group) {
   return PythonFunctor::convertToPython(*group);
 }
 
 /* --------------------------------------------------------------------------
  */
 
 template <>
 inline PyObject *
 PythonFunctor::convertToPython<ElementType>(const ElementType & type) {
   // std::stringstream sstr;
   // sstr << type;
   // return PythonFunctor::convertToPython(sstr.str());
   return PythonFunctor::convertToPython(int(type));
 }
 
 /* --------------------------------------------------------------------------
  */
 
 template <typename T>
 inline PyObject *
 PythonFunctor::convertToPython(const ElementTypeMapArray<T> & map) {
 
   std::map<std::string, Array<T> *> res;
   for (const auto & type : map.elementTypes()) {
     std::stringstream sstr;
     sstr << type;
     res[sstr.str()] = const_cast<Array<T> *>(&map(type));
   }
   return PythonFunctor::convertToPython(res);
 }
 
 /* --------------------------------------------------------------------------
  */
 
 template <typename T> PyObject * PythonFunctor::convertToPython(const T &) {
   AKANTU_EXCEPTION(__PRETTY_FUNCTION__ << " : not implemented yet !"
                                        << std::endl
                                        << debug::demangle(typeid(T).name()));
 }
 
 /* -------------------------------------------------------------------------- */
 template <typename T>
 inline PyObject * PythonFunctor::convertToPython(const std::vector<T> & array) {
   int data_typecode = getPythonDataTypeCode<T>();
   npy_intp dims[1] = {int(array.size())};
   PyObject * obj = PyArray_SimpleNewFromData(1, dims, data_typecode,
                                              const_cast<T *>(&array[0]));
   auto * res = (PyArrayObject *)obj;
   return (PyObject *)res;
 }
 /* -------------------------------------------------------------------------- */
 template <typename T>
 inline PyObject *
 PythonFunctor::convertToPython(const std::vector<Array<T> *> & array) {
 
   PyObject * res = PyDict_New();
 
   for (auto a : array) {
     PyObject * obj = PythonFunctor::convertToPython(*a);
     PyObject * name = PythonFunctor::convertToPython(a->getID());
     PyDict_SetItem(res, name, obj);
   }
   return (PyObject *)res;
 }
 /* -------------------------------------------------------------------------- */
 
 template <typename T1, typename T2>
 inline PyObject * PythonFunctor::convertToPython(const std::map<T1, T2> & map) {
 
   PyObject * res = PyDict_New();
 
   for (auto && a : map) {
     PyObject * key = PythonFunctor::convertToPython(a.first);
     PyObject * value = PythonFunctor::convertToPython(a.second);
     PyDict_SetItem(res, key, value);
   }
   return (PyObject *)res;
 }
 
 /* -------------------------------------------------------------------------- */
 template <typename T>
 PyObject * PythonFunctor::convertToPython(const Vector<T> & array) {
   int data_typecode = getPythonDataTypeCode<T>();
   npy_intp dims[1] = {array.size()};
   PyObject * obj =
       PyArray_SimpleNewFromData(1, dims, data_typecode, array.storage());
   auto * res = (PyArrayObject *)obj;
   return (PyObject *)res;
 }
 
 /* -------------------------------------------------------------------------- */
 template <typename T>
 inline PyObject *
 PythonFunctor::convertToPython(const InternalField<T> & internals) {
   return convertToPython(
       static_cast<const ElementTypeMapArray<T> &>(internals));
 }
 
 /* --------------------------------------------------------------------- */
 
 template <typename T>
 inline PyObject * PythonFunctor::convertToPython(const std::unique_ptr<T> & u) {
   return convertToPython(*u);
 }
 
 /* --------------------------------------------------------------------- */
 
 template <typename T>
 PyObject * PythonFunctor::convertToPython(const Array<T> & array) {
   int data_typecode = getPythonDataTypeCode<T>();
   npy_intp dims[2] = {array.size(), array.getNbComponent()};
   PyObject * obj =
       PyArray_SimpleNewFromData(2, dims, data_typecode, array.storage());
   auto * res = (PyArrayObject *)obj;
   return (PyObject *)res;
 }
 /* ---------------------------------------------------------------------- */
 template <typename T>
 PyObject * PythonFunctor::convertToPython(Array<T> * array) {
   return PythonFunctor::convertToPython(*array);
 }
 
 /* ---------------------------------------------------------------------- */
 template <typename T>
 PyObject * PythonFunctor::convertToPython(const Matrix<T> & mat) {
   int data_typecode = getPythonDataTypeCode<T>();
   npy_intp dims[2] = {mat.size(0), mat.size(1)};
   PyObject * obj =
       PyArray_SimpleNewFromData(2, dims, data_typecode, mat.storage());
   auto * res = (PyArrayObject *)obj;
   return (PyObject *)res;
 }
 
 /* ---------------------------------------------------------------------- */
 
 template <>
 inline PyObject *
 PythonFunctor::convertToPython<IntegrationPoint>(const IntegrationPoint & qp) {
 
   PyObject * input = PyDict_New();
   PyObject * num_point = PythonFunctor::convertToPython(qp.num_point);
   PyObject * global_num = PythonFunctor::convertToPython(qp.global_num);
   PyObject * material_id = PythonFunctor::convertToPython(qp.material_id);
   PyObject * position = PythonFunctor::convertToPython(qp.getPosition());
   PyDict_SetItemString(input, "num_point", num_point);
   PyDict_SetItemString(input, "global_num", global_num);
   PyDict_SetItemString(input, "material_id", material_id);
   PyDict_SetItemString(input, "position", position);
   return input;
 }
 
 /* --------------------------------------------------------------------------
  */
 inline PyObject *
 PythonFunctor::getPythonFunction(const std::string & functor_name) const {
 #if PY_MAJOR_VERSION < 3
   if (!PyInstance_Check(this->python_obj))
     AKANTU_EXCEPTION("Python object is not an instance");
 #else
 // does not make sense to check everything is an instance of object in python 3
 #endif
 
   if (not PyObject_HasAttrString(this->python_obj, functor_name.c_str()))
     AKANTU_EXCEPTION("Python dictionary has no " << functor_name << " entry");
 
   PyObject * pFunctor =
       PyObject_GetAttrString(this->python_obj, functor_name.c_str());
 
   return pFunctor;
 }
 
 /* --------------------------------------------------------------------------
  */
 inline void PythonFunctor::packArguments(__attribute__((unused))
                                          std::vector<PyObject *> & p_args) {}
 
 /* --------------------------------------------------------------------------
  */
 template <typename T, typename... Args>
 inline void PythonFunctor::packArguments(std::vector<PyObject *> & p_args,
                                          T & p, Args &... params) {
   p_args.push_back(PythonFunctor::convertToPython(p));
   if (sizeof...(params) != 0)
     PythonFunctor::packArguments(p_args, params...);
 }
 
 /* --------------------------------------------------------------------------
  */
 template <typename return_type, typename... Params>
 return_type PythonFunctor::callFunctor(const std::string & functor_name,
                                        Params &... parameters) const {
   _import_array();
 
   std::vector<PyObject *> arg_vector;
   this->packArguments(arg_vector, parameters...);
 
   PyObject * pArgs = PyTuple_New(arg_vector.size());
   for (UInt i = 0; i < arg_vector.size(); ++i) {
     PyTuple_SetItem(pArgs, i, arg_vector[i]);
   }
 
   PyObject * kwargs = PyDict_New();
 
   PyObject * pFunctor = this->getPythonFunction(functor_name);
   PyObject * res = this->callFunctor(pFunctor, pArgs, kwargs);
 
   Py_XDECREF(pArgs);
   Py_XDECREF(kwargs);
 
   return this->convertToAkantu<return_type>(res);
 }
 
 /* --------------------------------------------------------------------------
  */
 template <typename return_type>
 inline return_type PythonFunctor::convertToAkantu(PyObject * python_obj) {
 
   if (PyList_Check(python_obj)) {
     return PythonFunctor::convertListToAkantu<typename return_type::value_type>(
         python_obj);
   }
   AKANTU_TO_IMPLEMENT();
 }
 
 /* --------------------------------------------------------------------------
  */
 template <>
 inline void PythonFunctor::convertToAkantu<void>(PyObject * python_obj) {
   if (python_obj != Py_None)
     AKANTU_DEBUG_WARNING(
         "functor return a value while none was expected: ignored");
 }
 
 /* --------------------------------------------------------------------------
  */
 template <>
 inline std::string
 PythonFunctor::convertToAkantu<std::string>(PyObject * python_obj) {
 #if PY_MAJOR_VERSION >= 3
   if (!PyUnicode_Check(python_obj))
     AKANTU_EXCEPTION("cannot convert object to string");
 
   std::wstring unicode_str(PyUnicode_AsWideCharString(python_obj, NULL));
   std::wstring_convert<std::codecvt_utf8<wchar_t>, wchar_t> converter;
   return converter.to_bytes(unicode_str);
 #else
   if (!PyString_Check(python_obj))
     AKANTU_EXCEPTION("cannot convert object to string");
 
   return PyString_AsString(python_obj);
 #endif
 }
 
 /* --------------------------------------------------------------------------
  */
 template <>
 inline Real PythonFunctor::convertToAkantu<Real>(PyObject * python_obj) {
   if (!PyFloat_Check(python_obj))
     AKANTU_EXCEPTION("cannot convert object to float");
   return PyFloat_AsDouble(python_obj);
 }
 /* --------------------------------------------------------------------------
  */
 template <>
 inline UInt PythonFunctor::convertToAkantu<UInt>(PyObject * python_obj) {
 #if PY_MAJOR_VERSION >= 3
   if (!PyLong_Check(python_obj))
     AKANTU_EXCEPTION("cannot convert object to integer");
   return PyLong_AsLong(python_obj);
 #else
   if (!PyInt_Check(python_obj))
     AKANTU_EXCEPTION("cannot convert object to integer");
   return PyInt_AsLong(python_obj);
 #endif
 }
 
 /* --------------------------------------------------------------------------
  */
 template <typename T>
 inline std::vector<T>
 PythonFunctor::convertListToAkantu(PyObject * python_obj) {
   std::vector<T> res;
   UInt size = PyList_Size(python_obj);
   for (UInt i = 0; i < size; ++i) {
     PyObject * item = PyList_GET_ITEM(python_obj, i);
     res.push_back(PythonFunctor::convertToAkantu<T>(item));
   }
   return res;
 }
 
 /* --------------------------------------------------------------------------
  */
 
 } // akantu
 
 #endif /* __AKANTU_PYTHON_FUNCTOR_INLINE_IMPL_CC__ */
diff --git a/src/solver/petsc_wrapper.hh b/src/solver/petsc_wrapper.hh
index dab92ca0d..e49a50350 100644
--- a/src/solver/petsc_wrapper.hh
+++ b/src/solver/petsc_wrapper.hh
@@ -1,79 +1,79 @@
 /**
  * @file   petsc_wrapper.hh
  *
  * @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Thu Feb 21 2013
- * @date last modification: Wed Oct 07 2015
+ * @date last modification: Sat Feb 03 2018
  *
  * @brief  Wrapper of PETSc structures
  *
  * @section LICENSE
  *
- * Copyright  (©)  2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de Lausanne)
+ * 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
+ * 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
+ * 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_PETSC_WRAPPER_HH__
 #define __AKANTU_PETSC_WRAPPER_HH__
 
 /* -------------------------------------------------------------------------- */
 #include <mpi.h>
 #include <petscao.h>
 #include <petscis.h>
 #include <petscksp.h>
 #include <petscmat.h>
 #include <petscvec.h>
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 struct PETScMatrixWrapper {
   Mat mat;
   AO ao;
   ISLocalToGlobalMapping mapping;
   /// MPI communicator for PETSc commands
   MPI_Comm communicator;
 };
 
 /* -------------------------------------------------------------------------- */
 struct PETScSolverWrapper {
   KSP ksp;
   Vec solution;
   Vec rhs;
   // MPI communicator for PETSc commands
   MPI_Comm communicator;
 };
 
 #if not defined(PETSC_CLANGUAGE_CXX)
 extern int aka_PETScError(int ierr);
 
 #define CHKERRXX(x)                                                            \
   do {                                                                         \
     int error = aka_PETScError(x);                                             \
     if (error != 0) {                                                          \
       AKANTU_EXCEPTION("Error in PETSC");                                      \
     }                                                                          \
   } while (0)
 #endif
 
 } // akantu
 
 #endif /* __AKANTU_PETSC_WRAPPER_HH__ */
diff --git a/src/solver/solver_petsc.cc b/src/solver/solver_petsc.cc
index b32a28b4c..7742143c7 100644
--- a/src/solver/solver_petsc.cc
+++ b/src/solver/solver_petsc.cc
@@ -1,1106 +1,1106 @@
 /**
  * @file   solver_petsc.cc
  *
  * @author Alejandro M. Aragón <alejandro.aragon@epfl.ch>
  * @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Tue May 13 2014
- * @date last modification: Tue Jan 19 2016
+ * @date last modification: Sun Aug 13 2017
  *
  * @brief  Solver class implementation for the petsc solver
  *
  * @section LICENSE
  *
- * Copyright  (©)  2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de Lausanne)
+ * 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
+ * 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
+ * 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 "solver_petsc.hh"
 #include "dof_manager_petsc.hh"
 #include "mpi_type_wrapper.hh"
 #include "sparse_matrix_petsc.hh"
 /* -------------------------------------------------------------------------- */
 #include <petscksp.h>
 //#include <petscsys.h>
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 SolverPETSc::SolverPETSc(DOFManagerPETSc & dof_manager, const ID & matrix_id,
                          const ID & id, const MemoryID & memory_id)
     : SparseSolver(dof_manager, matrix_id, id, memory_id),
       dof_manager(dof_manager), matrix(dof_manager.getMatrix(matrix_id)),
       is_petsc_data_initialized(false) {
   PetscErrorCode ierr;
 
   /// create a solver context
   ierr = KSPCreate(PETSC_COMM_WORLD, &this->ksp);
   CHKERRXX(ierr);
 }
 
 /* -------------------------------------------------------------------------- */
 SolverPETSc::~SolverPETSc() {
   AKANTU_DEBUG_IN();
 
   this->destroyInternalData();
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void SolverPETSc::destroyInternalData() {
   AKANTU_DEBUG_IN();
 
   if (this->is_petsc_data_initialized) {
     PetscErrorCode ierr;
     ierr = KSPDestroy(&(this->ksp));
     CHKERRXX(ierr);
     this->is_petsc_data_initialized = false;
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void SolverPETSc::initialize() {
   AKANTU_DEBUG_IN();
 
   this->is_petsc_data_initialized = true;
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void SolverPETSc::solve() {
   AKANTU_DEBUG_IN();
 
   Vec & rhs = this->dof_manager.getResidual();
   Vec & solution = this->dof_manager.getGlobalSolution();
 
   PetscErrorCode ierr;
   ierr = KSPSolve(this->ksp, rhs, solution);
   CHKERRXX(ierr);
 
   AKANTU_DEBUG_OUT();
 }
 
 // /* --------------------------------------------------------------------------
 // */
 // void SolverPETSc::solve(Array<Real> & solution) {
 //   AKANTU_DEBUG_IN();
 
 //   this->solution = &solution;
 //   this->solve();
 
 //   PetscErrorCode ierr;
 //   PETScMatrix * petsc_matrix = static_cast<PETScMatrix *>(this->matrix);
 
 //   // ierr = VecGetOwnershipRange(this->petsc_solver_wrapper->solution,
 //   // solution_begin, solution_end); CHKERRXX(ierr);
 //   // ierr = VecGetArray(this->petsc_solver_wrapper->solution, PetscScalar
 //   // **array); CHKERRXX(ierr);
 //   UInt nb_component = solution.getNbComponent();
 //   UInt size = solution.size();
 
 //   for (UInt i = 0; i < size; ++i) {
 //     for (UInt j = 0; j < nb_component; ++j) {
 //       UInt i_local = i * nb_component + j;
 //       if (this->matrix->getDOFSynchronizer().isLocalOrMasterDOF(i_local)) {
 //         Int i_global =
 //             this->matrix->getDOFSynchronizer().getDOFGlobalID(i_local);
 //         ierr =
 //         AOApplicationToPetsc(petsc_matrix->getPETScMatrixWrapper()->ao,
 //                                     1, &(i_global));
 //         CHKERRXX(ierr);
 //         ierr = VecGetValues(this->petsc_solver_wrapper->solution, 1,
 //         &i_global,
 //                             &solution(i, j));
 //         CHKERRXX(ierr);
 //       }
 //     }
 //   }
 //   synch_registry->synchronize(_gst_solver_solution);
 
 //   AKANTU_DEBUG_OUT();
 // }
 
 /* -------------------------------------------------------------------------- */
 void SolverPETSc::setOperators() {
   AKANTU_DEBUG_IN();
   PetscErrorCode ierr;
 /// set the matrix that defines the linear system and the matrix for
 /// preconditioning (here they are the same)
 #if PETSC_VERSION_MAJOR >= 3 && PETSC_VERSION_MINOR >= 5
   ierr = KSPSetOperators(this->ksp, this->matrix.getPETScMat(),
                          this->matrix.getPETScMat());
   CHKERRXX(ierr);
 #else
   ierr = KSPSetOperators(this->ksp, this->matrix.getPETScMat(),
                          this->matrix.getPETScMat(), SAME_NONZERO_PATTERN);
   CHKERRXX(ierr);
 #endif
 
   /// If this is not called the solution vector is zeroed in the call to
   /// KSPSolve().
   ierr = KSPSetInitialGuessNonzero(this->ksp, PETSC_TRUE);
   KSPSetFromOptions(this->ksp);
 
   AKANTU_DEBUG_OUT();
 }
 /* -------------------------------------------------------------------------- */
 // void finalize_petsc() {
 
 //   static bool finalized = false;
 //   if (!finalized) {
 
 //     cout<<"*** INFO *** PETSc is finalizing..."<<endl;
 //     // finalize PETSc
 //     PetscErrorCode ierr = PetscFinalize();CHKERRCONTINUE(ierr);
 //     finalized = true;
 //   }
 // }
 
 // SolverPETSc::sparse_vector_type
 // SolverPETSc::operator()(const SolverPETSc::sparse_matrix_type& AA,
 //                          const SolverPETSc::sparse_vector_type& bb) {
 
 // #ifdef CPPUTILS_VERBOSE
 //   // parallel output stream
 //   Output_stream out;
 //   // timer
 //   cpputils::ctimer timer;
 //   out<<"Inside PETSc solver: "<<timer<<endl;
 // #endif
 
 // #ifdef CPPUTILS_VERBOSE
 //   out<<"  Inside operator()(const sparse_matrix_type&, const
 //   sparse_vector_type&)... "<<timer<<endl;
 // #endif
 
 //   assert(AA.rows() == bb.size());
 
 //   //  KSP ksp;            //!< linear solver context
 
 //   Vec            b;                /* RHS */
 //   PC             pc;               /* preconditioner context */
 //   PetscErrorCode ierr;
 //   PetscInt       nlocal;
 //   PetscInt       n = bb.size();
 //   VecScatter ctx;
 
 //   /*
 //    Create vectors.  Note that we form 1 vector from scratch and
 //    then duplicate as needed. For this simple case let PETSc decide how
 //    many elements of the vector are stored on each processor. The second
 //    argument to VecSetSizes() below causes PETSc to decide.
 //    */
 //   ierr = VecCreate(PETSC_COMM_WORLD,&b);CHKERRCONTINUE(ierr);
 //   ierr = VecSetSizes(b,PETSC_DECIDE,n);CHKERRCONTINUE(ierr);
 //   ierr = VecSetFromOptions(b);CHKERRCONTINUE(ierr);
 //   if (!allocated_) {
 //     ierr = VecDuplicate(b,&x_);CHKERRCONTINUE(ierr);
 //   } else
 //     VecZeroEntries(x_);
 
 // #ifdef CPPUTILS_VERBOSE
 //   out<<"  Vectors created... "<<timer<<endl;
 // #endif
 
 //   /* Set hight-hand-side vector */
 //   for (sparse_vector_type::const_hash_iterator it = bb.map_.begin(); it !=
 //   bb.map_.end(); ++it) {
 //     int row = it->first;
 //     ierr = VecSetValues(b, 1, &row, &it->second, ADD_VALUES);
 //   }
 
 // #ifdef CPPUTILS_VERBOSE
 //   out<<"  Right hand side set... "<<timer<<endl;
 // #endif
 
 //   /*
 //    Assemble vector, using the 2-step process:
 //    VecAssemblyBegin(), VecAssemblyEnd()
 //    Computations can be done while messages are in transition
 //    by placing code between these two statements.
 //    */
 //   ierr = VecAssemblyBegin(b);CHKERRCONTINUE(ierr);
 //   ierr = VecAssemblyEnd(b);CHKERRCONTINUE(ierr);
 
 // #ifdef CPPUTILS_VERBOSE
 //   out<<"  Right-hand-side vector assembled... "<<timer<<endl;
 
 //   ierr = VecView(b,PETSC_VIEWER_STDOUT_WORLD);CHKERRCONTINUE(ierr);
 
 //   Vec b_all;
 //   ierr = VecScatterCreateToAll(b, &ctx, &b_all);CHKERRCONTINUE(ierr);
 //   ierr =
 //   VecScatterBegin(ctx,b,b_all,INSERT_VALUES,SCATTER_FORWARD);CHKERRCONTINUE(ierr);
 //   ierr =
 //   VecScatterEnd(ctx,b,b_all,INSERT_VALUES,SCATTER_FORWARD);CHKERRCONTINUE(ierr);
 
 //   value_type nrm;
 //   VecNorm(b_all,NORM_2,&nrm);
 //   out<<"  Norm of right hand side... "<<nrm<<endl;
 // #endif
 
 //   /* Identify the starting and ending mesh points on each
 //    processor for the interior part of the mesh. We let PETSc decide
 //    above. */
 
 //   //    PetscInt rstart,rend;
 //   //    ierr = VecGetOwnershipRange(x_,&rstart,&rend);CHKERRCONTINUE(ierr);
 //   ierr = VecGetLocalSize(x_,&nlocal);CHKERRCONTINUE(ierr);
 
 //   /*
 //    Create matrix.  When using MatCreate(), the matrix format can
 //    be specified at runtime.
 
 //    Performance tuning note:  For problems of substantial size,
 //    preallocation of matrix memory is crucial for attaining good
 //    performance. See the matrix chapter of the users manual for details.
 
 //    We pass in nlocal as the "local" size of the matrix to force it
 //    to have the same parallel layout as the vector created above.
 //    */
 //   if (!allocated_) {
 
 //     ierr = MatCreate(PETSC_COMM_WORLD,&A_);CHKERRCONTINUE(ierr);
 //     ierr = MatSetSizes(A_,nlocal,nlocal,n,n);CHKERRCONTINUE(ierr);
 //     ierr = MatSetFromOptions(A_);CHKERRCONTINUE(ierr);
 //     ierr = MatSetUp(A_);CHKERRCONTINUE(ierr);
 //   } else {
 //     // zero-out matrix
 //     MatZeroEntries(A_);
 //   }
 
 //   /*
 //    Assemble matrix.
 
 //    The linear system is distributed across the processors by
 //    chunks of contiguous rows, which correspond to contiguous
 //    sections of the mesh on which the problem is discretized.
 //    For matrix assembly, each processor contributes entries for
 //    the part that it owns locally.
 //    */
 
 // #ifdef CPPUTILS_VERBOSE
 //   out<<"  Zeroed-out sparse matrix entries... "<<timer<<endl;
 // #endif
 
 //   for (sparse_matrix_type::const_hash_iterator it = AA.map_.begin(); it !=
 //   AA.map_.end(); ++it) {
 
 //     // get subscripts
 //     std::pair<size_t,size_t> subs = AA.unhash(it->first);
 //     PetscInt row = subs.first;
 //     PetscInt col = subs.second;
 //     ierr = MatSetValues(A_, 1, &row, 1, &col, &it->second,
 //     ADD_VALUES);CHKERRCONTINUE(ierr);
 //   }
 
 // #ifdef CPPUTILS_VERBOSE
 //   out<<"  Filled sparse matrix... "<<timer<<endl;
 // #endif
 
 //   /* Assemble the matrix */
 //   ierr = MatAssemblyBegin(A_,MAT_FINAL_ASSEMBLY);CHKERRCONTINUE(ierr);
 //   ierr = MatAssemblyEnd(A_,MAT_FINAL_ASSEMBLY);CHKERRCONTINUE(ierr);
 
 //   if (!allocated_) {
 //     // set after the first MatAssemblyEnd
 //     //        ierr = MatSetOption(A_, MAT_NEW_NONZERO_LOCATIONS,
 //     PETSC_FALSE);CHKERRCONTINUE(ierr);
 //     ierr = MatSetOption(A_, MAT_NEW_NONZERO_ALLOCATION_ERR,
 //     PETSC_FALSE);CHKERRCONTINUE(ierr);
 //   }
 
 // #ifdef CPPUTILS_VERBOSE
 //   out<<"  Sparse matrix assembled... "<<timer<<endl;
 //   // view matrix
 //   MatView(A_, PETSC_VIEWER_STDOUT_WORLD);
 
 //   MatNorm(A_,NORM_FROBENIUS,&nrm);
 //   out<<"  Norm of stiffness matrix... "<<nrm<<endl;
 // #endif
 
 //   /*
 //    Set operators. Here the matrix that defines the linear system
 //    also serves as the preconditioning matrix.
 //    */
 //   //    ierr =
 //   KSPSetOperators(ksp,A_,A_,DIFFERENT_NONZERO_PATTERN);CHKERRCONTINUE(ierr);
 //   ierr =
 //   KSPSetOperators(ksp_,A_,A_,SAME_NONZERO_PATTERN);CHKERRCONTINUE(ierr);
 
 //   //
 //   //    /*
 //   //     Set runtime options, e.g.,
 //   //     -ksp_type <type> -pc_type <type> -ksp_monitor -ksp_rtol <rtol>
 //   //     These options will override those specified above as long as
 //   //     KSPSetFromOptions() is called _after_ any other customization
 //   //     routines.
 //   //     */
 //   //    ierr = KSPSetFromOptions(ksp);CHKERRCONTINUE(ierr);
 
 // #ifdef CPPUTILS_VERBOSE
 //   out<<"  Solving system... "<<timer<<endl;
 // #endif
 
 //   /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 //    Solve the linear system
 //    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
 //   /*
 //    Solve linear system
 //    */
 //   ierr = KSPSolve(ksp_,b,x_);CHKERRCONTINUE(ierr);
 
 // #ifdef CPPUTILS_VERBOSE
 
 //   /*
 //    View solver info; we could instead use the option -ksp_view to
 //    print this info to the screen at the conclusion of KSPSolve().
 //    */
 //   ierr = KSPView(ksp_,PETSC_VIEWER_STDOUT_WORLD);CHKERRCONTINUE(ierr);
 
 //   int iter;
 //   KSPGetIterationNumber(ksp_, &iter);
 //   out<<"  System solved in "<<iter<<" iterations... "<<timer<<endl;
 //   KSPConvergedReason reason;
 //   ierr = KSPGetConvergedReason(ksp_,&reason);CHKERRCONTINUE(ierr);
 //   if (reason < 0)
 //     out<<"*** WARNING *** PETSc solver diverged with flag ";
 //   else
 //     out<<"*** INFO *** PETSc solver converged with flag ";
 
 //   if (reason == KSP_CONVERGED_RTOL)
 //     out<<"KSP_CONVERGED_RTOL"<<endl;
 //   else if (reason == KSP_CONVERGED_ATOL)
 //     out<<"KSP_CONVERGED_ATOL"<<endl;
 //   else if (reason == KSP_CONVERGED_ITS)
 //     out<<"KSP_CONVERGED_ITS"<<endl;
 //   else if (reason == KSP_CONVERGED_CG_NEG_CURVE)
 //     out<<"KSP_CONVERGED_CG_NEG_CURVE"<<endl;
 //   else if (reason == KSP_CONVERGED_CG_CONSTRAINED)
 //     out<<"KSP_CONVERGED_CG_CONSTRAINED"<<endl;
 //   else if (reason == KSP_CONVERGED_STEP_LENGTH)
 //     out<<"KSP_CONVERGED_STEP_LENGTH"<<endl;
 //   else if (reason == KSP_CONVERGED_HAPPY_BREAKDOWN)
 //     out<<"KSP_CONVERGED_HAPPY_BREAKDOWN"<<endl;
 //   else if (reason == KSP_DIVERGED_NULL)
 //     out<<"KSP_DIVERGED_NULL"<<endl;
 //   else if (reason == KSP_DIVERGED_ITS)
 //     out<<"KSP_DIVERGED_ITS"<<endl;
 //   else if (reason == KSP_DIVERGED_DTOL)
 //     out<<"KSP_DIVERGED_DTOL"<<endl;
 //   else if (reason == KSP_DIVERGED_BREAKDOWN)
 //     out<<"KSP_DIVERGED_BREAKDOWN"<<endl;
 //   else if (reason == KSP_DIVERGED_BREAKDOWN_BICG)
 //     out<<"KSP_DIVERGED_BREAKDOWN_BICG"<<endl;
 //   else if (reason == KSP_DIVERGED_NONSYMMETRIC)
 //     out<<"KSP_DIVERGED_NONSYMMETRIC"<<endl;
 //   else if (reason == KSP_DIVERGED_INDEFINITE_PC)
 //     out<<"KSP_DIVERGED_INDEFINITE_PC"<<endl;
 //   else if (reason == KSP_DIVERGED_NAN)
 //     out<<"KSP_DIVERGED_NAN"<<endl;
 //   else if (reason == KSP_DIVERGED_INDEFINITE_MAT)
 //     out<<"KSP_DIVERGED_INDEFINITE_MAT"<<endl;
 //   else if (reason == KSP_CONVERGED_ITERATING)
 //     out<<"KSP_CONVERGED_ITERATING"<<endl;
 
 //   PetscReal rnorm;
 //   ierr = KSPGetResidualNorm(ksp_,&rnorm);CHKERRCONTINUE(ierr);
 
 //   out<<"PETSc last residual norm computed: "<<rnorm<<endl;
 
 //   ierr = VecView(x_,PETSC_VIEWER_STDOUT_WORLD);CHKERRCONTINUE(ierr);
 
 //   VecNorm(x_,NORM_2,&nrm);
 //   out<<"  Norm of solution vector... "<<nrm<<endl;
 
 // #endif
 
 //   /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 //    Check solution and clean up
 //    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
 
 //   Vec x_all;
 
 //   ierr = VecScatterCreateToAll(x_, &ctx, &x_all);CHKERRCONTINUE(ierr);
 //   ierr =
 //   VecScatterBegin(ctx,x_,x_all,INSERT_VALUES,SCATTER_FORWARD);CHKERRCONTINUE(ierr);
 //   ierr =
 //   VecScatterEnd(ctx,x_,x_all,INSERT_VALUES,SCATTER_FORWARD);CHKERRCONTINUE(ierr);
 
 // #ifdef CPPUTILS_VERBOSE
 //   out<<"  Solution vector scattered... "<<timer<<endl;
 //   VecNorm(x_all,NORM_2,&nrm);
 //   out<<"  Norm of scattered vector... "<<nrm<<endl;
 //   //    ierr = VecView(x_all,PETSC_VIEWER_STDOUT_WORLD);CHKERRCONTINUE(ierr);
 // #endif
 
 //   /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 //    Get values from solution and store them in the object that will be
 //    returned
 //    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
 
 //   sparse_vector_type xx(bb.size());
 
 //   /* Set solution vector */
 //   double zero = 0.;
 //   double val;
 //   for (sparse_vector_type::const_hash_iterator it = bb.map_.begin(); it !=
 //   bb.map_.end(); ++it) {
 //     int row = it->first;
 //     ierr = VecGetValues(x_all, 1, &row, &val);
 //     if (val != zero)
 //       xx[row] = val;
 //   }
 
 // #ifdef CPPUTILS_VERBOSE
 //   out<<"  Solution vector copied... "<<timer<<endl;
 //   //    out<<"  Norm of copied solution vector... "<<norm(xx,
 //   Insert_t)<<endl;
 // #endif
 
 //   /*
 //    Free work space.  All PETSc objects should be destroyed when they
 //    are no longer needed.
 //    */
 //   ierr = VecDestroy(&b);CHKERRCONTINUE(ierr);
 //   //    ierr = KSPDestroy(&ksp);CHKERRCONTINUE(ierr);
 
 //   // set allocated flag
 //   if (!allocated_) {
 //     allocated_ = true;
 //   }
 
 // #ifdef CPPUTILS_VERBOSE
 //   out<<"  Temporary data structures destroyed... "<<timer<<endl;
 // #endif
 
 //   return xx;
 // }
 
 // SolverPETSc::sparse_vector_type SolverPETSc::operator()(const
 // SolverPETSc::sparse_matrix_type& KKpf, const SolverPETSc::sparse_matrix_type&
 // KKpp, const SolverPETSc::sparse_vector_type& UUp) {
 
 // #ifdef CPPUTILS_VERBOSE
 //   // parallel output stream
 //   Output_stream out;
 //   // timer
 //   cpputils::ctimer timer;
 //   out<<"Inside SolverPETSc::operator()(const sparse_matrix&, const
 //   sparse_matrix&, const sparse_vector&). "<<timer<<endl;
 // #endif
 
 //   Mat Kpf, Kpp;
 //   Vec Up, Pf, Pp;
 
 //   PetscErrorCode ierr =
 //   MatCreate(PETSC_COMM_WORLD,&Kpf);CHKERRCONTINUE(ierr);
 //   ierr = MatCreate(PETSC_COMM_WORLD,&Kpp);CHKERRCONTINUE(ierr);
 
 // #ifdef CPPUTILS_VERBOSE
 //   out<<"  Allocating memory... "<<timer<<endl;
 // #endif
 
 //   ierr = MatSetFromOptions(Kpf);CHKERRCONTINUE(ierr);
 //   ierr = MatSetFromOptions(Kpp);CHKERRCONTINUE(ierr);
 
 //   ierr = MatSetSizes(Kpf,PETSC_DECIDE,PETSC_DECIDE, KKpf.rows(),
 //   KKpf.columns());CHKERRCONTINUE(ierr);
 //   ierr = MatSetSizes(Kpp,PETSC_DECIDE,PETSC_DECIDE, KKpp.rows(),
 //   KKpp.columns());CHKERRCONTINUE(ierr);
 
 //   // get number of non-zeros in both diagonal and non-diagonal portions of
 //   the matrix
 
 //   std::pair<size_t,size_t> Kpf_nz = KKpf.non_zero_off_diagonal();
 //   std::pair<size_t,size_t> Kpp_nz = KKpp.non_zero_off_diagonal();
 
 //   ierr = MatMPIAIJSetPreallocation(Kpf, Kpf_nz.first, PETSC_NULL,
 //   Kpf_nz.second, PETSC_NULL); CHKERRCONTINUE(ierr);
 //   ierr = MatMPIAIJSetPreallocation(Kpp, Kpp_nz.first, PETSC_NULL,
 //   Kpp_nz.second, PETSC_NULL); CHKERRCONTINUE(ierr);
 //   ierr = MatSeqAIJSetPreallocation(Kpf, Kpf_nz.first, PETSC_NULL);
 //   CHKERRCONTINUE(ierr);
 //   ierr = MatSeqAIJSetPreallocation(Kpp, Kpp_nz.first, PETSC_NULL);
 //   CHKERRCONTINUE(ierr);
 
 //   for (sparse_matrix_type::const_hash_iterator it = KKpf.map_.begin(); it !=
 //   KKpf.map_.end(); ++it) {
 
 //     // get subscripts
 //     std::pair<size_t,size_t> subs = KKpf.unhash(it->first);
 //     int row = subs.first;
 //     int col = subs.second;
 //     ierr = MatSetValues(Kpf, 1, &row, 1, &col, &it->second,
 //     ADD_VALUES);CHKERRCONTINUE(ierr);
 //   }
 
 //   for (sparse_matrix_type::const_hash_iterator it = KKpp.map_.begin(); it !=
 //   KKpp.map_.end(); ++it) {
 
 //     // get subscripts
 //     std::pair<size_t,size_t> subs = KKpp.unhash(it->first);
 //     int row = subs.first;
 //     int col = subs.second;
 //     ierr = MatSetValues(Kpf, 1, &row, 1, &col, &it->second,
 //     ADD_VALUES);CHKERRCONTINUE(ierr);
 //   }
 
 // #ifdef CPPUTILS_VERBOSE
 //   out<<"  Filled sparse matrices... "<<timer<<endl;
 // #endif
 
 //   /*
 //    Assemble matrix, using the 2-step process:
 //    MatAssemblyBegin(), MatAssemblyEnd()
 //    Computations can be done while messages are in transition
 //    by placing code between these two statements.
 //    */
 //   ierr = MatAssemblyBegin(Kpf,MAT_FINAL_ASSEMBLY);CHKERRCONTINUE(ierr);
 //   ierr = MatAssemblyBegin(Kpp,MAT_FINAL_ASSEMBLY);CHKERRCONTINUE(ierr);
 //   ierr = MatAssemblyEnd(Kpf,MAT_FINAL_ASSEMBLY);CHKERRCONTINUE(ierr);
 //   ierr = MatAssemblyEnd(Kpp,MAT_FINAL_ASSEMBLY);CHKERRCONTINUE(ierr);
 
 // #ifdef CPPUTILS_VERBOSE
 //   out<<"  Sparse matrices assembled... "<<timer<<endl;
 // #endif
 
 //   ierr = VecCreate(PETSC_COMM_WORLD,&Up);CHKERRCONTINUE(ierr);
 //   ierr = VecSetSizes(Up,PETSC_DECIDE, UUp.size());CHKERRCONTINUE(ierr);
 //   ierr = VecSetFromOptions(Up);CHKERRCONTINUE(ierr);
 
 //   ierr = VecCreate(PETSC_COMM_WORLD,&Pf);CHKERRCONTINUE(ierr);
 //   ierr = VecSetSizes(Pf,PETSC_DECIDE, KKpf.rows());CHKERRCONTINUE(ierr);
 //   ierr = VecSetFromOptions(Pf);CHKERRCONTINUE(ierr);
 //   ierr = VecDuplicate(Pf,&Pp);CHKERRCONTINUE(ierr);
 
 // #ifdef CPPUTILS_VERBOSE
 //   out<<"  Vectors created... "<<timer<<endl;
 // #endif
 
 //   /* Set hight-hand-side vector */
 //   for (sparse_vector_type::const_hash_iterator it = UUp.map_.begin(); it !=
 //   UUp.map_.end(); ++it) {
 //     int row = it->first;
 //     ierr = VecSetValues(Up, 1, &row, &it->second, ADD_VALUES);
 //   }
 
 //   /*
 //    Assemble vector, using the 2-step process:
 //    VecAssemblyBegin(), VecAssemblyEnd()
 //    Computations can be done while messages are in transition
 //    by placing code between these two statements.
 //    */
 //   ierr = VecAssemblyBegin(Up);CHKERRCONTINUE(ierr);
 //   ierr = VecAssemblyEnd(Up);CHKERRCONTINUE(ierr);
 
 //   // add Kpf*Uf
 //   ierr = MatMult(Kpf, x_, Pf);
 
 //   // add Kpp*Up
 //   ierr = MatMultAdd(Kpp, Up, Pf, Pp);
 
 // #ifdef CPPUTILS_VERBOSE
 //   out<<"  Matrices multiplied... "<<timer<<endl;
 // #endif
 
 //   VecScatter ctx;
 //   Vec Pp_all;
 
 //   ierr = VecScatterCreateToAll(Pp, &ctx, &Pp_all);CHKERRCONTINUE(ierr);
 //   ierr =
 //   VecScatterBegin(ctx,Pp,Pp_all,INSERT_VALUES,SCATTER_FORWARD);CHKERRCONTINUE(ierr);
 //   ierr =
 //   VecScatterEnd(ctx,Pp,Pp_all,INSERT_VALUES,SCATTER_FORWARD);CHKERRCONTINUE(ierr);
 
 // #ifdef CPPUTILS_VERBOSE
 //   out<<"  Vector scattered... "<<timer<<endl;
 // #endif
 
 //   /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 //    Get values from solution and store them in the object that will be
 //    returned
 //    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
 
 //   sparse_vector_type pp(KKpf.rows());
 
 //   // get reaction vector
 //   for (int i=0; i<KKpf.rows(); ++i) {
 
 //     PetscScalar v;
 //     ierr = VecGetValues(Pp_all, 1, &i, &v);
 //     if (v != PetscScalar())
 //       pp[i] = v;
 //   }
 
 // #ifdef CPPUTILS_VERBOSE
 //   out<<"  Vector copied... "<<timer<<endl;
 // #endif
 
 //   ierr = MatDestroy(&Kpf);CHKERRCONTINUE(ierr);
 //   ierr = MatDestroy(&Kpp);CHKERRCONTINUE(ierr);
 //   ierr = VecDestroy(&Up);CHKERRCONTINUE(ierr);
 //   ierr = VecDestroy(&Pf);CHKERRCONTINUE(ierr);
 //   ierr = VecDestroy(&Pp);CHKERRCONTINUE(ierr);
 //   ierr = VecDestroy(&Pp_all);CHKERRCONTINUE(ierr);
 
 // #ifdef CPPUTILS_VERBOSE
 //   out<<"  Temporary data structures destroyed... "<<timer<<endl;
 // #endif
 
 //   return pp;
 // }
 
 // SolverPETSc::sparse_vector_type SolverPETSc::operator()(const
 // SolverPETSc::sparse_vector_type& aa, const SolverPETSc::sparse_vector_type&
 // bb) {
 
 //   assert(aa.size() == bb.size());
 
 // #ifdef CPPUTILS_VERBOSE
 //   // parallel output stream
 //   Output_stream out;
 //   // timer
 //   cpputils::ctimer timer;
 //   out<<"Inside SolverPETSc::operator()(const sparse_vector&, const
 //   sparse_vector&). "<<timer<<endl;
 // #endif
 
 //   Vec r;
 
 //   PetscErrorCode ierr = VecCreate(PETSC_COMM_WORLD,&r);CHKERRCONTINUE(ierr);
 //   ierr = VecSetSizes(r,PETSC_DECIDE, aa.size());CHKERRCONTINUE(ierr);
 //   ierr = VecSetFromOptions(r);CHKERRCONTINUE(ierr);
 
 // #ifdef CPPUTILS_VERBOSE
 //   out<<"  Vectors created... "<<timer<<endl;
 // #endif
 
 //   // set values
 //   for (sparse_vector_type::const_hash_iterator it = aa.map_.begin(); it !=
 //   aa.map_.end(); ++it) {
 //     int row = it->first;
 //     ierr = VecSetValues(r, 1, &row, &it->second, ADD_VALUES);
 //   }
 //   for (sparse_vector_type::const_hash_iterator it = bb.map_.begin(); it !=
 //   bb.map_.end(); ++it) {
 //     int row = it->first;
 //     ierr = VecSetValues(r, 1, &row, &it->second, ADD_VALUES);
 //   }
 
 //   /*
 //    Assemble vector, using the 2-step process:
 //    VecAssemblyBegin(), VecAssemblyEnd()
 //    Computations can be done while messages are in transition
 //    by placing code between these two statements.
 //    */
 //   ierr = VecAssemblyBegin(r);CHKERRCONTINUE(ierr);
 //   ierr = VecAssemblyEnd(r);CHKERRCONTINUE(ierr);
 
 //   sparse_vector_type rr(aa.size());
 
 //   for (sparse_vector_type::const_hash_iterator it = aa.map_.begin(); it !=
 //   aa.map_.end(); ++it) {
 //     int row = it->first;
 //     ierr = VecGetValues(r, 1, &row, &rr[row]);
 //   }
 //   for (sparse_vector_type::const_hash_iterator it = bb.map_.begin(); it !=
 //   bb.map_.end(); ++it) {
 //     int row = it->first;
 //     ierr = VecGetValues(r, 1, &row, &rr[row]);
 //   }
 
 // #ifdef CPPUTILS_VERBOSE
 //   out<<"  Vector copied... "<<timer<<endl;
 // #endif
 
 //   ierr = VecDestroy(&r);CHKERRCONTINUE(ierr);
 
 // #ifdef CPPUTILS_VERBOSE
 //   out<<"  Temporary data structures destroyed... "<<timer<<endl;
 // #endif
 
 //   return rr;
 // }
 
 // SolverPETSc::value_type SolverPETSc::norm(const
 // SolverPETSc::sparse_matrix_type& aa, Element_insertion_type flag) {
 
 // #ifdef CPPUTILS_VERBOSE
 //   // parallel output stream
 //   Output_stream out;
 //   // timer
 //   cpputils::ctimer timer;
 //   out<<"Inside SolverPETSc::norm(const sparse_matrix&). "<<timer<<endl;
 // #endif
 
 //   Mat r;
 
 //   PetscErrorCode ierr = MatCreate(PETSC_COMM_WORLD,&r);CHKERRCONTINUE(ierr);
 //   ierr = MatSetSizes(r,PETSC_DECIDE,PETSC_DECIDE, aa.rows(),
 //   aa.columns());CHKERRCONTINUE(ierr);
 //   ierr = MatSetFromOptions(r);CHKERRCONTINUE(ierr);
 
 // #ifdef CPPUTILS_VERBOSE
 //   out<<"  Matrix created... "<<timer<<endl;
 // #endif
 
 //   // set values
 //   for (sparse_vector_type::const_hash_iterator it = aa.map_.begin(); it !=
 //   aa.map_.end(); ++it) {
 //     // get subscripts
 //     std::pair<size_t,size_t> subs = aa.unhash(it->first);
 //     int row = subs.first;
 //     int col = subs.second;
 
 //     if (flag == Add_t)
 //       ierr = MatSetValues(r, 1, &row, 1, &col, &it->second, ADD_VALUES);
 //     else if (flag == Insert_t)
 //       ierr = MatSetValues(r, 1, &row, 1, &col, &it->second, INSERT_VALUES);
 //     CHKERRCONTINUE(ierr);
 //   }
 
 // #ifdef CPPUTILS_VERBOSE
 //   out<<"  Matrix filled..."<<timer<<endl;
 // #endif
 
 //   /*
 //    Assemble vector, using the 2-step process:
 //    VecAssemblyBegin(), VecAssemblyEnd()
 //    Computations can be done while messages are in transition
 //    by placing code between these two statements.
 //    */
 //   ierr = MatAssemblyBegin(r,MAT_FINAL_ASSEMBLY);CHKERRCONTINUE(ierr);
 //   ierr = MatAssemblyEnd(r,MAT_FINAL_ASSEMBLY);CHKERRCONTINUE(ierr);
 
 //   value_type nrm;
 
 //   MatNorm(r,NORM_FROBENIUS,&nrm);
 
 // #ifdef CPPUTILS_VERBOSE
 //   out<<"  Norm computed... "<<timer<<endl;
 // #endif
 
 //   ierr = MatDestroy(&r);CHKERRCONTINUE(ierr);
 
 // #ifdef CPPUTILS_VERBOSE
 //   out<<"  Temporary data structures destroyed... "<<timer<<endl;
 // #endif
 
 //   return nrm;
 // }
 
 // SolverPETSc::value_type SolverPETSc::norm(const
 // SolverPETSc::sparse_vector_type& aa, Element_insertion_type flag) {
 
 // #ifdef CPPUTILS_VERBOSE
 //   // parallel output stream
 //   Output_stream out;
 //   // timer
 //   cpputils::ctimer timer;
 //   out<<"Inside SolverPETSc::norm(const sparse_vector&). "<<timer<<endl;
 // #endif
 
 //   Vec r;
 
 //   PetscErrorCode ierr = VecCreate(PETSC_COMM_WORLD,&r);CHKERRCONTINUE(ierr);
 //   ierr = VecSetSizes(r,PETSC_DECIDE, aa.size());CHKERRCONTINUE(ierr);
 //   ierr = VecSetFromOptions(r);CHKERRCONTINUE(ierr);
 
 // #ifdef CPPUTILS_VERBOSE
 //   out<<"  Vector created... "<<timer<<endl;
 // #endif
 
 //   // set values
 //   for (sparse_vector_type::const_hash_iterator it = aa.map_.begin(); it !=
 //   aa.map_.end(); ++it) {
 //     int row = it->first;
 //     if (flag == Add_t)
 //       ierr = VecSetValues(r, 1, &row, &it->second, ADD_VALUES);
 //     else if (flag == Insert_t)
 //       ierr = VecSetValues(r, 1, &row, &it->second, INSERT_VALUES);
 //     CHKERRCONTINUE(ierr);
 //   }
 
 // #ifdef CPPUTILS_VERBOSE
 //   out<<"  Vector filled..."<<timer<<endl;
 // #endif
 
 //   /*
 //    Assemble vector, using the 2-step process:
 //    VecAssemblyBegin(), VecAssemblyEnd()
 //    Computations can be done while messages are in transition
 //    by placing code between these two statements.
 //    */
 //   ierr = VecAssemblyBegin(r);CHKERRCONTINUE(ierr);
 //   ierr = VecAssemblyEnd(r);CHKERRCONTINUE(ierr);
 
 //   value_type nrm;
 
 //   VecNorm(r,NORM_2,&nrm);
 
 // #ifdef CPPUTILS_VERBOSE
 //   out<<"  Norm computed... "<<timer<<endl;
 // #endif
 
 //   ierr = VecDestroy(&r);CHKERRCONTINUE(ierr);
 
 // #ifdef CPPUTILS_VERBOSE
 //   out<<"  Temporary data structures destroyed... "<<timer<<endl;
 // #endif
 
 //   return nrm;
 
 // }
 
 // //
 // ///*
 // -------------------------------------------------------------------------- */
 // //SolverMumps::SolverMumps(SparseMatrix & matrix,
 // //                         const ID & id,
 // //                         const MemoryID & memory_id) :
 // //Solver(matrix, id, memory_id), is_mumps_data_initialized(false),
 // rhs_is_local(true) {
 // //  AKANTU_DEBUG_IN();
 // //
 // //#ifdef AKANTU_USE_MPI
 // //  parallel_method = SolverMumpsOptions::_fully_distributed;
 // //#else //AKANTU_USE_MPI
 // //  parallel_method = SolverMumpsOptions::_master_slave_distributed;
 // //#endif //AKANTU_USE_MPI
 // //
 // //  CommunicatorEventHandler & comm_event_handler = *this;
 // //
 // //  communicator.registerEventHandler(comm_event_handler);
 // //
 // //  AKANTU_DEBUG_OUT();
 // //}
 // //
 // ///*
 // -------------------------------------------------------------------------- */
 // //SolverMumps::~SolverMumps() {
 // //  AKANTU_DEBUG_IN();
 // //
 // //  AKANTU_DEBUG_OUT();
 // //}
 // //
 // ///*
 // -------------------------------------------------------------------------- */
 // //void SolverMumps::destroyMumpsData() {
 // //  AKANTU_DEBUG_IN();
 // //
 // //  if(is_mumps_data_initialized) {
 // //    mumps_data.job = _smj_destroy; // destroy
 // //    dmumps_c(&mumps_data);
 // //    is_mumps_data_initialized = false;
 // //  }
 // //
 // //  AKANTU_DEBUG_OUT();
 // //}
 // //
 // ///*
 // -------------------------------------------------------------------------- */
 // //void SolverMumps::onCommunicatorFinalize(const StaticCommunicator & comm) {
 // //  AKANTU_DEBUG_IN();
 // //
 // //  try{
 // //    const StaticCommunicatorMPI & comm_mpi =
 // //    dynamic_cast<const StaticCommunicatorMPI
 // &>(comm.getRealStaticCommunicator());
 // //    if(mumps_data.comm_fortran ==
 // MPI_Comm_c2f(comm_mpi.getMPICommunicator()))
 // //      destroyMumpsData();
 // //  } catch(...) {}
 // //
 // //  AKANTU_DEBUG_OUT();
 // //}
 // //
 // ///*
 // -------------------------------------------------------------------------- */
 // //void SolverMumps::initMumpsData(SolverMumpsOptions::ParallelMethod
 // parallel_method) {
 // //  switch(parallel_method) {
 // //    case SolverMumpsOptions::_fully_distributed:
 // //      icntl(18) = 3; //fully distributed
 // //      icntl(28) = 0; //automatic choice
 // //
 // //      mumps_data.nz_loc  = matrix->getNbNonZero();
 // //      mumps_data.irn_loc = matrix->getIRN().values;
 // //      mumps_data.jcn_loc = matrix->getJCN().values;
 // //      break;
 // //    case SolverMumpsOptions::_master_slave_distributed:
 // //      if(prank == 0) {
 // //        mumps_data.nz  = matrix->getNbNonZero();
 // //        mumps_data.irn = matrix->getIRN().values;
 // //        mumps_data.jcn = matrix->getJCN().values;
 // //      } else {
 // //        mumps_data.nz  = 0;
 // //        mumps_data.irn = NULL;
 // //        mumps_data.jcn = NULL;
 // //
 // //        icntl(18) = 0; //centralized
 // //        icntl(28) = 0; //sequential analysis
 // //      }
 // //      break;
 // //  }
 // //}
 // //
 // ///*
 // -------------------------------------------------------------------------- */
 // //void SolverMumps::initialize(SolverOptions & options) {
 // //  AKANTU_DEBUG_IN();
 // //
 // //  mumps_data.par = 1;
 // //
 // //  if(SolverMumpsOptions * opt = dynamic_cast<SolverMumpsOptions
 // *>(&options)) {
 // //    if(opt->parallel_method ==
 // SolverMumpsOptions::_master_slave_distributed) {
 // //      mumps_data.par = 0;
 // //    }
 // //  }
 // //
 // //  mumps_data.sym = 2 * (matrix->getSparseMatrixType() == _symmetric);
 // //  prank = communicator.whoAmI();
 // //#ifdef AKANTU_USE_MPI
 // //  mumps_data.comm_fortran = MPI_Comm_c2f(dynamic_cast<const
 // StaticCommunicatorMPI
 // &>(communicator.getRealStaticCommunicator()).getMPICommunicator());
 // //#endif
 // //
 // //  if(AKANTU_DEBUG_TEST(dblTrace)) {
 // //    icntl(1) = 2;
 // //    icntl(2) = 2;
 // //    icntl(3) = 2;
 // //    icntl(4) = 4;
 // //  }
 // //
 // //  mumps_data.job = _smj_initialize; //initialize
 // //  dmumps_c(&mumps_data);
 // //  is_mumps_data_initialized = true;
 // //
 // //  /*
 // ------------------------------------------------------------------------ */
 // //  UInt size = matrix->size();
 // //
 // //  if(prank == 0) {
 // //    std::stringstream sstr_rhs; sstr_rhs << id << ":rhs";
 // //    rhs = &(alloc<Real>(sstr_rhs.str(), size, 1, REAL_INIT_VALUE));
 // //  } else {
 // //    rhs = NULL;
 // //  }
 // //
 // //  /// No outputs
 // //  icntl(1) = 0;
 // //  icntl(2) = 0;
 // //  icntl(3) = 0;
 // //  icntl(4) = 0;
 // //  mumps_data.nz_alloc = 0;
 // //
 // //  if (AKANTU_DEBUG_TEST(dblDump)) icntl(4) = 4;
 // //
 // //  mumps_data.n   = size;
 // //
 // //  if(AKANTU_DEBUG_TEST(dblDump)) {
 // //    strcpy(mumps_data.write_problem, "mumps_matrix.mtx");
 // //  }
 // //
 // //  /*
 // ------------------------------------------------------------------------ */
 // //  // Default Scaling
 // //  icntl(8) = 77;
 // //
 // //  icntl(5) = 0; // Assembled matrix
 // //
 // //  SolverMumpsOptions * opt = dynamic_cast<SolverMumpsOptions *>(&options);
 // //  if(opt)
 // //    parallel_method = opt->parallel_method;
 // //
 // //  initMumpsData(parallel_method);
 // //
 // //  mumps_data.job = _smj_analyze; //analyze
 // //  dmumps_c(&mumps_data);
 // //
 // //  AKANTU_DEBUG_OUT();
 // //}
 // //
 // ///*
 // -------------------------------------------------------------------------- */
 // //void SolverMumps::setRHS(Array<Real> & rhs) {
 // //  if(prank == 0) {
 // //    matrix->getDOFSynchronizer().gather(rhs, 0, this->rhs);
 // //  } else {
 // //    matrix->getDOFSynchronizer().gather(rhs, 0);
 // //  }
 // //}
 // //
 // ///*
 // -------------------------------------------------------------------------- */
 // //void SolverMumps::solve() {
 // //  AKANTU_DEBUG_IN();
 // //
 // //  if(parallel_method == SolverMumpsOptions::_fully_distributed)
 // //    mumps_data.a_loc  = matrix->getA().values;
 // //  else
 // //    if(prank == 0) {
 // //      mumps_data.a  = matrix->getA().values;
 // //    }
 // //
 // //  if(prank == 0) {
 // //    mumps_data.rhs = rhs->values;
 // //  }
 // //
 // //  /// Default centralized dense second member
 // //  icntl(20) = 0;
 // //  icntl(21) = 0;
 // //
 // //  mumps_data.job = _smj_factorize_solve; //solve
 // //  dmumps_c(&mumps_data);
 // //
 // //  AKANTU_DEBUG_ASSERT(info(1) != -10, "Singular matrix");
 // //  AKANTU_DEBUG_ASSERT(info(1) == 0,
 // //                      "Error in mumps during solve process, check mumps
 // user guide INFO(1) ="
 // //                      << info(1));
 // //
 // //  AKANTU_DEBUG_OUT();
 // //}
 // //
 // ///*
 // -------------------------------------------------------------------------- */
 // //void SolverMumps::solve(Array<Real> & solution) {
 // //  AKANTU_DEBUG_IN();
 // //
 // //  solve();
 // //
 // //  if(prank == 0) {
 // //    matrix->getDOFSynchronizer().scatter(solution, 0, this->rhs);
 // //  } else {
 // //    matrix->getDOFSynchronizer().scatter(solution, 0);
 // //  }
 // //
 // //  AKANTU_DEBUG_OUT();
 // //}
 
 } // akantu
diff --git a/src/solver/solver_petsc.hh b/src/solver/solver_petsc.hh
index 241884da4..76837b321 100644
--- a/src/solver/solver_petsc.hh
+++ b/src/solver/solver_petsc.hh
@@ -1,183 +1,185 @@
 /**
  * @file   solver_petsc.hh
  *
  * @author Alejandro M. Aragón <alejandro.aragon@epfl.ch>
  * @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Tue May 13 2014
- * @date last modification: Wed Oct 07 2015
+ * @date last modification: Mon Jun 19 2017
  *
  * @brief  Solver class interface for the petsc solver
  *
  * @section LICENSE
  *
- * Copyright  (©)  2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de Lausanne)
+ * 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
+ * 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
+ * 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 "sparse_solver.hh"
 /* -------------------------------------------------------------------------- */
 #include <petscksp.h>
 /* -------------------------------------------------------------------------- */
 
 #ifndef __AKANTU_SOLVER_PETSC_HH__
 #define __AKANTU_SOLVER_PETSC_HH__
 
 namespace akantu {
 class SparseMatrixPETSc;
 class DOFManagerPETSc;
 }
 
 namespace akantu {
 
 class SolverPETSc : public SparseSolver {
 
   /* ------------------------------------------------------------------------ */
   /* Constructors/Destructors                                                 */
   /* ------------------------------------------------------------------------ */
 public:
   SolverPETSc(DOFManagerPETSc & dof_manager, const ID & matrix_id,
               const ID & id = "solver_petsc", const MemoryID & memory_id = 0);
 
   virtual ~SolverPETSc();
 
   /* ------------------------------------------------------------------------ */
   /* Methods                                                                  */
   /* ------------------------------------------------------------------------ */
 public:
   /// create the solver context and set the matrices
   virtual void initialize();
   virtual void setOperators();
   virtual void setRHS(Array<Real> & rhs);
   virtual void solve();
   virtual void solve(Array<Real> & solution);
 
 private:
   /// clean the petsc data
   virtual void destroyInternalData();
 
 private:
   /// DOFManager correctly typed
   DOFManagerPETSc & dof_manager;
 
   /// PETSc linear solver
   KSP ksp;
 
   /// Matrix defining the system of equations
   SparseMatrixPETSc & matrix;
 
   /// specify if the petsc_data is initialized or not
   bool is_petsc_data_initialized;
 };
 
 //   SolverPETSc(int argc, char *argv[]) : allocated_(false) {
 
 //     /*
 //      Set linear solver defaults for this problem (optional).
 //      - By extracting the KSP and PC contexts from the KSP context,
 //      we can then directly call any KSP and PC routines to set
 //      various options.
 //      - The following four statements are optional; all of these
 //      parameters could alternatively be specified at runtime via
 //      KSPSetFromOptions();
 //      */
 //     //      ierr = KSPGetPC(ksp_,&pc);CHKERRCONTINUE(ierr);
 //     //      ierr = PCSetType(pc,PCILU);CHKERRCONTINUE(ierr);
 //     //    ierr = PCSetType(pc,PCJACOBI);CHKERRCONTINUE(ierr);
 //     ierr =
 //     KSPSetTolerances(ksp_,1.e-5,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT);CHKERRCONTINUE(ierr);
 //   }
 
 //   //! Overload operator() to solve system of linear equations
 //   sparse_vector_type operator()(const sparse_matrix_type& AA, const
 //   sparse_vector_type& bb);
 
 //   //! Overload operator() to obtain reaction vector
 //   sparse_vector_type operator()(const sparse_matrix_type& Kpf, const
 //   sparse_matrix_type& Kpp, const sparse_vector_type& Up);
 
 //   //! Overload operator() to obtain the addition two vectors
 //   sparse_vector_type operator()(const sparse_vector_type& aa, const
 //   sparse_vector_type& bb);
 
 //   value_type norm(const sparse_matrix_type& aa, Element_insertion_type it =
 //   Add_t);
 
 //   value_type norm(const sparse_vector_type& aa, Element_insertion_type it =
 //   Add_t);
 
 //   // NOTE: the destructor will return an error if it is called after
 //   MPI_Finalize is
 //   // called because it uses collect communication to free-up allocated
 //   memory.
 //   ~SolverPETSc() {
 
 //     static bool exit = false;
 //     if (!exit) {
 //       // add finalize PETSc function at exit
 //       atexit(finalize);
 //       exit = true;
 //     }
 
 //     if (allocated_) {
 //       PetscErrorCode ierr = MatDestroy(&A_);CHKERRCONTINUE(ierr);
 //       ierr = VecDestroy(&x_);CHKERRCONTINUE(ierr);
 //       ierr = KSPDestroy(&ksp_);CHKERRCONTINUE(ierr);
 //     }
 //   }
 
 //   /* from the PETSc library, these are the options that can be passed
 //    to the command line
 
 //    Options Database Keys
 
 //    -options_table	                - Calls PetscOptionsView()
-//    -options_left	                - Prints unused options that remain in the
+//    -options_left	                - Prints unused options that remain in
+//    the
 //    database
 //    -objects_left                  - Prints list of all objects that have not
 //    been freed
 //    -mpidump	                    - Calls PetscMPIDump()
 //    -malloc_dump	                - Calls PetscMallocDump()
 //    -malloc_info	                - Prints total memory usage
 //    -malloc_log	                - Prints summary of memory usage
 
 //    Options Database Keys for Profiling
 
 //    -log_summary [filename]	    - Prints summary of flop and timing
 //    information to screen.
 //    If the filename is specified the summary is written to the file. See
 //    PetscLogView().
 //    -log_summary_python [filename]	- Prints data on of flop and timing
 //    usage
 //    to a file or screen.
-//    -log_all [filename]	        - Logs extensive profiling information See
+//    -log_all [filename]	        - Logs extensive profiling information
+//    See
 //    PetscLogDump().
 //    -log [filename]	            - Logs basic profiline information See
 //    PetscLogDump().
 //    -log_sync	                    - Log the synchronization in scatters,
 //    inner products and norms
 //    -log_mpe [filename]            - Creates a logfile viewable by the utility
 //    Upshot/Nupshot (in MPICH distribution)
 //     }
 //   }
 // };
 
 } // akantu
 
 #endif /* __AKANTU_SOLVER_PETSC_HH__ */
diff --git a/src/solver/sparse_matrix.cc b/src/solver/sparse_matrix.cc
index 593016ef0..607399442 100644
--- a/src/solver/sparse_matrix.cc
+++ b/src/solver/sparse_matrix.cc
@@ -1,80 +1,79 @@
 /**
  * @file   sparse_matrix.cc
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Mon Dec 13 2010
- * @date last modification: Mon Nov 16 2015
+ * @date last modification: Wed Nov 08 2017
  *
  * @brief  implementation of the SparseMatrix class
  *
  * @section LICENSE
  *
- * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
- * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
- * Solides)
+ * 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
+ * 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
+ * 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 <fstream>
 /* -------------------------------------------------------------------------- */
 #include "communicator.hh"
 #include "dof_manager.hh"
 #include "sparse_matrix.hh"
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 SparseMatrix::SparseMatrix(DOFManager & dof_manager,
                            const MatrixType & matrix_type, const ID & id)
     : id(id), _dof_manager(dof_manager), matrix_type(matrix_type),
       size_(dof_manager.getSystemSize()), nb_non_zero(0) {
   AKANTU_DEBUG_IN();
 
   const auto & comm = _dof_manager.getCommunicator();
   this->nb_proc = comm.getNbProc();
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 SparseMatrix::SparseMatrix(const SparseMatrix & matrix, const ID & id)
     : SparseMatrix(matrix._dof_manager, matrix.matrix_type, id) {
   nb_non_zero = matrix.nb_non_zero;
 }
 
 /* -------------------------------------------------------------------------- */
 SparseMatrix::~SparseMatrix() = default;
 
 /* -------------------------------------------------------------------------- */
 Array<Real> & operator*=(Array<Real> & vect, const SparseMatrix & mat) {
   Array<Real> tmp(vect.size(), vect.getNbComponent(), 0.);
   mat.matVecMul(vect, tmp);
 
   vect.copy(tmp);
   return vect;
 }
 
 /* -------------------------------------------------------------------------- */
 void SparseMatrix::add(const SparseMatrix & B, Real alpha) {
   B.addMeTo(*this, alpha);
 }
 
 /* -------------------------------------------------------------------------- */
 
 } // akantu
diff --git a/src/solver/sparse_matrix.hh b/src/solver/sparse_matrix.hh
index 9dc5de8b3..08fe2c837 100644
--- a/src/solver/sparse_matrix.hh
+++ b/src/solver/sparse_matrix.hh
@@ -1,162 +1,160 @@
-
 /**
  * @file   sparse_matrix.hh
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Mon Dec 13 2010
- * @date last modification: Fri Oct 16 2015
+ * @date last modification: Tue Feb 20 2018
  *
  * @brief  sparse matrix storage class (distributed assembled matrix)
  * This is a COO format (Coordinate List)
  *
  * @section LICENSE
  *
- * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
- * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
- * Solides)
+ * 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
+ * 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
+ * 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"
 /* -------------------------------------------------------------------------- */
 
 #ifndef __AKANTU_SPARSE_MATRIX_HH__
 #define __AKANTU_SPARSE_MATRIX_HH__
 
 /* -------------------------------------------------------------------------- */
 namespace akantu {
 class DOFManager;
 class TermsToAssemble;
 }
 
 namespace akantu {
 
 class SparseMatrix {
   /* ------------------------------------------------------------------------ */
   /* Constructors/Destructors                                                 */
   /* ------------------------------------------------------------------------ */
 public:
   SparseMatrix(DOFManager & dof_manager, const MatrixType & matrix_type,
                const ID & id = "sparse_matrix");
 
   SparseMatrix(const SparseMatrix & matrix, const ID & id = "sparse_matrix");
 
   virtual ~SparseMatrix();
 
   /* ------------------------------------------------------------------------ */
   /* Methods                                                                  */
   /* ------------------------------------------------------------------------ */
 public:
   /// remove the existing profile
   virtual void clearProfile();
 
   /// set the matrix to 0
   virtual void clear() = 0;
 
   /// add a non-zero element to the profile
   virtual UInt add(UInt i, UInt j) = 0;
 
   /// assemble a local matrix in the sparse one
   virtual void add(UInt i, UInt j, Real value) = 0;
 
   /// save the profil in a file using the MatrixMarket file format
   virtual void saveProfile(__attribute__((unused)) const std::string &) const {
     AKANTU_TO_IMPLEMENT();
   }
 
   /// save the matrix in a file using the MatrixMarket file format
   virtual void saveMatrix(__attribute__((unused)) const std::string &) const {
     AKANTU_TO_IMPLEMENT();
   };
 
   /// multiply the matrix by a coefficient
   virtual void mul(Real alpha) = 0;
 
   /// add matrices
   virtual void add(const SparseMatrix & matrix, Real alpha = 1.);
 
   /// Equivalent of *gemv in blas
   virtual void matVecMul(const Array<Real> & x, Array<Real> & y,
                          Real alpha = 1., Real beta = 0.) const = 0;
 
   /// modify the matrix to "remove" the blocked dof
   virtual void applyBoundary(Real block_val = 1.) = 0;
 
   /// operator *=
   SparseMatrix & operator*=(Real alpha) {
     this->mul(alpha);
     return *this;
   }
 
 protected:
   /// This is the revert of add B += \alpha * *this;
   virtual void addMeTo(SparseMatrix & B, Real alpha) const = 0;
 
   /* ------------------------------------------------------------------------ */
   /* Accessors                                                                */
   /* ------------------------------------------------------------------------ */
 public:
   /// return the values at potition i, j
   virtual inline Real operator()(__attribute__((unused)) UInt i,
                                  __attribute__((unused)) UInt j) const {
     AKANTU_TO_IMPLEMENT();
   }
   /// return the values at potition i, j
   virtual inline Real & operator()(__attribute__((unused)) UInt i,
                                    __attribute__((unused)) UInt j) {
     AKANTU_TO_IMPLEMENT();
   }
 
   AKANTU_GET_MACRO(NbNonZero, nb_non_zero, UInt);
   UInt size() const { return size_; }
   AKANTU_GET_MACRO(MatrixType, matrix_type, const MatrixType &);
 
   virtual UInt getRelease() const = 0;
 
   /* ------------------------------------------------------------------------ */
   /* Class Members                                                            */
   /* ------------------------------------------------------------------------ */
 protected:
   ID id;
 
   /// Underlying dof manager
   DOFManager & _dof_manager;
 
   /// sparce matrix type
   MatrixType matrix_type;
 
   /// Size of the matrix
   UInt size_;
 
   /// number of processors
   UInt nb_proc;
 
   /// number of non zero element
   UInt nb_non_zero;
 };
 
 Array<Real> & operator*=(Array<Real> & vect, const SparseMatrix & mat);
 
 } // akantu
 
 /* -------------------------------------------------------------------------- */
 /* inline functions                                                           */
 /* -------------------------------------------------------------------------- */
 #include "sparse_matrix_inline_impl.cc"
 
 #endif /* __AKANTU_SPARSE_MATRIX_HH__ */
diff --git a/src/solver/sparse_matrix_aij.cc b/src/solver/sparse_matrix_aij.cc
index acf516e85..cb10f23ae 100644
--- a/src/solver/sparse_matrix_aij.cc
+++ b/src/solver/sparse_matrix_aij.cc
@@ -1,215 +1,216 @@
 /**
  * @file   sparse_matrix_aij.cc
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
- * @date   Tue Aug 18 16:31:23 2015
+ * @date creation: Fri Aug 21 2015
+ * @date last modification: Mon Dec 04 2017
  *
  * @brief  Implementation of the AIJ sparse matrix
  *
  * @section LICENSE
  *
- * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * Copyright (©) 2015-2018 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
- * terms  of the  GNU Lesser  General Public  License as  published by  the Free
+ * 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
+ * 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 "sparse_matrix_aij.hh"
 #include "aka_iterators.hh"
 #include "dof_manager_default.hh"
 #include "dof_synchronizer.hh"
 #include "terms_to_assemble.hh"
 /* -------------------------------------------------------------------------- */
 #include <fstream>
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 SparseMatrixAIJ::SparseMatrixAIJ(DOFManagerDefault & dof_manager,
                                  const MatrixType & matrix_type, const ID & id)
     : SparseMatrix(dof_manager, matrix_type, id), dof_manager(dof_manager),
       irn(0, 1, id + ":irn"), jcn(0, 1, id + ":jcn"), a(0, 1, id + ":a") {}
 
 /* -------------------------------------------------------------------------- */
 SparseMatrixAIJ::SparseMatrixAIJ(const SparseMatrixAIJ & matrix, const ID & id)
     : SparseMatrix(matrix, id), dof_manager(matrix.dof_manager),
       irn(matrix.irn, true, id + ":irn"), jcn(matrix.jcn, true, id + ":jcn"),
       a(matrix.a, true, id + ":a") {}
 
 /* -------------------------------------------------------------------------- */
 SparseMatrixAIJ::~SparseMatrixAIJ() = default;
 
 /* -------------------------------------------------------------------------- */
 void SparseMatrixAIJ::applyBoundary(Real block_val) {
   AKANTU_DEBUG_IN();
 
   // clang-format off
   const auto & blocked_dofs = this->dof_manager.getGlobalBlockedDOFs();
 
   for (auto && ij_a : zip(irn, jcn, a)) {
     UInt ni = this->dof_manager.globalToLocalEquationNumber(std::get<0>(ij_a) - 1);
     UInt nj = this->dof_manager.globalToLocalEquationNumber(std::get<1>(ij_a) - 1);
     if (blocked_dofs(ni) || blocked_dofs(nj)) {
       std::get<2>(ij_a) =
           std::get<0>(ij_a) != std::get<1>(ij_a)   ? 0.
         : this->dof_manager.isLocalOrMasterDOF(ni) ? block_val
         :                                            0.;
     }
   }
 
   this->value_release++;
   // clang-format on
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void SparseMatrixAIJ::saveProfile(const std::string & filename) const {
   AKANTU_DEBUG_IN();
 
   std::ofstream outfile;
   outfile.open(filename.c_str());
 
   UInt m = this->size_;
   outfile << "%%MatrixMarket matrix coordinate pattern";
   if (this->matrix_type == _symmetric)
     outfile << " symmetric";
   else
     outfile << " general";
   outfile << std::endl;
   outfile << m << " " << m << " " << this->nb_non_zero << std::endl;
 
   for (UInt i = 0; i < this->nb_non_zero; ++i) {
     outfile << this->irn.storage()[i] << " " << this->jcn.storage()[i] << " 1"
             << std::endl;
   }
 
   outfile.close();
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void SparseMatrixAIJ::saveMatrix(const std::string & filename) const {
   AKANTU_DEBUG_IN();
 
   // open and set the properties of the stream
   std::ofstream outfile;
   outfile.open(filename.c_str());
   outfile.precision(std::numeric_limits<Real>::digits10);
 
   // write header
   outfile << "%%MatrixMarket matrix coordinate real";
   if (this->matrix_type == _symmetric)
     outfile << " symmetric";
   else
     outfile << " general";
   outfile << std::endl;
   outfile << this->size_ << " " << this->size_ << " " << this->nb_non_zero
           << std::endl;
 
   // write content
   for (UInt i = 0; i < this->nb_non_zero; ++i) {
     outfile << this->irn(i) << " " << this->jcn(i) << " " << this->a(i)
             << std::endl;
   }
 
   // time to end
   outfile.close();
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void SparseMatrixAIJ::matVecMul(const Array<Real> & x, Array<Real> & y,
                                 Real alpha, Real beta) const {
   AKANTU_DEBUG_IN();
 
   y *= beta;
 
   auto i_it = this->irn.begin();
   auto j_it = this->jcn.begin();
   auto a_it = this->a.begin();
   auto a_end = this->a.end();
   auto x_it = x.begin_reinterpret(x.size() * x.getNbComponent());
   auto y_it = y.begin_reinterpret(x.size() * x.getNbComponent());
 
   for (; a_it != a_end; ++i_it, ++j_it, ++a_it) {
     Int i = this->dof_manager.globalToLocalEquationNumber(*i_it - 1);
     Int j = this->dof_manager.globalToLocalEquationNumber(*j_it - 1);
     const Real & A = *a_it;
 
     y_it[i] += alpha * A * x_it[j];
 
     if ((this->matrix_type == _symmetric) && (i != j))
       y_it[j] += alpha * A * x_it[i];
   }
 
   if (this->dof_manager.hasSynchronizer())
     this->dof_manager.getSynchronizer().reduceSynchronize<AddOperation>(y);
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void SparseMatrixAIJ::copyContent(const SparseMatrix & matrix) {
   AKANTU_DEBUG_IN();
   const auto & mat = dynamic_cast<const SparseMatrixAIJ &>(matrix);
   AKANTU_DEBUG_ASSERT(nb_non_zero == mat.getNbNonZero(),
                       "The to matrix don't have the same profiles");
   memcpy(a.storage(), mat.getA().storage(), nb_non_zero * sizeof(Real));
 
   this->value_release++;
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <class MatrixType>
 void SparseMatrixAIJ::addMeToTemplated(MatrixType & B, Real alpha) const {
   UInt i, j;
   Real A_ij;
   for (auto && tuple : zip(irn, jcn, a)) {
     std::tie(i, j, A_ij) = tuple;
     B.add(i - 1, j - 1, alpha * A_ij);
   }
 }
 
 /* -------------------------------------------------------------------------- */
 void SparseMatrixAIJ::addMeTo(SparseMatrix & B, Real alpha) const {
   if (auto * B_aij = dynamic_cast<SparseMatrixAIJ *>(&B)) {
     this->addMeToTemplated<SparseMatrixAIJ>(*B_aij, alpha);
   } else {
     //    this->addMeToTemplated<SparseMatrix>(*this, alpha);
   }
 }
 
 /* -------------------------------------------------------------------------- */
 void SparseMatrixAIJ::mul(Real alpha) {
   this->a *= alpha;
   this->value_release++;
 }
 
 /* -------------------------------------------------------------------------- */
 void SparseMatrixAIJ::clear() {
   a.set(0.);
 
   this->value_release++;
 }
 
 } // namespace akantu
diff --git a/src/solver/sparse_matrix_aij.hh b/src/solver/sparse_matrix_aij.hh
index 9c067be24..668927be0 100644
--- a/src/solver/sparse_matrix_aij.hh
+++ b/src/solver/sparse_matrix_aij.hh
@@ -1,180 +1,182 @@
 /**
  * @file   sparse_matrix_aij.hh
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
- * @date   Mon Aug 17 21:22:57 2015
+ * @date creation: Mon Dec 13 2010
+ * @date last modification: Wed Nov 08 2017
  *
- * @brief AIJ implementation of the SparseMatrix (this the format used by Mumps)
+ * @brief  AIJ implementation of the SparseMatrix (this the format used by
+ * Mumps)
  *
  * @section LICENSE
  *
- * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * 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
+ * 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
+ * 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_array.hh"
 #include "aka_common.hh"
 #include "sparse_matrix.hh"
 /* -------------------------------------------------------------------------- */
 #include <unordered_map>
 /* -------------------------------------------------------------------------- */
 
 #ifndef __AKANTU_SPARSE_MATRIX_AIJ_HH__
 #define __AKANTU_SPARSE_MATRIX_AIJ_HH__
 
 namespace akantu {
 class DOFManagerDefault;
 class TermsToAssemble;
 }
 
 namespace akantu {
 
 class SparseMatrixAIJ : public SparseMatrix {
   /* ------------------------------------------------------------------------ */
   /* Constructors/Destructors                                                 */
   /* ------------------------------------------------------------------------ */
 public:
   SparseMatrixAIJ(DOFManagerDefault & dof_manager,
                   const MatrixType & matrix_type,
                   const ID & id = "sparse_matrix_aij");
 
   SparseMatrixAIJ(const SparseMatrixAIJ & matrix,
                   const ID & id = "sparse_matrix_aij");
 
   ~SparseMatrixAIJ() override;
 
   /* ------------------------------------------------------------------------ */
   /* Methods                                                                  */
   /* ------------------------------------------------------------------------ */
 public:
   /// remove the existing profile
   inline void clearProfile() override;
 
   /// add a non-zero element
   inline UInt add(UInt i, UInt j) override;
 
   /// set the matrix to 0
   void clear() override;
 
   /// assemble a local matrix in the sparse one
   inline void add(UInt i, UInt j, Real value) override;
 
   /// set the size of the matrix
   void resize(UInt size) { this->size_ = size; }
 
   /// modify the matrix to "remove" the blocked dof
   void applyBoundary(Real block_val = 1.) override;
 
   /// save the profil in a file using the MatrixMarket file format
   void saveProfile(const std::string & filename) const override;
 
   /// save the matrix in a file using the MatrixMarket file format
   void saveMatrix(const std::string & filename) const override;
 
   /// copy assuming the profile are the same
   virtual void copyContent(const SparseMatrix & matrix);
 
   /// multiply the matrix by a scalar
   void mul(Real alpha) override;
 
   /// add matrix *this += B
   // virtual void add(const SparseMatrix & matrix, Real alpha);
 
   /// Equivalent of *gemv in blas
   void matVecMul(const Array<Real> & x, Array<Real> & y, Real alpha = 1.,
                  Real beta = 0.) const override;
 
   /* ------------------------------------------------------------------------ */
   /// accessor to A_{ij} - if (i, j) not present it returns 0
   inline Real operator()(UInt i, UInt j) const override;
 
   /// accessor to A_{ij} - if (i, j) not present it fails, (i, j) should be
   /// first added to the profile
   inline Real & operator()(UInt i, UInt j) override;
 
 protected:
   /// This is the revert of add B += \alpha * *this;
   void addMeTo(SparseMatrix & B, Real alpha) const override;
 
 private:
   /// This is just to inline the addToMatrix function
   template <class MatrixType>
   void addMeToTemplated(MatrixType & B, Real alpha) const;
 
   /* ------------------------------------------------------------------------ */
   /* Accessors                                                                */
   /* ------------------------------------------------------------------------ */
 public:
   AKANTU_GET_MACRO(IRN, irn, const Array<Int> &);
 
   AKANTU_GET_MACRO(JCN, jcn, const Array<Int> &);
 
   AKANTU_GET_MACRO(A, a, const Array<Real> &);
 
   /// The release changes at each call of a function that changes the profile,
   /// it in increasing but could overflow so it should be checked as
   /// (my_release != release) and not as (my_release < release)
   AKANTU_GET_MACRO(ProfileRelease, profile_release, UInt);
   AKANTU_GET_MACRO(ValueRelease, value_release, UInt);
   UInt getRelease() const override { return value_release; }
 
 protected:
   using KeyCOO = std::pair<UInt, UInt>;
   using coordinate_list_map = std::unordered_map<KeyCOO, UInt>;
 
   /// get the pair corresponding to (i, j)
   inline KeyCOO key(UInt i, UInt j) const {
     if (this->matrix_type == _symmetric && (i > j))
       return std::make_pair(j, i);
     return std::make_pair(i, j);
   }
 
   /* ------------------------------------------------------------------------ */
   /* Class Members                                                            */
   /* ------------------------------------------------------------------------ */
 private:
   DOFManagerDefault & dof_manager;
 
   /// row indexes
   Array<Int> irn;
 
   /// column indexes
   Array<Int> jcn;
 
   /// values : A[k] = Matrix[irn[k]][jcn[k]]
   Array<Real> a;
 
   /// Profile release
   UInt profile_release{1};
 
   /// Value release
   UInt value_release{1};
 
   /// map for (i, j) ->  k correspondence
   coordinate_list_map irn_jcn_k;
 };
 
 } // akantu
 
 /* -------------------------------------------------------------------------- */
 /* inline functions                                                           */
 /* -------------------------------------------------------------------------- */
 #include "sparse_matrix_aij_inline_impl.cc"
 
 #endif /* __AKANTU_SPARSE_MATRIX_AIJ_HH__ */
diff --git a/src/solver/sparse_matrix_aij_inline_impl.cc b/src/solver/sparse_matrix_aij_inline_impl.cc
index 2c6ee5081..d9d8f8774 100644
--- a/src/solver/sparse_matrix_aij_inline_impl.cc
+++ b/src/solver/sparse_matrix_aij_inline_impl.cc
@@ -1,116 +1,118 @@
 /**
  * @file   sparse_matrix_aij_inline_impl.cc
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
- * @date   Tue Aug 18 00:42:45 2015
+ * @date creation: Fri Aug 21 2015
+ * @date last modification: Wed Nov 08 2017
  *
  * @brief  Implementation of inline functions of SparseMatrixAIJ
  *
  * @section LICENSE
  *
- * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * Copyright (©) 2015-2018 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
- * terms  of the  GNU Lesser  General Public  License as  published by  the Free
+ * 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
+ * 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 "sparse_matrix_aij.hh"
 
 /* -------------------------------------------------------------------------- */
 #ifndef __AKANTU_SPARSE_MATRIX_AIJ_INLINE_IMPL_CC__
 #define __AKANTU_SPARSE_MATRIX_AIJ_INLINE_IMPL_CC__
 
 namespace akantu {
 
 inline UInt SparseMatrixAIJ::add(UInt i, UInt j) {
   KeyCOO jcn_irn = this->key(i, j);
 
   auto it = this->irn_jcn_k.find(jcn_irn);
 
   if (!(it == this->irn_jcn_k.end()))
     return it->second;
 
   if (i + 1 > this->size_)
     this->size_ = i + 1;
   if (j + 1 > this->size_)
     this->size_ = j + 1;
 
   this->irn.push_back(i + 1);
   this->jcn.push_back(j + 1);
   this->a.push_back(0.);
 
   this->irn_jcn_k[jcn_irn] = this->nb_non_zero;
 
   (this->nb_non_zero)++;
 
   this->profile_release++;
   this->value_release++;
 
   return (this->nb_non_zero - 1);
 }
 
 /* -------------------------------------------------------------------------- */
 inline void SparseMatrixAIJ::clearProfile() {
   SparseMatrix::clearProfile();
 
   this->irn_jcn_k.clear();
 
   this->irn.resize(0);
   this->jcn.resize(0);
   this->a.resize(0);
 
   this->size_ = 0;
 
   this->profile_release++;
   this->value_release++;
 }
 
 /* -------------------------------------------------------------------------- */
 inline void SparseMatrixAIJ::add(UInt i, UInt j, Real value) {
   UInt idx = this->add(i, j);
 
   this->a(idx) += value;
 
   this->value_release++;
 }
 
 /* -------------------------------------------------------------------------- */
 inline Real SparseMatrixAIJ::operator()(UInt i, UInt j) const {
   KeyCOO jcn_irn = this->key(i, j);
   auto irn_jcn_k_it = this->irn_jcn_k.find(jcn_irn);
 
   if (irn_jcn_k_it == this->irn_jcn_k.end())
     return 0.;
   return this->a(irn_jcn_k_it->second);
 }
 
 /* -------------------------------------------------------------------------- */
 inline Real & SparseMatrixAIJ::operator()(UInt i, UInt j) {
   KeyCOO jcn_irn = this->key(i, j);
   auto irn_jcn_k_it = this->irn_jcn_k.find(jcn_irn);
   AKANTU_DEBUG_ASSERT(irn_jcn_k_it != this->irn_jcn_k.end(),
                       "Couple (i,j) = (" << i << "," << j
                                          << ") does not exist in the profile");
 
   // it may change the profile so it is considered as a change
   this->value_release++;
 
   return this->a(irn_jcn_k_it->second);
 }
 
 } // namespace akantu
 
 #endif /* __AKANTU_SPARSE_MATRIX_AIJ_INLINE_IMPL_CC__ */
diff --git a/src/solver/sparse_matrix_inline_impl.cc b/src/solver/sparse_matrix_inline_impl.cc
index dc1a84948..8a90f0860 100644
--- a/src/solver/sparse_matrix_inline_impl.cc
+++ b/src/solver/sparse_matrix_inline_impl.cc
@@ -1,37 +1,36 @@
 /**
  * @file   sparse_matrix_inline_impl.cc
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Mon Dec 13 2010
- * @date last modification: Tue Aug 18 2015
+ * @date last modification: Mon Jun 19 2017
  *
  * @brief  implementation of inline methods of the SparseMatrix class
  *
  * @section LICENSE
  *
- * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
- * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
- * Solides)
+ * 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
+ * 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
+ * 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/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 namespace akantu {
 
 inline void SparseMatrix::clearProfile() { this->nb_non_zero = 0; }
 
 } // akantu
diff --git a/src/solver/sparse_matrix_petsc.cc b/src/solver/sparse_matrix_petsc.cc
index 906c4056e..ab5c6dbad 100644
--- a/src/solver/sparse_matrix_petsc.cc
+++ b/src/solver/sparse_matrix_petsc.cc
@@ -1,402 +1,405 @@
 /**
- * @file   petsc_matrix.cc
- * @author Aurelia Cuba Ramos <aurelia.cubaramos@epfl.ch>
- * @date   Mon Jul 21 17:40:41 2014
+ * @file   sparse_matrix_petsc.cc
+ *
+ * @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
+ *
+ * @date creation: Mon Dec 13 2010
+ * @date last modification: Sat Feb 03 2018
  *
  * @brief  Implementation of PETSc matrix class
  *
  * @section LICENSE
  *
- * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * 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
+ * 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
+ * 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 "sparse_matrix_petsc.hh"
 #include "dof_manager_petsc.hh"
 #include "mpi_type_wrapper.hh"
 #include "static_communicator.hh"
 /* -------------------------------------------------------------------------- */
 #include <cstring>
 #include <petscsys.h>
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 
 #if not defined(PETSC_CLANGUAGE_CXX)
 int aka_PETScError(int ierr) {
   CHKERRQ(ierr);
   return 0;
 }
 #endif
 
 /* -------------------------------------------------------------------------- */
 SparseMatrixPETSc::SparseMatrixPETSc(DOFManagerPETSc & dof_manager,
                                      const MatrixType & sparse_matrix_type,
                                      const ID & id, const MemoryID & memory_id)
     : SparseMatrix(dof_manager, matrix_type, id, memory_id),
       dof_manager(dof_manager), d_nnz(0, 1, "dnnz"), o_nnz(0, 1, "onnz"),
       first_global_index(0) {
   AKANTU_DEBUG_IN();
 
   PetscErrorCode ierr;
 
   // create the PETSc matrix object
   ierr = MatCreate(PETSC_COMM_WORLD, &this->mat);
   CHKERRXX(ierr);
 
   /**
    * Set the matrix type
    * @todo PETSc does currently not support a straightforward way to
    * apply Dirichlet boundary conditions for MPISBAIJ
    * matrices. Therefore always the entire matrix is allocated. It
    * would be possible to use MATSBAIJ for sequential matrices in case
    * memory becomes critical. Also, block matrices would give a much
    * better performance. Modify this in the future!
    */
   ierr = MatSetType(this->mat, MATAIJ);
   CHKERRXX(ierr);
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 SparseMatrixPETSc::~SparseMatrixPETSc() {
   AKANTU_DEBUG_IN();
 
   /// destroy all the PETSc data structures used for this matrix
   PetscErrorCode ierr;
   ierr = MatDestroy(&this->mat);
   CHKERRXX(ierr);
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 /**
  * With this method each processor computes the dimensions of the
  * local matrix, i.e. the part of the global matrix it is storing.
  * @param dof_synchronizer dof synchronizer that maps the local
  * dofs to the global dofs and the equation numbers, i.e., the
  * position at which the dof is assembled in the matrix
  */
 void SparseMatrixPETSc::setSize() {
   AKANTU_DEBUG_IN();
 
   //  PetscErrorCode ierr;
 
   /// find the number of dofs corresponding to master or local nodes
   UInt nb_dofs = this->dof_manager.getLocalSystemSize();
   // UInt nb_local_master_dofs = 0;
 
   /// create array to store the global equation number of all local and master
   /// dofs
   Array<Int> local_master_eq_nbs(nb_dofs);
   Array<Int>::scalar_iterator it_eq_nb = local_master_eq_nbs.begin();
 
   throw;
   /// get the pointer to the global equation number array
   //  Int * eq_nb_val =
   //       this->dof_synchronizer->getGlobalDOFEquationNumbers().storage();
 
   //   for (UInt i = 0; i < nb_dofs; ++i) {
   //     if (this->dof_synchronizer->isLocalOrMasterDOF(i)) {
   //       *it_eq_nb = eq_nb_val[i];
   //       ++it_eq_nb;
   //       ++nb_local_master_dofs;
   //     }
   //   }
 
   //   local_master_eq_nbs.resize(nb_local_master_dofs);
 
   //   /// set the local size
   //   this->local_size = nb_local_master_dofs;
 
   // /// resize PETSc matrix
   // #if defined(AKANTU_USE_MPI)
   //   ierr = MatSetSizes(this->petsc_matrix_wrapper->mat, this->local_size,
   //                      this->local_size, this->size, this->size);
   //   CHKERRXX(ierr);
   // #else
   //   ierr = MatSetSizes(this->petsc_matrix_wrapper->mat, this->local_size,
   //                      this->local_size);
   //   CHKERRXX(ierr);
   // #endif
 
   //   /// create mapping from akantu global numbering to petsc global numbering
   //   this->createGlobalAkantuToPETScMap(local_master_eq_nbs.storage());
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 /**
  * This method generates a mapping from the global Akantu equation
  * numbering to the global PETSc dof ordering
  * @param local_master_eq_nbs_ptr Int pointer to the array of equation
  * numbers of all local or master dofs, i.e. the row indices of the
  * local matrix
  */
 void SparseMatrixPETSc::createGlobalAkantuToPETScMap(
     Int * local_master_eq_nbs_ptr) {
   AKANTU_DEBUG_IN();
 
   PetscErrorCode ierr;
 
   StaticCommunicator & comm = StaticCommunicator::getStaticCommunicator();
   UInt rank = comm.whoAmI();
 
   // initialize vector to store the number of local and master nodes that are
   // assigned to each processor
   Vector<UInt> master_local_ndofs_per_proc(nb_proc);
 
   /// store the nb of master and local dofs on each processor
   master_local_ndofs_per_proc(rank) = this->local_size;
 
   /// exchange the information among all processors
   comm.allGather(master_local_ndofs_per_proc.storage(), 1);
 
   /// each processor creates a map for his akantu global dofs to the
   /// corresponding petsc global dofs
 
   /// determine the PETSc-index for the first dof on each processor
 
   for (UInt i = 0; i < rank; ++i) {
     this->first_global_index += master_local_ndofs_per_proc(i);
   }
 
   /// create array for petsc ordering
   Array<Int> petsc_dofs(this->local_size);
   Array<Int>::scalar_iterator it_petsc_dofs = petsc_dofs.begin();
 
   for (Int i = this->first_global_index;
        i < this->first_global_index + this->local_size; ++i, ++it_petsc_dofs) {
     *it_petsc_dofs = i;
   }
 
   ierr =
       AOCreateBasic(PETSC_COMM_WORLD, this->local_size, local_master_eq_nbs_ptr,
                     petsc_dofs.storage(), &(this->ao));
   CHKERRXX(ierr);
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 /**
  * Method to save the nonzero pattern and the values stored at each position
  * @param filename name of the file in which the information will be stored
  */
 void SparseMatrixPETSc::saveMatrix(const std::string & filename) const {
   AKANTU_DEBUG_IN();
 
   PetscErrorCode ierr;
 
   /// create Petsc viewer
   PetscViewer viewer;
   ierr = PetscViewerASCIIOpen(PETSC_COMM_WORLD, filename.c_str(), &viewer);
   CHKERRXX(ierr);
 
   /// set the format
   PetscViewerSetFormat(viewer, PETSC_VIEWER_DEFAULT);
   CHKERRXX(ierr);
 
   /// save the matrix
   /// @todo Write should be done in serial -> might cause problems
   ierr = MatView(this->mat, viewer);
   CHKERRXX(ierr);
 
   /// destroy the viewer
   ierr = PetscViewerDestroy(&viewer);
   CHKERRXX(ierr);
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 /**
  * Method to add an Akantu sparse matrix to the PETSc matrix
  * @param matrix Akantu sparse matrix to be added
  * @param alpha the factor specifying how many times the matrix should be added
  */
 // void SparseMatrixPETSc::add(const SparseMatrix & matrix, Real alpha) {
 //   PetscErrorCode ierr;
 //   //  AKANTU_DEBUG_ASSERT(nb_non_zero == matrix.getNbNonZero(),
 //   //                  "The two matrix don't have the same profiles");
 
 //   Real val_to_add = 0;
 //   Array<Int> index(2);
 //   for (UInt n = 0; n < matrix.getNbNonZero(); ++n) {
 //     UInt mat_to_add_offset = matrix.getOffset();
 //     index(0) = matrix.getIRN()(n) - mat_to_add_offset;
 //     index(1) = matrix.getJCN()(n) - mat_to_add_offset;
 //     AOApplicationToPetsc(this->petsc_matrix_wrapper->ao, 2, index.storage());
 //     if (this->sparse_matrix_type == _symmetric && index(0) > index(1))
 //       std::swap(index(0), index(1));
 
 //     val_to_add = matrix.getA()(n) * alpha;
 //     /// MatSetValue might be very slow for MATBAIJ, might need to use
 //     /// MatSetValuesBlocked
 //     ierr = MatSetValue(this->petsc_matrix_wrapper->mat, index(0), index(1),
 //                        val_to_add, ADD_VALUES);
 //     CHKERRXX(ierr);
 //     /// chek if sparse matrix to be added is symmetric. In this case
 //     /// the value also needs to be added at the transposed location in
 //     /// the matrix because PETSc is using the full profile, also for
 //     symmetric
 //     /// matrices
 //     if (matrix.getSparseMatrixType() == _symmetric && index(0) != index(1))
 //       ierr = MatSetValue(this->petsc_matrix_wrapper->mat, index(1), index(0),
 //                          val_to_add, ADD_VALUES);
 //     CHKERRXX(ierr);
 //   }
 
 //   this->performAssembly();
 // }
 
 /* -------------------------------------------------------------------------- */
 /**
  * Method to add another PETSc matrix to this PETSc matrix
  * @param matrix PETSc matrix to be added
  * @param alpha the factor specifying how many times the matrix should be added
  */
 void SparseMatrixPETSc::add(const SparseMatrixPETSc & matrix, Real alpha) {
   PetscErrorCode ierr;
 
   ierr = MatAXPY(this->mat, alpha, matrix.mat, SAME_NONZERO_PATTERN);
   CHKERRXX(ierr);
 
   this->performAssembly();
 }
 
 /* -------------------------------------------------------------------------- */
 /**
  * MatSetValues() generally caches the values. The matrix is ready to
  * use only after MatAssemblyBegin() and MatAssemblyEnd() have been
  * called. (http://www.mcs.anl.gov/petsc/)
  */
 void SparseMatrixPETSc::performAssembly() {
   this->beginAssembly();
   this->endAssembly();
 }
 
 /* -------------------------------------------------------------------------- */
 void SparseMatrixPETSc::beginAssembly() {
   PetscErrorCode ierr;
   ierr = MatAssemblyBegin(this->mat, MAT_FINAL_ASSEMBLY);
   CHKERRXX(ierr);
   ierr = MatAssemblyEnd(this->mat, MAT_FINAL_ASSEMBLY);
   CHKERRXX(ierr);
 }
 
 /* -------------------------------------------------------------------------- */
 void SparseMatrixPETSc::endAssembly() {
   PetscErrorCode ierr;
   ierr = MatAssemblyEnd(this->mat, MAT_FINAL_ASSEMBLY);
   CHKERRXX(ierr);
 }
 
 /* -------------------------------------------------------------------------- */
 /// access K(i, j). Works only for dofs on this processor!!!!
 Real SparseMatrixPETSc::operator()(UInt i, UInt j) const {
   AKANTU_DEBUG_IN();
 
   // AKANTU_DEBUG_ASSERT(this->dof_synchronizer->isLocalOrMasterDOF(i) &&
   //                         this->dof_synchronizer->isLocalOrMasterDOF(j),
   //                     "Operator works only for dofs on this processor");
 
   // Array<Int> index(2, 1);
   // index(0) = this->dof_synchronizer->getDOFGlobalID(i);
   // index(1) = this->dof_synchronizer->getDOFGlobalID(j);
   // AOApplicationToPetsc(this->petsc_matrix_wrapper->ao, 2, index.storage());
 
   // Real value = 0;
 
   // PetscErrorCode ierr;
   // /// @todo MatGetValue might be very slow for MATBAIJ, might need to use
   // /// MatGetValuesBlocked
   // ierr = MatGetValues(this->petsc_matrix_wrapper->mat, 1, &index(0), 1,
   //                     &index(1), &value);
   // CHKERRXX(ierr);
 
   // AKANTU_DEBUG_OUT();
 
   // return value;
   return 0.;
 }
 
 /* -------------------------------------------------------------------------- */
 /**
  * Apply Dirichlet boundary conditions by zeroing the rows and columns which
  * correspond to blocked dofs
  * @param boundary array of booleans which are true if the dof at this position
  * is blocked
  * @param block_val the value in the diagonal entry of blocked rows
  */
 void SparseMatrixPETSc::applyBoundary(const Array<bool> & boundary,
                                       Real block_val) {
   AKANTU_DEBUG_IN();
 
   // PetscErrorCode ierr;
 
   // /// get the global equation numbers to find the rows that need to be zeroed
   // /// for the blocked dofs
   // Int * eq_nb_val =
   // dof_synchronizer->getGlobalDOFEquationNumbers().storage();
 
   // /// every processor calls the MatSetZero() only for his local or master
   // dofs.
   // /// This assures that not two processors or more try to zero the same row
   // UInt nb_component = boundary.getNbComponent();
   // UInt size = boundary.size();
   // Int nb_blocked_local_master_eq_nb = 0;
   // Array<Int> blocked_local_master_eq_nb(this->local_size);
   // Int * blocked_lm_eq_nb_ptr = blocked_local_master_eq_nb.storage();
 
   // for (UInt i = 0; i < size; ++i) {
   //   for (UInt j = 0; j < nb_component; ++j) {
   //     UInt local_dof = i * nb_component + j;
   //     if (boundary(i, j) == true &&
   //         this->dof_synchronizer->isLocalOrMasterDOF(local_dof)) {
   //       Int global_eq_nb = *eq_nb_val;
   //       *blocked_lm_eq_nb_ptr = global_eq_nb;
   //       ++nb_blocked_local_master_eq_nb;
   //       ++blocked_lm_eq_nb_ptr;
   //     }
   //     ++eq_nb_val;
   //   }
   // }
   // blocked_local_master_eq_nb.resize(nb_blocked_local_master_eq_nb);
 
   // ierr = AOApplicationToPetsc(this->petsc_matrix_wrapper->ao,
   //                             nb_blocked_local_master_eq_nb,
   //                             blocked_local_master_eq_nb.storage());
   // CHKERRXX(ierr);
   // ierr = MatZeroRowsColumns(
   //     this->petsc_matrix_wrapper->mat, nb_blocked_local_master_eq_nb,
   //     blocked_local_master_eq_nb.storage(), block_val, 0, 0);
   // CHKERRXX(ierr);
 
   // this->performAssembly();
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 /// set all entries to zero while keeping the same nonzero pattern
 void SparseMatrixPETSc::clear() { MatZeroEntries(this->mat); }
 
 } // akantu
diff --git a/src/solver/sparse_matrix_petsc.hh b/src/solver/sparse_matrix_petsc.hh
index fafa3b64c..89597ebd5 100644
--- a/src/solver/sparse_matrix_petsc.hh
+++ b/src/solver/sparse_matrix_petsc.hh
@@ -1,142 +1,141 @@
 /**
- * @file   petsc_matrix.hh
+ * @file   sparse_matrix_petsc.hh
  *
  * @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
  *
  * @date creation: Fri Jun 18 2010
- * @date last modification: Fri Aug 21 2015
+ * @date last modification: Tue Feb 06 2018
  *
  * @brief  Interface for PETSc matrices
  *
  * @section LICENSE
  *
- * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
- * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
- * Solides)
+ * 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
+ * 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
+ * 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_PETSC_MATRIX_HH__
 #define __AKANTU_PETSC_MATRIX_HH__
 
 /* -------------------------------------------------------------------------- */
 #include "sparse_matrix.hh"
 /* -------------------------------------------------------------------------- */
 #include <petscao.h>
 #include <petscmat.h>
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 class DOFManagerPETSc;
 }
 
 namespace akantu {
 
 class SparseMatrixPETSc : public SparseMatrix {
   /* ------------------------------------------------------------------------ */
   /* Constructors/Destructors                                                 */
   /* ------------------------------------------------------------------------ */
 public:
   SparseMatrixPETSc(DOFManagerPETSc & dof_manager,
                     const MatrixType & matrix_type,
                     const ID & id = "sparse_matrix",
                     const MemoryID & memory_id = 0);
 
   SparseMatrixPETSc(const SparseMatrix & matrix,
                     const ID & id = "sparse_matrix_petsc",
                     const MemoryID & memory_id = 0);
 
   virtual ~SparseMatrixPETSc();
 
   /* ------------------------------------------------------------------------ */
   /* Methods                                                                  */
   /* ------------------------------------------------------------------------ */
 public:
   /// set the matrix to 0
   virtual void clear();
 
   /// modify the matrix to "remove" the blocked dof
   virtual void applyBoundary(const Array<bool> & boundary, Real block_val = 1.);
 
   /// save the matrix in a ASCII file format
   virtual void saveMatrix(const std::string & filename) const;
 
   /// add a sparse matrix assuming the profile are the same
   virtual void add(const SparseMatrix & matrix, Real alpha);
   /// add a petsc matrix assuming the profile are the same
   virtual void add(const SparseMatrixPETSc & matrix, Real alpha);
 
   Real operator()(UInt i, UInt j) const;
 
 protected:
   typedef std::pair<UInt, UInt> KeyCOO;
   inline KeyCOO key(UInt i, UInt j) const { return std::make_pair(i, j); }
 
 private:
   virtual void destroyInternalData();
 
   /// set the size of the PETSc matrix
   void setSize();
   void createGlobalAkantuToPETScMap(Int * local_master_eq_nbs_ptr);
   void createLocalAkantuToPETScMap();
 
   /// start to assemble the matrix
   void beginAssembly();
   /// finishes to assemble the matrix
   void endAssembly();
 
   /// perform the assembly stuff from petsc
   void performAssembly();
 
   /* ------------------------------------------------------------------------ */
   /* Accessors                                                                */
   /* ------------------------------------------------------------------------ */
 public:
   AKANTU_GET_MACRO(PETScMat, mat, const Mat &);
   /* ------------------------------------------------------------------------ */
   /* Class Members                                                            */
   /* ------------------------------------------------------------------------ */
 private:
   // DOFManagerPETSc that contains the numbering for petsc
   DOFManagerPETSc & dof_manager;
 
   /// store the PETSc matrix
   Mat mat;
 
   AO ao;
 
   /// size of the diagonal part of the matrix partition
   Int local_size;
 
   /// number of nonzeros in every row of the diagonal part
   Array<Int> d_nnz;
 
   /// number of nonzeros in every row of the off-diagonal part
   Array<Int> o_nnz;
 
   /// the global index of the first local row
   Int first_global_index;
 
   /// bool to indicate if the matrix data has been initialized by calling
   /// MatCreate
   bool is_petsc_matrix_initialized;
 };
 
 } // akantu
 
 #endif /* __AKANTU_PETSC_MATRIX_HH__ */
diff --git a/src/solver/sparse_solver.cc b/src/solver/sparse_solver.cc
index 81e6a18f8..9fe6be43a 100644
--- a/src/solver/sparse_solver.cc
+++ b/src/solver/sparse_solver.cc
@@ -1,85 +1,84 @@
 /**
- * @file   solver.cc
+ * @file   sparse_solver.cc
  *
  * @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Mon Dec 13 2010
- * @date last modification: Tue Jan 19 2016
+ * @date last modification: Fri Dec 08 2017
  *
  * @brief  Solver interface class
  *
  * @section LICENSE
  *
- * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
- * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
- * Solides)
+ * 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
+ * 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
+ * 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 "sparse_solver.hh"
 #include "communicator.hh"
 #include "dof_manager.hh"
 #include "mesh.hh"
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 SparseSolver::SparseSolver(DOFManager & dof_manager, const ID & matrix_id,
                            const ID & id, const MemoryID & memory_id)
     : Memory(id, memory_id), Parsable(ParserType::_solver, id),
       _dof_manager(dof_manager), matrix_id(matrix_id),
       communicator(dof_manager.getCommunicator()) {
   AKANTU_DEBUG_IN();
 
   // OK this is fishy...
   this->communicator.registerEventHandler(*this);
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 SparseSolver::~SparseSolver() {
   AKANTU_DEBUG_IN();
 
   // this->destroyInternalData();
   this->communicator.unregisterEventHandler(*this);
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void SparseSolver::beforeStaticSolverDestroy() {
   AKANTU_DEBUG_IN();
 
   try {
     this->destroyInternalData();
   } catch (...) {
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void SparseSolver::createSynchronizerRegistry() {
   // this->synch_registry = new SynchronizerRegistry(this);
 }
 
 void SparseSolver::onCommunicatorFinalize() { this->destroyInternalData(); }
 
 } // akantu
diff --git a/src/solver/sparse_solver.hh b/src/solver/sparse_solver.hh
index 7c79df5a1..5b042f3c3 100644
--- a/src/solver/sparse_solver.hh
+++ b/src/solver/sparse_solver.hh
@@ -1,130 +1,130 @@
 /**
  * @file   sparse_solver.hh
  *
  * @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
+ * @author Lucas Frerot <lucas.frerot@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Fri Jun 18 2010
- * @date last modification: Tue Jan 19 2016
+ * @date last modification: Wed Jan 24 2018
  *
  * @brief  interface for solvers
  *
  * @section LICENSE
  *
- * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
- * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
- * Solides)
+ * 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
+ * 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
+ * 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_memory.hh"
 #include "communicator_event_handler.hh"
 #include "parsable.hh"
 /* -------------------------------------------------------------------------- */
 
 #ifndef __AKANTU_SOLVER_HH__
 #define __AKANTU_SOLVER_HH__
 
 namespace akantu {
 enum SolverParallelMethod {
   _not_parallel,
   _fully_distributed,
   _master_slave_distributed
 };
 
 class DOFManager;
 }
 
 namespace akantu {
 
 class SparseSolver : protected Memory,
                      public Parsable,
                      public CommunicatorEventHandler {
   /* ------------------------------------------------------------------------ */
   /* Constructors/Destructors                                                 */
   /* ------------------------------------------------------------------------ */
 public:
   SparseSolver(DOFManager & dof_manager, const ID & matrix_id,
                const ID & id = "solver", const MemoryID & memory_id = 0);
 
   ~SparseSolver() override;
   /* ------------------------------------------------------------------------ */
   /* Methods                                                                  */
   /* ------------------------------------------------------------------------ */
 public:
   /// initialize the solver
   virtual void initialize() = 0;
 
   virtual void analysis(){};
 
   virtual void factorize(){};
 
   virtual void solve(){};
 
 protected:
   virtual void destroyInternalData(){};
 
 public:
   virtual void beforeStaticSolverDestroy();
 
   void createSynchronizerRegistry();
   /* ------------------------------------------------------------------------ */
   /* Data Accessor inherited members                                          */
   /* ------------------------------------------------------------------------ */
 public:
   void onCommunicatorFinalize() override;
 
   // inline virtual UInt getNbDataForDOFs(const Array<UInt> & dofs,
   //                                      SynchronizationTag tag) const;
 
   // inline virtual void packDOFData(CommunicationBuffer & buffer,
   //                                 const Array<UInt> & dofs,
   //                                 SynchronizationTag tag) const;
 
   // inline virtual void unpackDOFData(CommunicationBuffer & buffer,
   //                                   const Array<UInt> & dofs,
   //                                   SynchronizationTag tag);
 
   /* ------------------------------------------------------------------------ */
   /* Class Members                                                            */
   /* ------------------------------------------------------------------------ */
 protected:
   /// manager handling the dofs for this SparseMatrix solver
   DOFManager & _dof_manager;
 
   /// The id of the associated matrix
   ID matrix_id;
 
   /// How to parallelize the solve
   SolverParallelMethod parallel_method;
 
   /// Communicator used by the solver
   Communicator & communicator;
 };
 
 namespace debug {
   class SingularMatrixException : public Exception {
   public:
     SingularMatrixException(const SparseMatrix & matrix)
         : Exception("Solver encountered singular matrix"), matrix(matrix) {}
     const SparseMatrix & matrix;
   };
 }
 
 } // akantu
 
 #endif /* __AKANTU_SOLVER_HH__ */
diff --git a/src/solver/sparse_solver_inline_impl.cc b/src/solver/sparse_solver_inline_impl.cc
index 98e3a7bc9..a2890274e 100644
--- a/src/solver/sparse_solver_inline_impl.cc
+++ b/src/solver/sparse_solver_inline_impl.cc
@@ -1,83 +1,87 @@
 /**
- * @file   solver_inline_impl.cc
- * @author Aurelia Cuba Ramos <aurelia.cubaramos@epfl.ch>
- * @date   Thu Nov 13 14:43:41 2014
+ * @file   sparse_solver_inline_impl.cc
+ *
+ * @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
+ * @author Nicolas Richart <nicolas.richart@epfl.ch>
+ *
+ * @date creation: Mon Dec 13 2010
+ * @date last modification: Sun Aug 13 2017
  *
  * @brief  implementation of solver inline functions
  *
  * @section LICENSE
  *
- * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * 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
+ * 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
+ * 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/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 // inline UInt Solver::getNbDataForDOFs(const Array<UInt> & dofs,
 // 				     SynchronizationTag tag) const {
 //   AKANTU_DEBUG_IN();
 
 //   UInt size = 0;
 
 //   switch(tag) {
 //   case _gst_solver_solution: {
 //     size += dofs.size() * sizeof(Real);
 //     break;
 //   }
 //   default: {  }
 //   }
 
 //   AKANTU_DEBUG_OUT();
 //   return size;
 // }
 
 // /* --------------------------------------------------------------------------
 // */
 // inline void Solver::packDOFData(CommunicationBuffer & buffer,
 // 				const Array<UInt> & dofs,
 // 				SynchronizationTag tag) const {
 //   AKANTU_DEBUG_IN();
 
 //   switch(tag) {
 //   case _gst_solver_solution: {
 //     packDOFDataHelper(*solution, buffer, dofs);
 //     break;
 //   }
 //   default: {
 //   }
 //   }
 
 //   AKANTU_DEBUG_OUT();
 // }
 
 // /* --------------------------------------------------------------------------
 // */
 // inline void Solver::unpackDOFData(CommunicationBuffer & buffer,
 // 				  const Array<UInt> & dofs,
 // 				  SynchronizationTag tag) {
 //   AKANTU_DEBUG_IN();
 
 //   switch(tag) {
 //   case _gst_solver_solution: {
 //     unpackDOFDataHelper(*solution, buffer, dofs);
 //     break;
 //   }
 //   default: {
 //   }
 //   }
 
 //   AKANTU_DEBUG_OUT();
 // }
diff --git a/src/solver/sparse_solver_mumps.cc b/src/solver/sparse_solver_mumps.cc
index 918d89f09..63ea0148d 100644
--- a/src/solver/sparse_solver_mumps.cc
+++ b/src/solver/sparse_solver_mumps.cc
@@ -1,446 +1,445 @@
 /**
  * @file   sparse_solver_mumps.cc
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Mon Dec 13 2010
- * @date last modification: Tue Jan 19 2016
+ * @date last modification: Tue Feb 20 2018
  *
  * @brief  implem of SparseSolverMumps class
  *
  * @section LICENSE
  *
- * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
- * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
- * Solides)
+ * 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
+ * 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
+ * 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/>.
  *
  * @section DESCRIPTION
  *
  * @subsection Ctrl_param Control parameters
  *
  * ICNTL(1),
  * ICNTL(2),
  * ICNTL(3) : output streams for error, diagnostics, and global messages
  *
  * ICNTL(4) : verbose level : 0 no message - 4 all messages
  *
  * ICNTL(5) : type of matrix, 0 assembled, 1 elementary
  *
  * ICNTL(6) : control  the permutation and scaling(default 7)  see mumps doc for
  * more information
  *
  * ICNTL(7) : determine  the pivot  order (default  7) see  mumps doc  for more
  * information
  *
  * ICNTL(8) : describe the scaling method used
  *
  * ICNTL(9) : 1 solve A x = b, 0 solve At x = b
  *
  * ICNTL(10) : number of iterative refinement when NRHS = 1
  *
  * ICNTL(11) : > 0 return statistics
  *
  * ICNTL(12) : only used for SYM = 2, ordering strategy
  *
  * ICNTL(13) :
  *
  * ICNTL(14) : percentage of increase of the estimated working space
  *
  * ICNTL(15-17) : not used
  *
  * ICNTL(18) : only  used if ICNTL(5) = 0, 0 matrix  centralized, 1 structure on
  * host and mumps  give the mapping, 2 structure on  host and distributed matrix
  * for facto, 3 distributed matrix
  *
  * ICNTL(19) : > 0, Shur complement returned
  *
  * ICNTL(20) : 0 rhs dense, 1 rhs sparse
  *
  * ICNTL(21) : 0 solution in rhs, 1 solution distributed in ISOL_loc and SOL_loc
  * allocated by user
  *
  * ICNTL(22) : 0 in-core, 1 out-of-core
  *
  * ICNTL(23) : maximum memory allocatable by mumps pre proc
  *
  * ICNTL(24) : controls the detection of "null pivot rows"
  *
  * ICNTL(25) :
  *
  * ICNTL(26) :
  *
  * ICNTL(27) :
  *
  * ICNTL(28) : 0 automatic choice, 1 sequential analysis, 2 parallel analysis
  *
  * ICNTL(29) : 0 automatic choice, 1 PT-Scotch, 2 ParMetis
  */
 
 /* -------------------------------------------------------------------------- */
 #include "aka_common.hh"
 #include "dof_manager_default.hh"
 #include "dof_synchronizer.hh"
 #include "sparse_matrix_aij.hh"
 
 #if defined(AKANTU_USE_MPI)
 #include "mpi_communicator_data.hh"
 #endif
 
 #include "sparse_solver_mumps.hh"
 
 /* -------------------------------------------------------------------------- */
 // static std::ostream & operator <<(std::ostream & stream, const DMUMPS_STRUC_C
 // & _this) {
 //   stream << "DMUMPS Data [" << std::endl;
 //   stream << " + job          : " << _this.job          << std::endl;
 //   stream << " + par          : " << _this.par          << std::endl;
 //   stream << " + sym          : " << _this.sym          << std::endl;
 //   stream << " + comm_fortran : " << _this.comm_fortran << std::endl;
 //   stream << " + nz           : " << _this.nz           << std::endl;
 //   stream << " + irn          : " << _this.irn          << std::endl;
 //   stream << " + jcn          : " << _this.jcn          << std::endl;
 //   stream << " + nz_loc       : " << _this.nz_loc       << std::endl;
 //   stream << " + irn_loc      : " << _this.irn_loc      << std::endl;
 //   stream << " + jcn_loc      : " << _this.jcn_loc      << std::endl;
 //   stream << "]";
 //   return stream;
 // }
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 SparseSolverMumps::SparseSolverMumps(DOFManagerDefault & dof_manager,
                                      const ID & matrix_id, const ID & id,
                                      const MemoryID & memory_id)
     : SparseSolver(dof_manager, matrix_id, id, memory_id),
       dof_manager(dof_manager), master_rhs_solution(0, 1) {
   AKANTU_DEBUG_IN();
 
   this->prank = communicator.whoAmI();
 
 #ifdef AKANTU_USE_MPI
   this->parallel_method = _fully_distributed;
 #else  // AKANTU_USE_MPI
   this->parallel_method = _not_parallel;
 #endif // AKANTU_USE_MPI
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 SparseSolverMumps::~SparseSolverMumps() {
   AKANTU_DEBUG_IN();
 
   mumpsDataDestroy();
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void SparseSolverMumps::mumpsDataDestroy() {
   if (this->is_initialized) {
     this->mumps_data.job = _smj_destroy; // destroy
     dmumps_c(&this->mumps_data);
     this->is_initialized = false;
   }
 }
 
 /* -------------------------------------------------------------------------- */
 void SparseSolverMumps::destroyInternalData() { mumpsDataDestroy(); }
 
 /* -------------------------------------------------------------------------- */
 void SparseSolverMumps::checkInitialized() {
   if (this->is_initialized)
     return;
 
   this->initialize();
 }
 
 /* -------------------------------------------------------------------------- */
 void SparseSolverMumps::setOutputLevel() {
   // Output setup
   icntl(1) = 0; // error output
   icntl(2) = 0; // diagnostics output
   icntl(3) = 0; // information
   icntl(4) = 0;
 
 #if !defined(AKANTU_NDEBUG)
   DebugLevel dbg_lvl = debug::debugger.getDebugLevel();
 
   if (AKANTU_DEBUG_TEST(dblDump)) {
     strcpy(this->mumps_data.write_problem, "mumps_matrix.mtx");
   }
 
   // clang-format off
   icntl(1) = (dbg_lvl >= dblWarning) ? 6 : 0;
   icntl(3) = (dbg_lvl >= dblInfo)    ? 6 : 0;
   icntl(2) = (dbg_lvl >= dblTrace)   ? 6 : 0;
 
   icntl(4) =
     dbg_lvl >= dblDump    ? 4 :
     dbg_lvl >= dblTrace   ? 3 :
     dbg_lvl >= dblInfo    ? 2 :
     dbg_lvl >= dblWarning ? 1 :
                             0;
 
 // clang-format on
 #endif
 }
 
 /* -------------------------------------------------------------------------- */
 void SparseSolverMumps::initMumpsData() {
   auto & A = dof_manager.getMatrix(matrix_id);
 
   // Default Scaling
   icntl(8) = 77;
 
   // Assembled matrix
   icntl(5) = 0;
 
   /// Default centralized dense second member
   icntl(20) = 0;
   icntl(21) = 0;
 
   // automatic choice for analysis
   icntl(28) = 0;
 
   UInt size = A.size();
 
   if (prank == 0) {
     this->master_rhs_solution.resize(size);
   }
 
   this->mumps_data.nz_alloc = 0;
   this->mumps_data.n = size;
 
   switch (this->parallel_method) {
   case _fully_distributed:
     icntl(18) = 3; // fully distributed
 
     this->mumps_data.nz_loc = A.getNbNonZero();
     this->mumps_data.irn_loc = A.getIRN().storage();
     this->mumps_data.jcn_loc = A.getJCN().storage();
 
     break;
   case _not_parallel:
   case _master_slave_distributed:
     icntl(18) = 0; // centralized
 
     if (prank == 0) {
       this->mumps_data.nz = A.getNbNonZero();
       this->mumps_data.irn = A.getIRN().storage();
       this->mumps_data.jcn = A.getJCN().storage();
     } else {
       this->mumps_data.nz = 0;
       this->mumps_data.irn = nullptr;
       this->mumps_data.jcn = nullptr;
     }
     break;
   default:
     AKANTU_ERROR("This case should not happen!!");
   }
 }
 
 /* -------------------------------------------------------------------------- */
 void SparseSolverMumps::initialize() {
   AKANTU_DEBUG_IN();
 
   this->mumps_data.par = 1; // The host is part of computations
 
   switch (this->parallel_method) {
   case _not_parallel:
     break;
   case _master_slave_distributed:
     this->mumps_data.par = 0; // The host is not part of the computations
   /* FALLTHRU */
   /* [[fallthrough]]; un-comment when compiler will get it */
   case _fully_distributed:
 #ifdef AKANTU_USE_MPI
     const auto & mpi_data = dynamic_cast<const MPICommunicatorData &>(
         communicator.getCommunicatorData());
     MPI_Comm mpi_comm = mpi_data.getMPICommunicator();
     this->mumps_data.comm_fortran = MPI_Comm_c2f(mpi_comm);
 #else
     AKANTU_ERROR(
         "You cannot use parallel method to solve without activating MPI");
 #endif
     break;
   }
 
   const auto & A = dof_manager.getMatrix(matrix_id);
 
   this->mumps_data.sym = 2 * (A.getMatrixType() == _symmetric);
   this->prank = communicator.whoAmI();
 
   this->setOutputLevel();
 
   this->mumps_data.job = _smj_initialize; // initialize
   dmumps_c(&this->mumps_data);
 
   this->setOutputLevel();
 
   this->is_initialized = true;
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void SparseSolverMumps::analysis() {
   AKANTU_DEBUG_IN();
 
   initMumpsData();
 
   this->mumps_data.job = _smj_analyze; // analyze
   dmumps_c(&this->mumps_data);
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void SparseSolverMumps::factorize() {
   AKANTU_DEBUG_IN();
 
   auto & A = dof_manager.getMatrix(matrix_id);
 
   if (parallel_method == _fully_distributed)
     this->mumps_data.a_loc = A.getA().storage();
   else {
     if (prank == 0)
       this->mumps_data.a = A.getA().storage();
   }
 
   this->mumps_data.job = _smj_factorize; // factorize
   dmumps_c(&this->mumps_data);
 
   this->printError();
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void SparseSolverMumps::solve(Array<Real> & x, const Array<Real> & b) {
   auto & synch = this->dof_manager.getSynchronizer();
 
   if (this->prank == 0) {
     this->master_rhs_solution.resize(this->dof_manager.getSystemSize());
     synch.gather(b, this->master_rhs_solution);
   } else {
     synch.gather(b);
   }
 
   this->solveInternal();
 
   if (this->prank == 0) {
     synch.scatter(x, this->master_rhs_solution);
   } else {
     synch.scatter(x);
   }
 }
 
 /* -------------------------------------------------------------------------- */
 void SparseSolverMumps::solve() {
   this->master_rhs_solution.copy(this->dof_manager.getGlobalResidual());
 
   this->solveInternal();
 
   this->dof_manager.setGlobalSolution(this->master_rhs_solution);
 
   this->dof_manager.splitSolutionPerDOFs();
 }
 
 /* -------------------------------------------------------------------------- */
 void SparseSolverMumps::solveInternal() {
   AKANTU_DEBUG_IN();
 
   this->checkInitialized();
 
   const auto & A = dof_manager.getMatrix(matrix_id);
 
   this->setOutputLevel();
 
   if (this->last_profile_release != A.getProfileRelease()) {
     this->analysis();
     this->last_profile_release = A.getProfileRelease();
   }
 
   if (AKANTU_DEBUG_TEST(dblDump)) {
     std::stringstream sstr;
     sstr << prank << ".mtx";
     A.saveMatrix("solver_mumps" + sstr.str());
   }
 
   if (this->last_value_release != A.getValueRelease()) {
     this->factorize();
     this->last_value_release = A.getValueRelease();
   }
 
   if (prank == 0) {
     this->mumps_data.rhs = this->master_rhs_solution.storage();
   }
 
   this->mumps_data.job = _smj_solve; // solve
   dmumps_c(&this->mumps_data);
 
   this->printError();
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void SparseSolverMumps::printError() {
   Vector<Int> _info_v(2);
   _info_v[0] = info(1);  // to get errors
   _info_v[1] = -info(1); // to get warnings
   dof_manager.getCommunicator().allReduce(_info_v, SynchronizerOperation::_min);
   _info_v[1] = -_info_v[1];
 
   if (_info_v[0] < 0) { // < 0 is an error
     switch (_info_v[0]) {
     case -10:
       AKANTU_CUSTOM_EXCEPTION(
           debug::SingularMatrixException(dof_manager.getMatrix(matrix_id)));
       break;
     case -9: {
       icntl(14) += 10;
       if (icntl(14) != 90) {
         // std::cout << "Dynamic memory increase of 10%" << std::endl;
         AKANTU_DEBUG_WARNING("MUMPS dynamic memory is insufficient it will be "
                              "increased allowed to use 10% more");
 
         // change releases to force a recompute
         this->last_value_release--;
         this->last_profile_release--;
 
         this->solve();
       } else {
         AKANTU_ERROR("The MUMPS workarray is too small INFO(2)="
                      << info(2) << "No further increase possible");
       }
       break;
     }
     default:
       AKANTU_ERROR("Error in mumps during solve process, check mumps "
                    "user guide INFO(1) = "
                    << _info_v[1]);
     }
   } else if (_info_v[1] > 0) {
     AKANTU_DEBUG_WARNING("Warning in mumps during solve process, check mumps "
                          "user guide INFO(1) = "
                          << _info_v[1]);
   }
 }
 
 } // akantu
diff --git a/src/solver/sparse_solver_mumps.hh b/src/solver/sparse_solver_mumps.hh
index 23ec34a6b..af401c7e1 100644
--- a/src/solver/sparse_solver_mumps.hh
+++ b/src/solver/sparse_solver_mumps.hh
@@ -1,158 +1,157 @@
 /**
  * @file   sparse_solver_mumps.hh
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Fri Jun 18 2010
- * @date last modification: Tue Jan 19 2016
+ * @date last modification: Sun Dec 03 2017
  *
  * @brief  Solver class implementation for the mumps solver
  *
  * @section LICENSE
  *
- * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
- * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
- * Solides)
+ * 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
+ * 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
+ * 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 "sparse_solver.hh"
 /* -------------------------------------------------------------------------- */
 #include <dmumps_c.h>
 /* -------------------------------------------------------------------------- */
 
 #ifndef __AKANTU_SOLVER_MUMPS_HH__
 #define __AKANTU_SOLVER_MUMPS_HH__
 
 namespace akantu {
 class DOFManagerDefault;
 class SparseMatrixAIJ;
 }
 
 namespace akantu {
 
 class SparseSolverMumps : public SparseSolver {
   /* ------------------------------------------------------------------------ */
   /* Constructors/Destructors                                                 */
   /* ------------------------------------------------------------------------ */
 public:
   SparseSolverMumps(DOFManagerDefault & dof_manager, const ID & matrix_id,
                     const ID & id = "sparse_solver_mumps",
                     const MemoryID & memory_id = 0);
 
   ~SparseSolverMumps() override;
 
   /* ------------------------------------------------------------------------ */
   /* Methods                                                                  */
   /* ------------------------------------------------------------------------ */
 public:
   /// build the profile and do the analysis part
   void initialize() override;
 
   /// analysis (symbolic facto + permutations)
   void analysis() override;
 
   /// factorize the matrix
   void factorize() override;
 
   /// solve the system
   virtual void solve(Array<Real> & x, const Array<Real> & b);
 
   /// solve using residual and solution from the dof_manager
   void solve() override;
 
 private:
   /// print the error if any happened in mumps
   void printError();
 
   /// solve the system with master_rhs_solution as b and x
   void solveInternal();
 
   /// set internal values;
   void initMumpsData();
 
   /// set the level of verbosity of mumps based on the debug level of akantu
   void setOutputLevel();
 
 protected:
   /// de-initialize the internal data
   void destroyInternalData() override;
 
   /// check if initialized and except if it is not the case
   void checkInitialized();
 
 private:
   void mumpsDataDestroy();
 
   /* ------------------------------------------------------------------------ */
   /* Accessors                                                                */
   /* ------------------------------------------------------------------------ */
 private:
   /// access the control variable
   inline Int & icntl(UInt i) { return mumps_data.icntl[i - 1]; }
 
   /// access the results info
   inline Int & info(UInt i) { return mumps_data.info[i - 1]; }
 
   /* ------------------------------------------------------------------------ */
   /* Class Members                                                            */
   /* ------------------------------------------------------------------------ */
 private:
   /// DOFManager used by the Mumps implementation of the SparseSolver
   DOFManagerDefault & dof_manager;
 
   /// Full right hand side on the master processors and solution after solve
   Array<Real> master_rhs_solution;
 
   /// mumps data
   DMUMPS_STRUC_C mumps_data;
 
   /// Rank of the current process
   UInt prank;
 
   /// matrix release at last solve
   UInt last_profile_release{UInt(-1)};
 
   /// matrix release at last solve
   UInt last_value_release{UInt(-1)};
 
   /// check if the solver data are initialized
   bool is_initialized{false};
 
   /* ------------------------------------------------------------------------ */
   /* Local types                                                              */
   /* ------------------------------------------------------------------------ */
 private:
   SolverParallelMethod parallel_method;
 
   // bool rhs_is_local;
 
   enum SolverMumpsJob {
     _smj_initialize = -1,
     _smj_analyze = 1,
     _smj_factorize = 2,
     _smj_solve = 3,
     _smj_analyze_factorize = 4,
     _smj_factorize_solve = 5,
     _smj_complete = 6, // analyze, factorize, solve
     _smj_destroy = -2
   };
 };
 
 } // akantu
 
 #endif /* __AKANTU_SOLVER_MUMPS_HH__ */
diff --git a/src/solver/terms_to_assemble.hh b/src/solver/terms_to_assemble.hh
index 375d30fe4..4b4d834ff 100644
--- a/src/solver/terms_to_assemble.hh
+++ b/src/solver/terms_to_assemble.hh
@@ -1,99 +1,100 @@
 /**
  * @file   terms_to_assemble.hh
  *
- * @author Nicolas Richart
+ * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
- * @date creation  Tue Dec 20 2016
+ * @date creation: Fri Jun 18 2010
+ * @date last modification: Wed Nov 08 2017
  *
- * @brief List of terms to assemble to a matrix
+ * @brief  List of terms to assemble to a matrix
  *
  * @section LICENSE
  *
- * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * 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
+ * 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
+ * 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 <vector>
 /* -------------------------------------------------------------------------- */
 
 #ifndef __AKANTU_TERMS_TO_ASSEMBLE_HH__
 #define __AKANTU_TERMS_TO_ASSEMBLE_HH__
 
 namespace akantu {
 
 class TermsToAssemble {
   /* ------------------------------------------------------------------------ */
   /* Constructors/Destructors                                                 */
   /* ------------------------------------------------------------------------ */
 public:
   TermsToAssemble() = default;
   virtual ~TermsToAssemble() = default;
 
   class TermToAssemble {
   public:
     TermToAssemble(UInt i, UInt j) : _i(i), _j(j), val(0.) {}
     inline TermToAssemble & operator=(Real val) {
       this->val = val;
       return *this;
     }
     inline TermToAssemble operator+=(Real val) {
       this->val += val;
       return *this;
     }
     inline operator Real() const { return val; }
     inline UInt i() const { return _i; }
     inline UInt j() const { return _j; }
 
   private:
     UInt _i, _j;
     Real val;
   };
 
   /* ------------------------------------------------------------------------ */
   /* Methods                                                                  */
   /* ------------------------------------------------------------------------ */
 public:
   inline TermToAssemble & operator()(UInt i, UInt j) {
     terms.emplace_back(i, j);
     return terms.back();
   }
 
   /* ------------------------------------------------------------------------ */
   /* Accessors                                                                */
   /* ------------------------------------------------------------------------ */
 private:
   using TermsContainer = std::vector<TermToAssemble>;
 
 public:
   using const_terms_iterator = TermsContainer::const_iterator;
 
   const_terms_iterator begin() const { return terms.begin(); }
   const_terms_iterator end() const { return terms.end(); }
 
   /* ------------------------------------------------------------------------ */
   /* Class Members                                                            */
   /* ------------------------------------------------------------------------ */
 private:
   TermsContainer terms;
 };
 
 } // akantu
 
 #endif /* __AKANTU_TERMS_TO_ASSEMBLE_HH__ */
diff --git a/src/synchronizer/communication_buffer.hh b/src/synchronizer/communication_buffer.hh
index 5cd056d1e..5e0b0da8d 100644
--- a/src/synchronizer/communication_buffer.hh
+++ b/src/synchronizer/communication_buffer.hh
@@ -1,183 +1,182 @@
 /**
  * @file   communication_buffer.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 Oct 19 2014
+ * @date last modification: Wed Nov 08 2017
  *
  * @brief  Buffer for packing and unpacking data
  *
  * @section LICENSE
  *
- * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
- * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
- * Solides)
+ * 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
+ * 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
+ * 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_array.hh"
 #include "aka_common.hh"
 #include "element.hh"
 
 #ifndef __AKANTU_COMMUNICATION_BUFFER_HH__
 #define __AKANTU_COMMUNICATION_BUFFER_HH__
 
 namespace akantu {
 
 template <bool is_static = true> class CommunicationBufferTemplated {
   /* ------------------------------------------------------------------------ */
   /* Constructors/Destructors                                                 */
   /* ------------------------------------------------------------------------ */
 public:
   explicit CommunicationBufferTemplated(UInt size) : buffer(size, 1) {
     ptr_pack = buffer.storage();
     ptr_unpack = buffer.storage();
   };
 
   CommunicationBufferTemplated() : CommunicationBufferTemplated(0) {}
 
   CommunicationBufferTemplated(const CommunicationBufferTemplated & other) {
     buffer = other.buffer;
     ptr_pack = buffer.storage();
     ptr_unpack = buffer.storage();
   }
 
   CommunicationBufferTemplated &
   operator=(const CommunicationBufferTemplated & other) {
     if (this != &other) {
       buffer = other.buffer;
       ptr_pack = buffer.storage();
       ptr_unpack = buffer.storage();
     }
     return *this;
   }
 
   virtual ~CommunicationBufferTemplated() = default;
 
   /* ------------------------------------------------------------------------ */
   /* Methods                                                                  */
   /* ------------------------------------------------------------------------ */
 public:
   /// reset to "empty"
   inline void reset();
 
   /// resize the internal buffer
   inline void resize(UInt size);
 
   /// clear buffer context
   inline void clear();
 
 private:
   inline void packResize(UInt size);
 
   /* ------------------------------------------------------------------------ */
   /* Accessors                                                                */
   /* ------------------------------------------------------------------------ */
 public:
   inline char * storage() { return buffer.storage(); };
   inline const char * storage() const { return buffer.storage(); };
   /* ------------------------------------------------------------------------ */
   /* Operators                                                                */
   /* ------------------------------------------------------------------------ */
 public:
   /// printing tool
   template <typename T> inline std::string extractStream(UInt packet_size);
 
   /// packing data
   template <typename T>
   inline CommunicationBufferTemplated & operator<<(const T & to_pack);
 
   template <typename T>
   inline CommunicationBufferTemplated & operator<<(const Vector<T> & to_pack);
 
   template <typename T>
   inline CommunicationBufferTemplated & operator<<(const Matrix<T> & to_pack);
 
   template <typename T>
   inline CommunicationBufferTemplated &
   operator<<(const std::vector<T> & to_pack);
 
   /// unpacking data
   template <typename T>
   inline CommunicationBufferTemplated & operator>>(T & to_unpack);
 
   template <typename T>
   inline CommunicationBufferTemplated & operator>>(Vector<T> & to_unpack);
 
   template <typename T>
   inline CommunicationBufferTemplated & operator>>(Matrix<T> & to_unpack);
 
   template <typename T>
   inline CommunicationBufferTemplated & operator>>(std::vector<T> & to_unpack);
 
   inline CommunicationBufferTemplated & operator<<(const std::string & to_pack);
   inline CommunicationBufferTemplated & operator>>(std::string & to_unpack);
 
 private:
   template <typename T> inline void packIterable(T & to_pack);
   template <typename T> inline void unpackIterable(T & to_pack);
 
   /* ------------------------------------------------------------------------ */
   /* Accessor                                                                 */
   /* ------------------------------------------------------------------------ */
 public:
   template <typename T> static inline UInt sizeInBuffer(const T & data);
   template <typename T> static inline UInt sizeInBuffer(const Vector<T> & data);
   template <typename T> static inline UInt sizeInBuffer(const Matrix<T> & data);
   template <typename T>
   static inline UInt sizeInBuffer(const std::vector<T> & data);
   static inline UInt sizeInBuffer(const std::string & data);
 
   /// return the size in bytes of the stored values
   inline UInt getPackedSize() const { return ptr_pack - buffer.storage(); };
   /// return the size in bytes of data left to be unpacked
   inline UInt getLeftToUnpack() const {
     return buffer.size() - (ptr_unpack - buffer.storage());
   };
   /// return the global size allocated
   inline UInt size() const { return buffer.size(); };
 
   /* ------------------------------------------------------------------------ */
   /* Class Members                                                            */
   /* ------------------------------------------------------------------------ */
 private:
   /// current position for packing
   char * ptr_pack;
 
   /// current position for unpacking
   char * ptr_unpack;
 
   /// storing buffer
   Array<char> buffer;
 };
 
 /* -------------------------------------------------------------------------- */
 /* inline functions                                                           */
 /* -------------------------------------------------------------------------- */
 
 #if defined(AKANTU_INCLUDE_INLINE_IMPL)
 #include "communication_buffer_inline_impl.cc"
 #endif
 
 using CommunicationBuffer = CommunicationBufferTemplated<true>;
 using DynamicCommunicationBuffer = CommunicationBufferTemplated<false>;
 
 } // namespace akantu
 
 #endif /* __AKANTU_COMMUNICATION_BUFFER_HH__ */
diff --git a/src/synchronizer/communication_buffer_inline_impl.cc b/src/synchronizer/communication_buffer_inline_impl.cc
index 9e75736e8..d242a4b42 100644
--- a/src/synchronizer/communication_buffer_inline_impl.cc
+++ b/src/synchronizer/communication_buffer_inline_impl.cc
@@ -1,319 +1,318 @@
 /**
  * @file   communication_buffer_inline_impl.cc
  *
  * @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Thu Apr 14 2011
- * @date last modification: Sun Oct 19 2014
+ * @date last modification: Wed Nov 08 2017
  *
  * @brief  CommunicationBuffer inline implementation
  *
  * @section LICENSE
  *
- * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
- * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
- * Solides)
+ * 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
+ * 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
+ * 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/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 template <bool is_static>
 template <typename T>
 inline UInt CommunicationBufferTemplated<is_static>::sizeInBuffer(const T &) {
   return sizeof(T);
 }
 
 template <bool is_static>
 template <typename T>
 inline UInt
 CommunicationBufferTemplated<is_static>::sizeInBuffer(const Vector<T> & data) {
   UInt size = data.size() * sizeof(T);
   return size;
 }
 
 template <bool is_static>
 template <typename T>
 inline UInt
 CommunicationBufferTemplated<is_static>::sizeInBuffer(const Matrix<T> & data) {
   UInt size = data.size() * sizeof(T);
   return size;
 }
 
 template <bool is_static>
 template <typename T>
 inline UInt CommunicationBufferTemplated<is_static>::sizeInBuffer(
     const std::vector<T> & data) {
   UInt size = data.size() * sizeof(T) + sizeof(size_t);
   return size;
 }
 
 template <bool is_static>
 inline UInt CommunicationBufferTemplated<is_static>::sizeInBuffer(
     const std::string & data) {
   UInt size = data.size() * sizeof(std::string::value_type) + sizeof(size_t);
   return size;
 }
 
 /* -------------------------------------------------------------------------- */
 template <bool is_static>
 inline void CommunicationBufferTemplated<is_static>::packResize(UInt size) {
   if (!is_static) {
     char * values = buffer.storage();
     buffer.resize(buffer.size() + size);
     ptr_pack = buffer.storage() + (ptr_pack - values);
     ptr_unpack = buffer.storage() + (ptr_unpack - values);
   }
 }
 
 /* -------------------------------------------------------------------------- */
 template <bool is_static>
 template <typename T>
 inline CommunicationBufferTemplated<is_static> &
 CommunicationBufferTemplated<is_static>::operator<<(const T & to_pack) {
   UInt size = sizeInBuffer(to_pack);
   packResize(size);
   AKANTU_DEBUG_ASSERT(
       (buffer.storage() + buffer.size()) >= (ptr_pack + size),
       "Packing too much data in the CommunicationBufferTemplated");
   memcpy(ptr_pack, reinterpret_cast<const char *>(&to_pack), size);
   ptr_pack += size;
   return *this;
 }
 
 /* -------------------------------------------------------------------------- */
 template <bool is_static>
 template <typename T>
 inline CommunicationBufferTemplated<is_static> &
 CommunicationBufferTemplated<is_static>::operator>>(T & to_unpack) {
   UInt size = sizeInBuffer(to_unpack);
 
   alignas(alignof(T)) std::array<char, sizeof(T)> aligned_ptr;
   memcpy(aligned_ptr.data(), ptr_unpack, size);
 
   auto * tmp = reinterpret_cast<T *>(aligned_ptr.data());
   AKANTU_DEBUG_ASSERT(
       (buffer.storage() + buffer.size()) >= (ptr_unpack + size),
       "Unpacking too much data in the CommunicationBufferTemplated");
   to_unpack = *tmp;
   // memcpy(reinterpret_cast<char *>(&to_unpack), ptr_unpack, size);
   ptr_unpack += size;
   return *this;
 }
 
 /* -------------------------------------------------------------------------- */
 /* Specialization                                                             */
 /* -------------------------------------------------------------------------- */
 
 /**
  * Vector
  */
 
 /* -------------------------------------------------------------------------- */
 template <bool is_static>
 template <typename T>
 inline CommunicationBufferTemplated<is_static> &
 CommunicationBufferTemplated<is_static>::operator<<(const Vector<T> & to_pack) {
   UInt size = sizeInBuffer(to_pack);
   packResize(size);
   AKANTU_DEBUG_ASSERT(
       (buffer.storage() + buffer.size()) >= (ptr_pack + size),
       "Packing too much data in the CommunicationBufferTemplated");
   memcpy(ptr_pack, to_pack.storage(), size);
   ptr_pack += size;
   return *this;
 }
 
 /* -------------------------------------------------------------------------- */
 template <bool is_static>
 template <typename T>
 inline CommunicationBufferTemplated<is_static> &
 CommunicationBufferTemplated<is_static>::operator>>(Vector<T> & to_unpack) {
   UInt size = sizeInBuffer(to_unpack);
   AKANTU_DEBUG_ASSERT(
       (buffer.storage() + buffer.size()) >= (ptr_unpack + size),
       "Unpacking too much data in the CommunicationBufferTemplated");
   memcpy(to_unpack.storage(), ptr_unpack, size);
   ptr_unpack += size;
   return *this;
 }
 
 /**
  * Matrix
  */
 
 /* -------------------------------------------------------------------------- */
 template <bool is_static>
 template <typename T>
 inline CommunicationBufferTemplated<is_static> &
 CommunicationBufferTemplated<is_static>::operator<<(const Matrix<T> & to_pack) {
   UInt size = sizeInBuffer(to_pack);
   packResize(size);
   AKANTU_DEBUG_ASSERT(
       (buffer.storage() + buffer.size()) >= (ptr_pack + size),
       "Packing too much data in the CommunicationBufferTemplated");
   memcpy(ptr_pack, to_pack.storage(), size);
   ptr_pack += size;
   return *this;
 }
 
 /* -------------------------------------------------------------------------- */
 template <bool is_static>
 template <typename T>
 inline CommunicationBufferTemplated<is_static> &
 CommunicationBufferTemplated<is_static>::operator>>(Matrix<T> & to_unpack) {
   UInt size = sizeInBuffer(to_unpack);
   AKANTU_DEBUG_ASSERT(
       (buffer.storage() + buffer.size()) >= (ptr_unpack + size),
       "Unpacking too much data in the CommunicationBufferTemplated");
   memcpy(to_unpack.storage(), ptr_unpack, size);
   ptr_unpack += size;
   return *this;
 }
 
 /* -------------------------------------------------------------------------- */
 template <bool is_static>
 template <typename T>
 inline void CommunicationBufferTemplated<is_static>::packIterable(T & to_pack) {
   operator<<(size_t(to_pack.size()));
   auto it = to_pack.begin();
   auto end = to_pack.end();
   for (; it != end; ++it)
     operator<<(*it);
 }
 
 /* -------------------------------------------------------------------------- */
 template <bool is_static>
 template <typename T>
 inline void
 CommunicationBufferTemplated<is_static>::unpackIterable(T & to_unpack) {
   size_t size;
   operator>>(size);
   to_unpack.resize(size);
   auto it = to_unpack.begin();
   auto end = to_unpack.end();
   for (; it != end; ++it)
     operator>>(*it);
 }
 
 /**
  * std::vector<T>
  */
 /* -------------------------------------------------------------------------- */
 
 template <bool is_static>
 template <typename T>
 inline CommunicationBufferTemplated<is_static> &
 CommunicationBufferTemplated<is_static>::
 operator<<(const std::vector<T> & to_pack) {
   packIterable(to_pack);
   return *this;
 }
 
 /* -------------------------------------------------------------------------- */
 template <bool is_static>
 template <typename T>
 inline CommunicationBufferTemplated<is_static> &
 CommunicationBufferTemplated<is_static>::
 operator>>(std::vector<T> & to_unpack) {
   unpackIterable(to_unpack);
   return *this;
 }
 
 /**
  * std::string
  */
 /* -------------------------------------------------------------------------- */
 
 template <bool is_static>
 inline CommunicationBufferTemplated<is_static> &
 CommunicationBufferTemplated<is_static>::
 operator<<(const std::string & to_pack) {
   packIterable(to_pack);
   return *this;
 }
 
 /* -------------------------------------------------------------------------- */
 template <bool is_static>
 inline CommunicationBufferTemplated<is_static> &
 CommunicationBufferTemplated<is_static>::operator>>(std::string & to_unpack) {
   unpackIterable(to_unpack);
   return *this;
 }
 
 /* -------------------------------------------------------------------------- */
 template <bool is_static>
 template <typename T>
 inline std::string
 CommunicationBufferTemplated<is_static>::extractStream(UInt block_size) {
   std::stringstream str;
   auto * ptr = reinterpret_cast<T *>(buffer.storage());
   UInt sz = buffer.size() / sizeof(T);
   UInt sz_block = block_size / sizeof(T);
 
   UInt n_block = 0;
   for (UInt i = 0; i < sz; ++i) {
     if (i % sz_block == 0) {
       str << std::endl << n_block << " ";
       ++n_block;
     }
     str << *ptr << " ";
     ++ptr;
   }
   return str.str();
 }
 
 /* -------------------------------------------------------------------------- */
 template <bool is_static>
 inline void CommunicationBufferTemplated<is_static>::resize(UInt size) {
   if (!is_static) {
     buffer.resize(0);
   } else {
     buffer.resize(size);
   }
   reset();
 #ifndef AKANTU_NDEBUG
   clear();
 #endif
 }
 
 /* -------------------------------------------------------------------------- */
 template <bool is_static>
 inline void CommunicationBufferTemplated<is_static>::clear() {
   buffer.clear();
 }
 
 /* -------------------------------------------------------------------------- */
 template <bool is_static>
 inline void CommunicationBufferTemplated<is_static>::reset() {
   ptr_pack = buffer.storage();
   ptr_unpack = buffer.storage();
 }
 
 /* -------------------------------------------------------------------------- */
 // template<bool is_static>
 // inline CommunicationBufferTemplated<is_static> &
 // CommunicationBufferTemplated<is_static>::packMeshData (const MeshData &
 // to_pack, const ElementType & type) {
 
 // UInt size = to_pack.size();
 // operator<<(size);
 // typename std::vector<T>::iterator it  = to_pack.begin();
 // typename std::vector<T>::iterator end = to_pack.end();
 // for(;it != end; ++it) operator<<(*it);
 // return *this;
 
 //}
diff --git a/src/synchronizer/communication_descriptor.hh b/src/synchronizer/communication_descriptor.hh
index 373abd5b1..246422f47 100644
--- a/src/synchronizer/communication_descriptor.hh
+++ b/src/synchronizer/communication_descriptor.hh
@@ -1,153 +1,154 @@
 /**
- * @file   synchronizer_tmpl.hh
+ * @file   communication_descriptor.hh
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
- * @date   Wed Aug  3 13:49:36 2016
+ * @date creation: Wed Sep 07 2016
+ * @date last modification: Thu Jan 25 2018
  *
  * @brief  Implementation of the helper classes for the synchronizer
  *
  * @section LICENSE
  *
- * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * 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
+ * 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
+ * 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_array.hh"
 #include "communication_request.hh"
 #include "communication_tag.hh"
 #include "data_accessor.hh"
 /* -------------------------------------------------------------------------- */
 
 #ifndef __AKANTU_COMMUNICATION_DESCRIPTOR_HH__
 #define __AKANTU_COMMUNICATION_DESCRIPTOR_HH__
 
 namespace akantu {
 
 /* ------------------------------------------------------------------------ */
 enum CommunicationSendRecv { _send, _recv, _csr_not_defined };
 
 /* -------------------------------------------------------------------------- */
 struct CommunicationSRType {
   using type = CommunicationSendRecv;
   static const type _begin_ = _send;
   static const type _end_ = _csr_not_defined;
 };
 
 using send_recv_t = safe_enum<CommunicationSRType>;
 
 namespace {
   send_recv_t iterate_send_recv{};
 }
 
 /* ------------------------------------------------------------------------ */
 class Communication {
 public:
   explicit Communication(const CommunicationSendRecv & type = _csr_not_defined)
       : _type(type) {}
 
   Communication(const Communication &) = delete;
   Communication & operator=(const Communication &) = delete;
 
   void resize(UInt size) {
     this->_size = size;
     this->_buffer.resize(size);
   }
 
   inline const CommunicationSendRecv & type() const { return this->_type; }
   inline const UInt & size() const { return this->_size; }
 
   inline const CommunicationRequest & request() const { return this->_request; }
   inline CommunicationRequest & request() { return this->_request; }
 
   inline const CommunicationBuffer & buffer() const { return this->_buffer; }
   inline CommunicationBuffer & buffer() { return this->_buffer; }
 
 private:
   UInt _size{0};
   CommunicationBuffer _buffer;
   CommunicationRequest _request;
   CommunicationSendRecv _type;
 };
 
 template <class Entity> class Communications;
 
 /* ------------------------------------------------------------------------ */
 template <class Entity> class CommunicationDescriptor {
 public:
   CommunicationDescriptor(Communication & communication, Array<Entity> & scheme,
                           Communications<Entity> & communications,
                           const SynchronizationTag & tag, UInt proc);
 
   CommunicationDescriptor(const CommunicationDescriptor &) = default;
 
   CommunicationDescriptor &
   operator=(const CommunicationDescriptor &) = default;
 
   /// get the quantity of data in the buffer
   UInt getNbData() { return communication.size(); }
   /// set the quantity of data in the buffer
   void setNbData(UInt size) { communication.resize(size); }
 
   /// get the corresponding tag
   const SynchronizationTag & getTag() const { return tag; }
   /// get the data buffer
   CommunicationBuffer & getBuffer();
 
   /// get the corresponding request
   CommunicationRequest & getRequest();
 
   /// get the communication scheme
   const Array<Entity> & getScheme();
 
   /// reset the buffer before pack or after unpack
   void resetBuffer();
 
   /// pack data for entities in the buffer
   void packData(const DataAccessor<Entity> & accessor);
 
   /// unpack data for entities from the buffer
   void unpackData(DataAccessor<Entity> & accessor);
 
   /// posts asynchronous send requests
   void postSend(int hash_id);
 
   /// posts asynchronous receive requests
   void postRecv(int hash_id);
 
   /// free the request
   void freeRequest();
 
   UInt getProc() { return proc; }
 
 protected:
   Communication & communication;
   const Array<Entity> & scheme;
   Communications<Entity> & communications;
   const SynchronizationTag & tag;
   UInt proc;
   UInt rank;
   UInt counter;
 };
 
 /* -------------------------------------------------------------------------- */
 } // namespace akantu
 
 #include "communication_descriptor_tmpl.hh"
 
 #endif /* __AKANTU_COMMUNICATION_DESCRIPTOR_HH__ */
diff --git a/src/synchronizer/communication_descriptor_tmpl.hh b/src/synchronizer/communication_descriptor_tmpl.hh
index 8b61411ec..92044ef1a 100644
--- a/src/synchronizer/communication_descriptor_tmpl.hh
+++ b/src/synchronizer/communication_descriptor_tmpl.hh
@@ -1,151 +1,152 @@
 /**
  * @file   communication_descriptor_tmpl.hh
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
- * @date   Tue Sep  6 14:03:16 2016
+ * @date creation: Wed Sep 07 2016
+ * @date last modification: Thu Jan 25 2018
  *
  * @brief  implementation of CommunicationDescriptor
  *
  * @section LICENSE
  *
- * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * 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
+ * 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
+ * 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 "communication_descriptor.hh"
 /* -------------------------------------------------------------------------- */
 
 #ifndef __AKANTU_COMMUNICATION_DESCRIPTOR_TMPL_HH__
 #define __AKANTU_COMMUNICATION_DESCRIPTOR_TMPL_HH__
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 /* Implementations                                                            */
 /* -------------------------------------------------------------------------- */
 template <class Entity>
 CommunicationDescriptor<Entity>::CommunicationDescriptor(
     Communication & communication, Array<Entity> & scheme,
     Communications<Entity> & communications, const SynchronizationTag & tag,
     UInt proc)
     : communication(communication), scheme(scheme),
       communications(communications), tag(tag), proc(proc),
       rank(communications.getCommunicator().whoAmI()) {
   counter = communications.getCounter(tag);
 }
 
 /* -------------------------------------------------------------------------- */
 template <class Entity>
 CommunicationBuffer & CommunicationDescriptor<Entity>::getBuffer() {
   return communication.buffer();
 }
 
 /* -------------------------------------------------------------------------- */
 template <class Entity>
 CommunicationRequest & CommunicationDescriptor<Entity>::getRequest() {
   return communication.request();
 }
 
 /* -------------------------------------------------------------------------- */
 template <class Entity> void CommunicationDescriptor<Entity>::freeRequest() {
   const auto & comm = communications.getCommunicator();
 
   // comm.test(communication.request());
   comm.freeCommunicationRequest(communication.request());
 
   communications.decrementPending(tag, communication.type());
 }
 
 /* -------------------------------------------------------------------------- */
 template <class Entity>
 const Array<Entity> & CommunicationDescriptor<Entity>::getScheme() {
   return scheme;
 }
 
 template <class Entity> void CommunicationDescriptor<Entity>::resetBuffer() {
   this->communication.buffer().reset();
 }
 
 /* -------------------------------------------------------------------------- */
 template <class Entity>
 void CommunicationDescriptor<Entity>::packData(
     const DataAccessor<Entity> & accessor) {
   AKANTU_DEBUG_ASSERT(
       communication.type() == _send,
       "Cannot pack data on communication that is not of type _send");
   accessor.packData(communication.buffer(), scheme, tag);
 }
 
 /* -------------------------------------------------------------------------- */
 template <class Entity>
 void CommunicationDescriptor<Entity>::unpackData(
     DataAccessor<Entity> & accessor) {
   AKANTU_DEBUG_ASSERT(
       communication.type() == _recv,
       "Cannot unpack data from communication that is not of type _recv");
   accessor.unpackData(communication.buffer(), scheme, tag);
 }
 
 /* -------------------------------------------------------------------------- */
 template <class Entity>
 void CommunicationDescriptor<Entity>::postSend(int hash_id) {
   AKANTU_DEBUG_ASSERT(communication.type() == _send,
                       "Cannot send a communication that is not of type _send");
   Tag comm_tag = Tag::genTag(rank, counter, tag, hash_id);
   AKANTU_DEBUG_ASSERT(communication.buffer().getPackedSize() ==
                           communication.size(),
                       "a problem have been introduced with "
                           << "false sent sizes declaration "
                           << communication.buffer().getPackedSize()
                           << " != " << communication.size());
 
   AKANTU_DEBUG_INFO("Posting send to proc " << proc << " (tag: " << tag << " - "
                                             << communication.size()
                                             << " data to send) "
                                             << " [ " << comm_tag << " ]");
 
   CommunicationRequest & request = communication.request();
   request = communications.getCommunicator().asyncSend(communication.buffer(),
                                                        proc, comm_tag);
   communications.incrementPending(tag, communication.type());
 }
 
 /* -------------------------------------------------------------------------- */
 template <class Entity>
 void CommunicationDescriptor<Entity>::postRecv(int hash_id) {
   AKANTU_DEBUG_ASSERT(communication.type() == _recv,
                       "Cannot receive data for communication ("
                           << communication.type()
                           << ")that is not of type _recv");
 
   Tag comm_tag = Tag::genTag(proc, counter, tag, hash_id);
   AKANTU_DEBUG_INFO("Posting receive from proc "
                     << proc << " (tag: " << tag << " - " << communication.size()
                     << " data to receive) "
                     << " [ " << comm_tag << " ]");
 
   CommunicationRequest & request = communication.request();
   request = communications.getCommunicator().asyncReceive(
       communication.buffer(), proc, comm_tag);
   communications.incrementPending(tag, communication.type());
 }
 
 } // akantu
 
 #endif /* __AKANTU_COMMUNICATION_DESCRIPTOR_TMPL_HH__ */
diff --git a/src/synchronizer/communication_request.hh b/src/synchronizer/communication_request.hh
index f93ba330c..73b83e0ec 100644
--- a/src/synchronizer/communication_request.hh
+++ b/src/synchronizer/communication_request.hh
@@ -1,113 +1,112 @@
 /**
- * @file   real_static_communicator.hh
+ * @file   communication_request.hh
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Mon Jun 14 2010
- * @date last modification: Wed Jan 13 2016
+ * @date last modification: Wed Nov 08 2017
  *
  * @brief  empty class just for inheritance
  *
  * @section LICENSE
  *
- * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
- * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
- * Solides)
+ * 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
+ * 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
+ * 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 <memory>
 /* -------------------------------------------------------------------------- */
 
 #ifndef __AKANTU_REAL_STATIC_COMMUNICATOR_HH__
 #define __AKANTU_REAL_STATIC_COMMUNICATOR_HH__
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 class InternalCommunicationRequest {
 public:
   InternalCommunicationRequest(UInt source, UInt dest);
   virtual ~InternalCommunicationRequest();
 
   virtual void printself(std::ostream & stream, int indent = 0) const;
 
   AKANTU_GET_MACRO(Source, source, UInt);
   AKANTU_GET_MACRO(Destination, destination, UInt);
 
 private:
   UInt source;
   UInt destination;
   UInt id;
   static UInt counter;
 };
 
 /* -------------------------------------------------------------------------- */
 class CommunicationRequest {
 public:
   CommunicationRequest(
       std::shared_ptr<InternalCommunicationRequest> request = nullptr)
       : request(std::move(request)) {}
 
   virtual ~CommunicationRequest() = default;
 
   virtual void free() { request.reset(); }
 
   void printself(std::ostream & stream, int indent = 0) const {
     request->printself(stream, indent);
   };
 
   UInt getSource() const { return request->getSource(); }
   UInt getDestination() const { return request->getDestination(); }
 
   bool isFreed() const { return request.get() == nullptr; }
 
   InternalCommunicationRequest & getInternal() { return *request; }
 
 private:
   std::shared_ptr<InternalCommunicationRequest> request;
 };
 
 /* -------------------------------------------------------------------------- */
 class CommunicationStatus {
 public:
   AKANTU_GET_MACRO(Source, source, Int);
   UInt size() const { return size_; }
   AKANTU_GET_MACRO(Tag, tag, Int);
 
   AKANTU_SET_MACRO(Source, source, Int);
   AKANTU_SET_MACRO(Size, size_, UInt);
   AKANTU_SET_MACRO(Tag, tag, Int);
 
 private:
   Int source{0};
   UInt size_{0};
   Int tag{0};
 };
 
 /* -------------------------------------------------------------------------- */
 /// Datatype to pack pairs for MPI_{MIN,MAX}LOC
 template <typename T1, typename T2> struct SCMinMaxLoc {
   T1 min_max;
   T2 loc;
 };
 
 } // akantu
 
 #endif /* __AKANTU_REAL_STATIC_COMMUNICATOR_HH__ */
diff --git a/src/synchronizer/communication_tag.hh b/src/synchronizer/communication_tag.hh
index e6fb54a82..f9c125ea1 100644
--- a/src/synchronizer/communication_tag.hh
+++ b/src/synchronizer/communication_tag.hh
@@ -1,116 +1,118 @@
 /**
  * @file   communication_tag.hh
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
- * @date   Wed Aug 24 12:40:55 2016
+ * @date creation: Wed Sep 07 2016
+ * @date last modification: Wed Nov 08 2017
  *
  * @brief  Description of the communication tags
  *
  * @section LICENSE
  *
- * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * 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
+ * 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
+ * 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_COMMUNICATION_TAG_HH__
 #define __AKANTU_COMMUNICATION_TAG_HH__
 
 namespace akantu {
 /**
  * tag = |__________20_________|___8____|_4_|
  *       |          proc       | num mes| ct|
  */
 class Tag {
 public:
   Tag() = default;
   Tag(int val) : tag(val) {}
   Tag(int val, int hash) : tag(val), hash(hash) {}
 
   operator int() const {
     return int(max_tag == 0 ? tag : (uint32_t(tag) % max_tag));
   }
 
   /// generates a tag
   template <typename CommTag>
   static inline Tag genTag(int proc, UInt msg_count, CommTag tag) {
     int _tag = ((((proc & 0xFFFFF) << 12) + ((msg_count & 0xFF) << 4) +
                  ((int)tag & 0xF)));
     Tag t(_tag);
     return t;
   }
 
   /// generates a tag and hashes it
   template <typename CommTag>
   static inline Tag genTag(int proc, UInt msg_count, CommTag tag, int hash) {
     Tag t = genTag(proc, msg_count, tag);
     t.tag = t.tag ^ hash;
     t.hash = hash;
     return t;
   }
 
   virtual void printself(std::ostream & stream, int) const {
     int t = tag;
     stream << "TAG(";
     if (hash != 0)
       t = t ^ hash;
     stream << (t >> 12) << ":" << (t >> 4 & 0xFF) << ":" << (t & 0xF) << " -> "
            << std::hex << "0x" << int(*this);
     if (hash != 0)
       stream << " {hash: 0x" << hash << "}";
     stream << " [0x" << this->max_tag << "]";
     stream << ")";
   }
 
   enum CommTags : int {
     _SIZES = 1,
     _CONNECTIVITY = 2,
     _DATA = 3,
     _PARTITIONS = 4,
     _NB_NODES = 5,
     _NODES = 6,
     _COORDINATES = 7,
     _NODES_TYPE = 8,
     _MESH_DATA = 9,
     _ELEMENT_GROUP = 10,
     _NODE_GROUP = 11,
     _MODIFY_SCHEME = 12,
     _GATHER_INITIALIZATION = 1,
     _GATHER = 2,
     _SCATTER = 3,
     _SYNCHRONIZE = 15,
   };
 
 private:
   static void setMaxTag(int _max_tag) { max_tag = _max_tag; }
   friend void initialize(const std::string &, int &, char **&);
 
 private:
   int tag{0};
   int hash{0};
   static int max_tag;
 };
 
 /* -------------------------------------------------------------------------- */
 inline std::ostream & operator<<(std::ostream & stream, const Tag & _this) {
   _this.printself(stream, 0);
   return stream;
 }
 
 /* -------------------------------------------------------------------------- */
 }
 
 #endif /* __AKANTU_COMMUNICATION_TAG_HH__ */
diff --git a/src/synchronizer/communications.hh b/src/synchronizer/communications.hh
index 8190e94ed..f3968b4e3 100644
--- a/src/synchronizer/communications.hh
+++ b/src/synchronizer/communications.hh
@@ -1,272 +1,274 @@
 /**
  * @file   communications.hh
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
- * @date   Wed Aug 24 13:56:14 2016
+ * @date creation: Wed Sep 07 2016
+ * @date last modification: Tue Feb 20 2018
  *
- * @brief
+ * @brief  Class handling the pending communications and the communications
+ * schemes
  *
  * @section LICENSE
  *
- * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * 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
+ * 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
+ * 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 "communication_descriptor.hh"
 #include "communicator.hh"
 /* -------------------------------------------------------------------------- */
 #include <map>
 /* -------------------------------------------------------------------------- */
 
 #ifndef __AKANTU_COMMUNICATIONS_HH__
 #define __AKANTU_COMMUNICATIONS_HH__
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 template <class Entity> class Communications {
 public:
   using Scheme = Array<Entity>;
 
 protected:
   using CommunicationPerProcs = std::map<UInt, Communication>;
   using CommunicationsPerTags =
       std::map<SynchronizationTag, CommunicationPerProcs>;
   using CommunicationSchemes = std::map<UInt, Scheme>;
   using Request = std::map<UInt, std::vector<CommunicationRequest>>;
 
   friend class CommunicationDescriptor<Entity>;
 
 public:
   using scheme_iterator = typename CommunicationSchemes::iterator;
   using const_scheme_iterator = typename CommunicationSchemes::const_iterator;
 
   /* ------------------------------------------------------------------------ */
   class iterator;
   class tag_iterator;
   /* ------------------------------------------------------------------------ */
 
 public:
   CommunicationPerProcs & getCommunications(const SynchronizationTag & tag,
                                             const CommunicationSendRecv & sr);
 
   /* ------------------------------------------------------------------------ */
   bool hasPending(const SynchronizationTag & tag,
                   const CommunicationSendRecv & sr) const;
   UInt getPending(const SynchronizationTag & tag,
                   const CommunicationSendRecv & sr) const;
 
   /* ------------------------------------------------------------------------ */
   iterator begin(const SynchronizationTag & tag,
                  const CommunicationSendRecv & sr);
   iterator end(const SynchronizationTag & tag,
                const CommunicationSendRecv & sr);
 
   /* ------------------------------------------------------------------------ */
   iterator waitAny(const SynchronizationTag & tag,
                    const CommunicationSendRecv & sr);
 
   /* ------------------------------------------------------------------------ */
   void waitAll(const SynchronizationTag & tag,
                const CommunicationSendRecv & sr);
   void incrementPending(const SynchronizationTag & tag,
                         const CommunicationSendRecv & sr);
   void decrementPending(const SynchronizationTag & tag,
                         const CommunicationSendRecv & sr);
   void freeRequests(const SynchronizationTag & tag,
                     const CommunicationSendRecv & sr);
 
   /* ------------------------------------------------------------------------ */
   Scheme & createScheme(UInt proc, const CommunicationSendRecv & sr);
   void resetSchemes(const CommunicationSendRecv & sr);
 
   /* ------------------------------------------------------------------------ */
   void setCommunicationSize(const SynchronizationTag & tag, UInt proc,
                             UInt size, const CommunicationSendRecv & sr);
 
 public:
   explicit Communications(const Communicator & communicator);
   explicit Communications(const Communications & communications);
 
   /* ------------------------------------------------------------------------ */
   class IterableCommunicationDesc {
   public:
     IterableCommunicationDesc(Communications & communications,
                               SynchronizationTag tag, CommunicationSendRecv sr)
         : communications(communications), tag(std::move(tag)),
           sr(std::move(sr)) {}
     auto begin() { return communications.begin(tag, sr); }
     auto end() { return communications.end(tag, sr); }
 
   private:
     Communications & communications;
     SynchronizationTag tag;
     CommunicationSendRecv sr;
   };
 
   auto iterateRecv(const SynchronizationTag & tag) {
     return IterableCommunicationDesc(*this, tag, _recv);
   }
   auto iterateSend(const SynchronizationTag & tag) {
     return IterableCommunicationDesc(*this, tag, _send);
   }
 
   /* ------------------------------------------------------------------------ */
   // iterator begin_send(const SynchronizationTag & tag);
   // iterator end_send(const SynchronizationTag & tag);
 
   /* ------------------------------------------------------------------------ */
   // iterator begin_recv(const SynchronizationTag & tag);
   // iterator end_recv(const SynchronizationTag & tag);
 
   /* ------------------------------------------------------------------------ */
   class IterableTags {
   public:
     explicit IterableTags(Communications & communications)
         : communications(communications) {}
     decltype(auto) begin() { return communications.begin_tag(); }
     decltype(auto) end() { return communications.end_tag(); }
 
   private:
     Communications & communications;
   };
 
   decltype(auto) iterateTags() { return IterableTags(*this); }
 
   tag_iterator begin_tag();
   tag_iterator end_tag();
 
   /* ------------------------------------------------------------------------ */
   bool hasCommunication(const SynchronizationTag & tag) const;
   void incrementCounter(const SynchronizationTag & tag);
   UInt getCounter(const SynchronizationTag & tag) const;
   bool hasCommunicationSize(const SynchronizationTag & tag) const;
   void invalidateSizes();
 
   /* ------------------------------------------------------------------------ */
   bool hasPendingRecv(const SynchronizationTag & tag) const;
   bool hasPendingSend(const SynchronizationTag & tag) const;
 
   const auto & getCommunicator() const;
 
   /* ------------------------------------------------------------------------ */
   iterator waitAnyRecv(const SynchronizationTag & tag);
   iterator waitAnySend(const SynchronizationTag & tag);
 
   void waitAllRecv(const SynchronizationTag & tag);
   void waitAllSend(const SynchronizationTag & tag);
 
   void freeSendRequests(const SynchronizationTag & tag);
   void freeRecvRequests(const SynchronizationTag & tag);
 
   /* ------------------------------------------------------------------------ */
   /* ------------------------------------------------------------------------ */
   class IterableSchemes {
   public:
     IterableSchemes(Communications & communications, CommunicationSendRecv sr)
         : communications(communications), sr(std::move(sr)) {}
     decltype(auto) begin() { return communications.begin_scheme(sr); }
     decltype(auto) end() { return communications.end_scheme(sr); }
 
   private:
     Communications & communications;
     CommunicationSendRecv sr;
   };
 
   class ConstIterableSchemes {
   public:
     ConstIterableSchemes(const Communications & communications,
                          CommunicationSendRecv sr)
         : communications(communications), sr(std::move(sr)) {}
     decltype(auto) begin() const { return communications.begin_scheme(sr); }
     decltype(auto) end() const { return communications.end_scheme(sr); }
 
   private:
     const Communications & communications;
     CommunicationSendRecv sr;
   };
 
   decltype(auto) iterateSchemes(const CommunicationSendRecv & sr) {
     return IterableSchemes(*this, sr);
   }
   decltype(auto) iterateSchemes(const CommunicationSendRecv & sr) const {
     return ConstIterableSchemes(*this, sr);
   }
 
   decltype(auto) iterateSendSchemes() { return IterableSchemes(*this, _send); }
   decltype(auto) iterateSendSchemes() const {
     return ConstIterableSchemes(*this, _send);
   }
 
   decltype(auto) iterateRecvSchemes() { return IterableSchemes(*this, _recv); }
   decltype(auto) iterateRecvSchemes() const {
     return ConstIterableSchemes(*this, _recv);
   }
 
   scheme_iterator begin_scheme(const CommunicationSendRecv & sr);
   scheme_iterator end_scheme(const CommunicationSendRecv & sr);
   const_scheme_iterator begin_scheme(const CommunicationSendRecv & sr) const;
   const_scheme_iterator end_scheme(const CommunicationSendRecv & sr) const;
 
   /* ------------------------------------------------------------------------ */
   scheme_iterator begin_send_scheme();
   scheme_iterator end_send_scheme();
   const_scheme_iterator begin_send_scheme() const;
   const_scheme_iterator end_send_scheme() const;
 
   /* ------------------------------------------------------------------------ */
   scheme_iterator begin_recv_scheme();
   scheme_iterator end_recv_scheme();
   const_scheme_iterator begin_recv_scheme() const;
   const_scheme_iterator end_recv_scheme() const;
 
   /* ------------------------------------------------------------------------ */
   Scheme & createSendScheme(UInt proc);
   Scheme & createRecvScheme(UInt proc);
 
   /* ------------------------------------------------------------------------ */
   Scheme & getScheme(UInt proc, const CommunicationSendRecv & sr);
   const Scheme & getScheme(UInt proc, const CommunicationSendRecv & sr) const;
 
   /* ------------------------------------------------------------------------ */
   void resetSchemes();
   /* ------------------------------------------------------------------------ */
   void setSendCommunicationSize(const SynchronizationTag & tag, UInt proc,
                                 UInt size);
   void setRecvCommunicationSize(const SynchronizationTag & tag, UInt proc,
                                 UInt size);
 
   void initializeCommunications(const SynchronizationTag & tag);
 
 protected:
   CommunicationSchemes schemes[2];
   CommunicationsPerTags communications[2];
 
   std::map<SynchronizationTag, UInt> comm_counter;
   std::map<SynchronizationTag, UInt> pending_communications[2];
   std::map<SynchronizationTag, bool> comm_size_computed;
 
   const Communicator & communicator;
 };
 
 } // namespace akantu
 
 #include "communications_tmpl.hh"
 
 #endif /* __AKANTU_COMMUNICATIONS_HH__ */
diff --git a/src/synchronizer/communications_tmpl.hh b/src/synchronizer/communications_tmpl.hh
index 9b4f2aef9..71cb69298 100644
--- a/src/synchronizer/communications_tmpl.hh
+++ b/src/synchronizer/communications_tmpl.hh
@@ -1,550 +1,551 @@
 /**
  * @file   communications_tmpl.hh
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
- * @date   Tue Sep  6 17:14:06 2016
+ * @date creation: Wed Sep 07 2016
+ * @date last modification: Tue Feb 20 2018
  *
  * @brief  Implementation of Communications
  *
  * @section LICENSE
  *
- * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * 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
+ * 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
+ * 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 "communications.hh"
 /* -------------------------------------------------------------------------- */
 
 #ifndef __AKANTU_COMMUNICATIONS_TMPL_HH__
 #define __AKANTU_COMMUNICATIONS_TMPL_HH__
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 template <class Entity>
 Communications<Entity>::Communications(const Communicator & communicator)
     : communicator(communicator) {}
 
 /* -------------------------------------------------------------------------- */
 template <class Entity>
 Communications<Entity>::Communications(const Communications & other)
     : communicator(other.communicator) {
   for (auto sr : iterate_send_recv) {
     for (const auto & scheme_pair : other.iterateSchemes(sr)) {
       auto proc = scheme_pair.first;
       auto & other_scheme = scheme_pair.second;
       auto & scheme = this->createScheme(proc, sr);
       scheme.copy(other_scheme);
     }
   }
 
   this->invalidateSizes();
 }
 
 /* -------------------------------------------------------------------------- */
 template <class Entity> class Communications<Entity>::iterator {
   using communication_iterator =
       typename std::map<UInt, Communication>::iterator;
 
 public:
   iterator() : communications(nullptr) {}
   iterator(scheme_iterator scheme_it, communication_iterator comm_it,
            Communications<Entity> & communications,
            const SynchronizationTag & tag)
       : scheme_it(scheme_it), comm_it(comm_it), communications(&communications),
         tag(tag) {}
 
   iterator & operator=(const iterator & other) {
     if (this != &other) {
       this->scheme_it = other.scheme_it;
       this->comm_it = other.comm_it;
       this->communications = other.communications;
       this->tag = other.tag;
     }
     return *this;
   }
 
   iterator & operator++() {
     ++scheme_it;
     ++comm_it;
     return *this;
   }
 
   CommunicationDescriptor<Entity> operator*() {
     AKANTU_DEBUG_ASSERT(
         scheme_it->first == comm_it->first,
         "The two iterators are not in phase, something wrong"
             << " happened, time to take out your favorite debugger ("
             << scheme_it->first << " != " << comm_it->first << ")");
     return CommunicationDescriptor<Entity>(comm_it->second, scheme_it->second,
                                            *communications, tag,
                                            scheme_it->first);
   }
 
   bool operator==(const iterator & other) const {
     return scheme_it == other.scheme_it && comm_it == other.comm_it;
   }
 
   bool operator!=(const iterator & other) const {
     return scheme_it != other.scheme_it || comm_it != other.comm_it;
   }
 
 private:
   scheme_iterator scheme_it;
   communication_iterator comm_it;
   Communications<Entity> * communications;
   SynchronizationTag tag;
 };
 
 /* -------------------------------------------------------------------------- */
 template <class Entity> class Communications<Entity>::tag_iterator {
   using internal_iterator = std::map<SynchronizationTag, UInt>::const_iterator;
 
 public:
   tag_iterator(const internal_iterator & it) : it(it) {}
   tag_iterator & operator++() {
     ++it;
     return *this;
   }
   SynchronizationTag operator*() { return it->first; }
   bool operator==(const tag_iterator & other) const { return it == other.it; }
   bool operator!=(const tag_iterator & other) const { return it != other.it; }
 
 private:
   internal_iterator it;
 };
 
 /* -------------------------------------------------------------------------- */
 template <class Entity>
 typename Communications<Entity>::CommunicationPerProcs &
 Communications<Entity>::getCommunications(const SynchronizationTag & tag,
                                           const CommunicationSendRecv & sr) {
   auto comm_it = this->communications[sr].find(tag);
   if (comm_it == this->communications[sr].end())
     AKANTU_CUSTOM_EXCEPTION_INFO(
         debug::CommunicationException(),
         "No known communications for the tag: " << tag);
   return comm_it->second;
 }
 
 /* ---------------------------------------------------------------------- */
 template <class Entity>
 UInt Communications<Entity>::getPending(
     const SynchronizationTag & tag, const CommunicationSendRecv & sr) const {
   const std::map<SynchronizationTag, UInt> & pending =
       pending_communications[sr];
   auto it = pending.find(tag);
 
   if (it == pending.end())
     return 0;
   return it->second;
 }
 
 /* -------------------------------------------------------------------------- */
 template <class Entity>
 bool Communications<Entity>::hasPending(
     const SynchronizationTag & tag, const CommunicationSendRecv & sr) const {
   return this->hasCommunication(tag) && (this->getPending(tag, sr) != 0);
 }
 
 /* ---------------------------------------------------------------------- */
 template <class Entity>
 typename Communications<Entity>::iterator
 Communications<Entity>::begin(const SynchronizationTag & tag,
                               const CommunicationSendRecv & sr) {
   auto & comms = this->getCommunications(tag, sr);
   return iterator(this->schemes[sr].begin(), comms.begin(), *this, tag);
 }
 
 template <class Entity>
 typename Communications<Entity>::iterator
 Communications<Entity>::end(const SynchronizationTag & tag,
                             const CommunicationSendRecv & sr) {
   auto & comms = this->getCommunications(tag, sr);
   return iterator(this->schemes[sr].end(), comms.end(), *this, tag);
 }
 
 /* ---------------------------------------------------------------------- */
 template <class Entity>
 typename Communications<Entity>::iterator
 Communications<Entity>::waitAny(const SynchronizationTag & tag,
                                 const CommunicationSendRecv & sr) {
   auto & comms = this->getCommunications(tag, sr);
   auto it = comms.begin();
   auto end = comms.end();
 
   std::vector<CommunicationRequest> requests;
 
   for (; it != end; ++it) {
     auto & request = it->second.request();
     if (!request.isFreed())
       requests.push_back(request);
   }
 
   UInt req_id = communicator.waitAny(requests);
   if (req_id != UInt(-1)) {
     auto & request = requests[req_id];
     UInt proc = sr == _recv ? request.getSource() : request.getDestination();
 
     return iterator(this->schemes[sr].find(proc), comms.find(proc), *this, tag);
   } else {
     return this->end(tag, sr);
   }
 }
 
 /* ---------------------------------------------------------------------- */
 template <class Entity>
 void Communications<Entity>::waitAll(const SynchronizationTag & tag,
                                      const CommunicationSendRecv & sr) {
   auto & comms = this->getCommunications(tag, sr);
   auto it = comms.begin();
   auto end = comms.end();
 
   std::vector<CommunicationRequest> requests;
 
   for (; it != end; ++it) {
     requests.push_back(it->second.request());
   }
 
   communicator.waitAll(requests);
 }
 
 template <class Entity>
 void Communications<Entity>::incrementPending(
     const SynchronizationTag & tag, const CommunicationSendRecv & sr) {
   ++(pending_communications[sr][tag]);
 }
 
 template <class Entity>
 void Communications<Entity>::decrementPending(
     const SynchronizationTag & tag, const CommunicationSendRecv & sr) {
   --(pending_communications[sr][tag]);
 }
 
 template <class Entity>
 void Communications<Entity>::freeRequests(const SynchronizationTag & tag,
                                           const CommunicationSendRecv & sr) {
   iterator it = this->begin(tag, sr);
   iterator end = this->end(tag, sr);
 
   for (; it != end; ++it) {
     (*it).freeRequest();
   }
 }
 
 /* -------------------------------------------------------------------------- */
 template <class Entity>
 typename Communications<Entity>::Scheme &
 Communications<Entity>::createScheme(UInt proc,
                                      const CommunicationSendRecv & sr) {
   // scheme_iterator it = schemes[sr].find(proc);
   // if (it != schemes[sr].end()) {
   //   AKANTU_CUSTOM_EXCEPTION_INFO(debug::CommunicationException(),
   //                                "Communication scheme("
   //                                    << sr
   //                                    << ") already created for proc: " <<
   //                                    proc);
   // }
   return schemes[sr][proc];
 }
 
 template <class Entity>
 void Communications<Entity>::resetSchemes(const CommunicationSendRecv & sr) {
   auto it = this->schemes[sr].begin();
   auto end = this->schemes[sr].end();
   for (; it != end; ++it) {
     it->second.resize(0);
   }
 }
 
 /* -------------------------------------------------------------------------- */
 template <class Entity>
 void Communications<Entity>::setCommunicationSize(
     const SynchronizationTag & tag, UInt proc, UInt size,
     const CommunicationSendRecv & sr) {
   // accessor that fails if it does not exists
   comm_size_computed[tag] = true; // TODO: need perhaps to be split based on sr
   auto & comms = this->communications[sr];
   auto & comms_per_tag = comms.at(tag);
 
   comms_per_tag.at(proc).resize(size);
 }
 
 /* -------------------------------------------------------------------------- */
 template <class Entity>
 void Communications<Entity>::initializeCommunications(
     const SynchronizationTag & tag) {
 
   for (auto t = send_recv_t::begin(); t != send_recv_t::end(); ++t) {
     pending_communications[*t].insert(std::make_pair(tag, 0));
 
     auto & comms = this->communications[*t];
     auto & comms_per_tag =
         comms.insert(std::make_pair(tag, CommunicationPerProcs()))
             .first->second;
 
     for (auto pair : this->schemes[*t]) {
       comms_per_tag.emplace(std::piecewise_construct,
                             std::forward_as_tuple(pair.first),
                             std::forward_as_tuple(*t));
     }
   }
 
   comm_counter.insert(std::make_pair(tag, 0));
 }
 
 /* -------------------------------------------------------------------------- */
 template <class Entity>
 typename Communications<Entity>::tag_iterator
 Communications<Entity>::begin_tag() {
   return tag_iterator(comm_counter.begin());
 }
 
 template <class Entity>
 typename Communications<Entity>::tag_iterator
 Communications<Entity>::end_tag() {
   return tag_iterator(comm_counter.end());
 }
 
 /* -------------------------------------------------------------------------- */
 template <class Entity>
 typename Communications<Entity>::scheme_iterator
 Communications<Entity>::begin_scheme(const CommunicationSendRecv & sr) {
   return this->schemes[sr].begin();
 }
 
 template <class Entity>
 typename Communications<Entity>::scheme_iterator
 Communications<Entity>::end_scheme(const CommunicationSendRecv & sr) {
   return this->schemes[sr].end();
 }
 
 /* -------------------------------------------------------------------------- */
 template <class Entity>
 typename Communications<Entity>::const_scheme_iterator
 Communications<Entity>::begin_scheme(const CommunicationSendRecv & sr) const {
   return this->schemes[sr].begin();
 }
 
 template <class Entity>
 typename Communications<Entity>::const_scheme_iterator
 Communications<Entity>::end_scheme(const CommunicationSendRecv & sr) const {
   return this->schemes[sr].end();
 }
 
 /* -------------------------------------------------------------------------- */
 template <class Entity>
 typename Communications<Entity>::scheme_iterator
 Communications<Entity>::begin_send_scheme() {
   return this->begin_scheme(_send);
 }
 
 template <class Entity>
 typename Communications<Entity>::scheme_iterator
 Communications<Entity>::end_send_scheme() {
   return this->end_scheme(_send);
 }
 
 /* -------------------------------------------------------------------------- */
 template <class Entity>
 typename Communications<Entity>::const_scheme_iterator
 Communications<Entity>::begin_send_scheme() const {
   return this->begin_scheme(_send);
 }
 
 template <class Entity>
 typename Communications<Entity>::const_scheme_iterator
 Communications<Entity>::end_send_scheme() const {
   return this->end_scheme(_send);
 }
 
 /* -------------------------------------------------------------------------- */
 template <class Entity>
 typename Communications<Entity>::scheme_iterator
 Communications<Entity>::begin_recv_scheme() {
   return this->begin_scheme(_recv);
 }
 
 template <class Entity>
 typename Communications<Entity>::scheme_iterator
 Communications<Entity>::end_recv_scheme() {
   return this->end_scheme(_recv);
 }
 
 /* -------------------------------------------------------------------------- */
 template <class Entity>
 typename Communications<Entity>::const_scheme_iterator
 Communications<Entity>::begin_recv_scheme() const {
   return this->begin_scheme(_recv);
 }
 
 template <class Entity>
 typename Communications<Entity>::const_scheme_iterator
 Communications<Entity>::end_recv_scheme() const {
   return this->end_scheme(_recv);
 }
 
 /* ------------------------------------------------------------------------ */
 template <class Entity>
 bool Communications<Entity>::hasCommunication(
     const SynchronizationTag & tag) const {
   return (communications[_send].find(tag) != communications[_send].end());
 }
 
 template <class Entity>
 void Communications<Entity>::incrementCounter(const SynchronizationTag & tag) {
   auto it = comm_counter.find(tag);
   if (it == comm_counter.end()) {
     AKANTU_CUSTOM_EXCEPTION_INFO(
         debug::CommunicationException(),
         "No counter initialized in communications for the tags: " << tag);
   }
 
   ++(it->second);
 }
 
 template <class Entity>
 UInt Communications<Entity>::getCounter(const SynchronizationTag & tag) const {
   auto it = comm_counter.find(tag);
   if (it == comm_counter.end()) {
     AKANTU_CUSTOM_EXCEPTION_INFO(
         debug::CommunicationException(),
         "No counter initialized in communications for the tags: " << tag);
   }
 
   return it->second;
 }
 
 template <class Entity>
 bool Communications<Entity>::hasCommunicationSize(
     const SynchronizationTag & tag) const {
   auto it = comm_size_computed.find(tag);
   if (it == comm_size_computed.end()) {
     return false;
   }
 
   return it->second;
 }
 
 template <class Entity> void Communications<Entity>::invalidateSizes() {
   for (auto && pair : comm_size_computed) {
     pair.second = true;
   }
 }
 
 template <class Entity>
 bool Communications<Entity>::hasPendingRecv(
     const SynchronizationTag & tag) const {
   return this->hasPending(tag, _recv);
 }
 
 template <class Entity>
 bool Communications<Entity>::hasPendingSend(
     const SynchronizationTag & tag) const {
   return this->hasPending(tag, _send);
 }
 
 template <class Entity>
 const auto & Communications<Entity>::getCommunicator() const {
   return communicator;
 }
 
 /* -------------------------------------------------------------------------- */
 template <class Entity>
 typename Communications<Entity>::iterator
 Communications<Entity>::waitAnyRecv(const SynchronizationTag & tag) {
   return this->waitAny(tag, _recv);
 }
 
 template <class Entity>
 typename Communications<Entity>::iterator
 Communications<Entity>::waitAnySend(const SynchronizationTag & tag) {
   return this->waitAny(tag, _send);
 }
 
 template <class Entity>
 void Communications<Entity>::waitAllRecv(const SynchronizationTag & tag) {
   this->waitAll(tag, _recv);
 }
 
 template <class Entity>
 void Communications<Entity>::waitAllSend(const SynchronizationTag & tag) {
   this->waitAll(tag, _send);
 }
 
 template <class Entity>
 void Communications<Entity>::freeSendRequests(const SynchronizationTag & tag) {
   this->freeRequests(tag, _send);
 }
 
 template <class Entity>
 void Communications<Entity>::freeRecvRequests(const SynchronizationTag & tag) {
   this->freeRequests(tag, _recv);
 }
 
 /* -------------------------------------------------------------------------- */
 template <class Entity>
 typename Communications<Entity>::Scheme &
 Communications<Entity>::createSendScheme(UInt proc) {
   return createScheme(proc, _send);
 }
 
 template <class Entity>
 typename Communications<Entity>::Scheme &
 Communications<Entity>::createRecvScheme(UInt proc) {
   return createScheme(proc, _recv);
 }
 
 /* -------------------------------------------------------------------------- */
 template <class Entity> void Communications<Entity>::resetSchemes() {
   resetSchemes(_send);
   resetSchemes(_recv);
 }
 
 /* -------------------------------------------------------------------------- */
 template <class Entity>
 typename Communications<Entity>::Scheme &
 Communications<Entity>::getScheme(UInt proc, const CommunicationSendRecv & sr) {
   return this->schemes[sr].find(proc)->second;
 }
 
 /* -------------------------------------------------------------------------- */
 template <class Entity>
 const typename Communications<Entity>::Scheme &
 Communications<Entity>::getScheme(UInt proc,
                                   const CommunicationSendRecv & sr) const {
   return this->schemes[sr].find(proc)->second;
 }
 
 /* -------------------------------------------------------------------------- */
 template <class Entity>
 void Communications<Entity>::setSendCommunicationSize(
     const SynchronizationTag & tag, UInt proc, UInt size) {
   this->setCommunicationSize(tag, proc, size, _send);
 }
 
 template <class Entity>
 void Communications<Entity>::setRecvCommunicationSize(
     const SynchronizationTag & tag, UInt proc, UInt size) {
   this->setCommunicationSize(tag, proc, size, _recv);
 }
 
 } // namespace akantu
 
 #endif /* __AKANTU_COMMUNICATIONS_TMPL_HH__ */
diff --git a/src/synchronizer/communicator.cc b/src/synchronizer/communicator.cc
index ff8ae1f9a..fc925697c 100644
--- a/src/synchronizer/communicator.cc
+++ b/src/synchronizer/communicator.cc
@@ -1,182 +1,181 @@
 /**
- * @file   static_communicator.cc
+ * @file   communicator.cc
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Fri Jun 18 2010
- * @date last modification: Tue Jan 19 2016
+ * @date last modification: Mon Feb 05 2018
  *
  * @brief  implementation of the common part of the static communicator
  *
  * @section LICENSE
  *
- * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
- * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
- * Solides)
+ * 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
+ * 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
+ * A PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 #include "communicator.hh"
 #if defined(AKANTU_USE_MPI)
 #include "mpi_communicator_data.hh"
 #endif
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 
 #if defined(AKANTU_USE_MPI)
 int MPICommunicatorData::is_externaly_initialized = 0;
 #endif
 
 UInt InternalCommunicationRequest::counter = 0;
 
 /* -------------------------------------------------------------------------- */
 InternalCommunicationRequest::InternalCommunicationRequest(UInt source,
                                                            UInt dest)
     : source(source), destination(dest) {
   this->id = counter++;
 }
 
 /* -------------------------------------------------------------------------- */
 InternalCommunicationRequest::~InternalCommunicationRequest() = default;
 
 /* -------------------------------------------------------------------------- */
 void InternalCommunicationRequest::printself(std::ostream & stream,
                                              int indent) const {
   std::string space;
   for (Int i = 0; i < indent; i++, space += AKANTU_INDENT)
     ;
 
   stream << space << "CommunicationRequest [" << std::endl;
   stream << space << " + id          : " << id << std::endl;
   stream << space << " + source      : " << source << std::endl;
   stream << space << " + destination : " << destination << std::endl;
   stream << space << "]" << std::endl;
 }
 
 /* -------------------------------------------------------------------------- */
 Communicator::~Communicator() {
   auto * event = new FinalizeCommunicatorEvent(*this);
   this->sendEvent(*event);
   delete event;
 }
 
 /* -------------------------------------------------------------------------- */
 Communicator & Communicator::getStaticCommunicator() {
   AKANTU_DEBUG_IN();
 
   if (!static_communicator) {
     int nb_args = 0;
     char ** null = nullptr;
     static_communicator =
         std::make_unique<Communicator>(nb_args, null, private_member{});
   }
 
   AKANTU_DEBUG_OUT();
   return *static_communicator;
 }
 
 /* -------------------------------------------------------------------------- */
 Communicator & Communicator::getStaticCommunicator(int & argc, char **& argv) {
   if (!static_communicator)
     static_communicator =
         std::make_unique<Communicator>(argc, argv, private_member{});
   return getStaticCommunicator();
 }
 
 } // namespace akantu
 
 #ifdef AKANTU_USE_MPI
 #include "communicator_mpi_inline_impl.cc"
 #else
 #include "communicator_dummy_inline_impl.cc"
 #endif
 
 namespace akantu {
 /* -------------------------------------------------------------------------- */
 /* Template instantiation                                                     */
 /* -------------------------------------------------------------------------- */
 #define AKANTU_COMM_INSTANTIATE(T)                                             \
   template void Communicator::probe<T>(Int sender, Int tag,                    \
                                        CommunicationStatus & status) const;    \
   template bool Communicator::asyncProbe<T>(                                   \
       Int sender, Int tag, CommunicationStatus & status) const;                \
   template void Communicator::sendImpl<T>(                                     \
       const T * buffer, Int size, Int receiver, Int tag,                       \
       const CommunicationMode & mode) const;                                   \
   template void Communicator::receiveImpl<T>(T * buffer, Int size, Int sender, \
                                              Int tag) const;                   \
   template CommunicationRequest Communicator::asyncSendImpl<T>(                \
       const T * buffer, Int size, Int receiver, Int tag,                       \
       const CommunicationMode & mode) const;                                   \
   template CommunicationRequest Communicator::asyncReceiveImpl<T>(             \
       T * buffer, Int size, Int sender, Int tag) const;                        \
   template void Communicator::allGatherImpl<T>(T * values, int nb_values)      \
       const;                                                                   \
   template void Communicator::allGatherVImpl<T>(T * values, int * nb_values)   \
       const;                                                                   \
   template void Communicator::gatherImpl<T>(T * values, int nb_values,         \
                                             int root) const;                   \
   template void Communicator::gatherImpl<T>(                                   \
       T * values, int nb_values, T * gathered, int nb_gathered) const;         \
   template void Communicator::gatherVImpl<T>(T * values, int * nb_values,      \
                                              int root) const;                  \
   template void Communicator::broadcastImpl<T>(T * values, int nb_values,      \
                                                int root) const;                \
   template void Communicator::allReduceImpl<T>(                                \
       T * values, int nb_values, const SynchronizerOperation & op) const
 
 #define MIN_MAX_REAL SCMinMaxLoc<Real, int>
 
 AKANTU_COMM_INSTANTIATE(bool);
 AKANTU_COMM_INSTANTIATE(Real);
 AKANTU_COMM_INSTANTIATE(UInt);
 AKANTU_COMM_INSTANTIATE(Int);
 AKANTU_COMM_INSTANTIATE(char);
 AKANTU_COMM_INSTANTIATE(NodeType);
 AKANTU_COMM_INSTANTIATE(MIN_MAX_REAL);
 
 #if AKANTU_INTEGER_SIZE > 4
 AKANTU_COMM_INSTANTIATE(int);
 #endif
 
 // template void Communicator::send<SCMinMaxLoc<Real, int>>(
 //     SCMinMaxLoc<Real, int> * buffer, Int size, Int receiver, Int tag);
 // template void Communicator::receive<SCMinMaxLoc<Real, int>>(
 //     SCMinMaxLoc<Real, int> * buffer, Int size, Int sender, Int tag);
 // template CommunicationRequest
 // Communicator::asyncSend<SCMinMaxLoc<Real, int>>(
 //     SCMinMaxLoc<Real, int> * buffer, Int size, Int receiver, Int tag);
 // template CommunicationRequest
 // Communicator::asyncReceive<SCMinMaxLoc<Real, int>>(
 //     SCMinMaxLoc<Real, int> * buffer, Int size, Int sender, Int tag);
 // template void Communicator::probe<SCMinMaxLoc<Real, int>>(
 //     Int sender, Int tag, CommunicationStatus & status);
 // template void Communicator::allGather<SCMinMaxLoc<Real, int>>(
 //     SCMinMaxLoc<Real, int> * values, int nb_values);
 // template void Communicator::allGatherV<SCMinMaxLoc<Real, int>>(
 //     SCMinMaxLoc<Real, int> * values, int * nb_values);
 // template void Communicator::gather<SCMinMaxLoc<Real, int>>(
 //     SCMinMaxLoc<Real, int> * values, int nb_values, int root);
 // template void Communicator::gatherV<SCMinMaxLoc<Real, int>>(
 //     SCMinMaxLoc<Real, int> * values, int * nb_values, int root);
 // template void Communicator::broadcast<SCMinMaxLoc<Real, int>>(
 //     SCMinMaxLoc<Real, int> * values, int nb_values, int root);
 // template void Communicator::allReduce<SCMinMaxLoc<Real, int>>(
 //     SCMinMaxLoc<Real, int> * values, int nb_values,
 //     const SynchronizerOperation & op);
 } // akantu
diff --git a/src/synchronizer/communicator.hh b/src/synchronizer/communicator.hh
index 045542321..d045722d3 100644
--- a/src/synchronizer/communicator.hh
+++ b/src/synchronizer/communicator.hh
@@ -1,437 +1,437 @@
 /**
- * @file   static_communicator.hh
+ * @file   communicator.hh
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Fri Jun 18 2010
- * @date last modification: Tue Jan 19 2016
+ * @date last modification: Wed Nov 15 2017
  *
  * @brief  Class handling the parallel communications
  *
  * @section LICENSE
  *
- * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
- * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
- * Solides)
+ * 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
+ * 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
+ * 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_array.hh"
 #include "aka_common.hh"
 #include "aka_event_handler_manager.hh"
 #include "communication_buffer.hh"
 #include "communication_request.hh"
 #include "communicator_event_handler.hh"
 /* -------------------------------------------------------------------------- */
 
 #ifndef __AKANTU_STATIC_COMMUNICATOR_HH__
 #define __AKANTU_STATIC_COMMUNICATOR_HH__
 
 namespace akantu {
 
 namespace debug {
   class CommunicationException : public Exception {
   public:
     CommunicationException()
         : Exception("An exception happen during a communication process.") {}
   };
 } // namespace debug
 
 /// @enum SynchronizerOperation reduce operation that the synchronizer can
 /// perform
 enum class SynchronizerOperation {
   _sum,
   _min,
   _max,
   _prod,
   _land,
   _band,
   _lor,
   _bor,
   _lxor,
   _bxor,
   _min_loc,
   _max_loc,
   _null
 };
 
 enum class CommunicationMode { _auto, _synchronous, _ready };
 
 namespace {
   int _any_source = -1;
 }
 } // namespace akantu
 
 namespace akantu {
 
 struct CommunicatorInternalData {
   virtual ~CommunicatorInternalData() = default;
 };
 
 /* -------------------------------------------------------------------------- */
 /* -------------------------------------------------------------------------- */
 
 class Communicator : public EventHandlerManager<CommunicatorEventHandler> {
   struct private_member {};
   /* ------------------------------------------------------------------------ */
   /* Constructors/Destructors                                                 */
   /* ------------------------------------------------------------------------ */
 public:
   Communicator(int & argc, char **& argv, const private_member &);
   ~Communicator() override;
 
   /* ------------------------------------------------------------------------ */
   /* Methods                                                                  */
   /* ------------------------------------------------------------------------ */
 public:
   /* ------------------------------------------------------------------------ */
   /* Point to Point                                                           */
   /* ------------------------------------------------------------------------ */
   template <typename T>
   inline void receive(Array<T> & values, Int sender, Int tag) const {
     return this->receiveImpl(
         values.storage(), values.size() * values.getNbComponent(), sender, tag);
   }
   template <typename Tensor>
   inline void
   receive(Tensor & values, Int sender, Int tag,
           std::enable_if_t<is_tensor<Tensor>::value> * = nullptr) const {
     return this->receiveImpl(values.storage(), values.size(), sender, tag);
   }
   template <bool is_static>
   inline void receive(CommunicationBufferTemplated<is_static> & values,
                       Int sender, Int tag) const {
     return this->receiveImpl(values.storage(), values.size(), sender, tag);
   }
   template <typename T>
   inline void
   receive(T & values, Int sender, Int tag,
           std::enable_if_t<std::is_arithmetic<T>::value> * = nullptr) const {
     return this->receiveImpl(&values, 1, sender, tag);
   }
   /* ------------------------------------------------------------------------ */
   template <typename T>
   inline void
   send(const Array<T> & values, Int receiver, Int tag,
        const CommunicationMode & mode = CommunicationMode::_auto) const {
     return this->sendImpl(values.storage(),
                           values.size() * values.getNbComponent(), receiver,
                           tag, mode);
   }
   template <typename Tensor>
   inline void
   send(const Tensor & values, Int receiver, Int tag,
        const CommunicationMode & mode = CommunicationMode::_auto,
        std::enable_if_t<is_tensor<Tensor>::value> * = nullptr) const {
     return this->sendImpl(values.storage(), values.size(), receiver, tag, mode);
   }
   template <bool is_static>
   inline void
   send(const CommunicationBufferTemplated<is_static> & values, Int receiver,
        Int tag,
        const CommunicationMode & mode = CommunicationMode::_auto) const {
     return this->sendImpl(values.storage(), values.size(), receiver, tag, mode);
   }
   template <typename T>
   inline void
   send(const T & values, Int receiver, Int tag,
        const CommunicationMode & mode = CommunicationMode::_auto,
        std::enable_if_t<std::is_arithmetic<T>::value> * = nullptr) const {
     return this->sendImpl(&values, 1, receiver, tag, mode);
   }
 
   /* ------------------------------------------------------------------------ */
   template <typename T>
   inline CommunicationRequest
   asyncSend(const Array<T> & values, Int receiver, Int tag,
             const CommunicationMode & mode = CommunicationMode::_auto) const {
     return this->asyncSendImpl(values.storage(),
                                values.size() * values.getNbComponent(),
                                receiver, tag, mode);
   }
   template <typename T>
   inline CommunicationRequest
   asyncSend(const std::vector<T> & values, Int receiver, Int tag,
             const CommunicationMode & mode = CommunicationMode::_auto) const {
     return this->asyncSendImpl(values.data(), values.size(), receiver, tag,
                                mode);
   }
 
   template <typename Tensor>
   inline CommunicationRequest
   asyncSend(const Tensor & values, Int receiver, Int tag,
             const CommunicationMode & mode = CommunicationMode::_auto,
             std::enable_if_t<is_tensor<Tensor>::value> * = nullptr) const {
     return this->asyncSendImpl(values.storage(), values.size(), receiver, tag,
                                mode);
   }
   template <bool is_static>
   inline CommunicationRequest
   asyncSend(const CommunicationBufferTemplated<is_static> & values,
             Int receiver, Int tag,
             const CommunicationMode & mode = CommunicationMode::_auto) const {
     return this->asyncSendImpl(values.storage(), values.size(), receiver, tag,
                                mode);
   }
   template <typename T>
   inline CommunicationRequest
   asyncSend(const T & values, Int receiver, Int tag,
             const CommunicationMode & mode = CommunicationMode::_auto,
             std::enable_if_t<std::is_arithmetic<T>::value> * = nullptr) const {
     return this->asyncSendImpl(&values, 1, receiver, tag, mode);
   }
 
   /* ------------------------------------------------------------------------ */
   template <typename T>
   inline CommunicationRequest asyncReceive(Array<T> & values, Int sender,
                                            Int tag) const {
     return this->asyncReceiveImpl(
         values.storage(), values.size() * values.getNbComponent(), sender, tag);
   }
   template <typename T>
   inline CommunicationRequest asyncReceive(std::vector<T> & values, Int sender,
                                            Int tag) const {
     return this->asyncReceiveImpl(values.data(), values.size(), sender, tag);
   }
 
   template <typename Tensor,
             typename = std::enable_if_t<is_tensor<Tensor>::value>>
   inline CommunicationRequest asyncReceive(Tensor & values, Int sender,
                                            Int tag) const {
     return this->asyncReceiveImpl(values.storage(), values.size(), sender, tag);
   }
   template <bool is_static>
   inline CommunicationRequest
   asyncReceive(CommunicationBufferTemplated<is_static> & values, Int sender,
                Int tag) const {
     return this->asyncReceiveImpl(values.storage(), values.size(), sender, tag);
   }
 
   /* ------------------------------------------------------------------------ */
   template <typename T>
   void probe(Int sender, Int tag, CommunicationStatus & status) const;
 
   template <typename T>
   bool asyncProbe(Int sender, Int tag, CommunicationStatus & status) const;
 
   /* ------------------------------------------------------------------------ */
   /* Collectives                                                              */
   /* ------------------------------------------------------------------------ */
   template <typename T>
   inline void allReduce(Array<T> & values,
                         const SynchronizerOperation & op) const {
     this->allReduceImpl(values.storage(),
                         values.size() * values.getNbComponent(), op);
   }
 
   template <typename Tensor>
   inline void
   allReduce(Tensor & values, const SynchronizerOperation & op,
             std::enable_if_t<is_tensor<Tensor>::value> * = nullptr) const {
     this->allReduceImpl(values.storage(), values.size(), op);
   }
 
   template <typename T>
   inline void
   allReduce(T & values, const SynchronizerOperation & op,
             std::enable_if_t<std::is_arithmetic<T>::value> * = nullptr) const {
     this->allReduceImpl(&values, 1, op);
   }
 
   /* ------------------------------------------------------------------------ */
   template <typename T> inline void allGather(Array<T> & values) const {
     AKANTU_DEBUG_ASSERT(UInt(psize) == values.size(),
                         "The array size is not correct");
     this->allGatherImpl(values.storage(), values.getNbComponent());
   }
 
   template <typename Tensor,
             typename = std::enable_if_t<is_tensor<Tensor>::value>>
   inline void allGather(Tensor & values) const {
     AKANTU_DEBUG_ASSERT(UInt(psize) == values.size(),
                         "The vector size is not correct");
     this->allGatherImpl(values.storage(), 1);
   }
 
   /* ------------------------------------------------------------------------ */
   template <typename T>
   inline void allGatherV(Array<T> & values, const Array<Int> & sizes) const {
     this->allGatherVImpl(values.storage(), sizes.storage());
   }
 
   /* ------------------------------------------------------------------------ */
   template <typename T>
   inline void reduce(Array<T> & values, const SynchronizerOperation & op,
                      int root = 0) const {
     this->reduceImpl(values.storage(), values.size() * values.getNbComponent(),
                      op, root);
   }
 
   /* ------------------------------------------------------------------------ */
   template <typename Tensor>
   inline void
   gather(Tensor & values, int root = 0,
          std::enable_if_t<is_tensor<Tensor>::value> * = nullptr) const {
     this->gatherImpl(values.storage(), values.getNbComponent(), root);
   }
   template <typename T>
   inline void
   gather(T values, int root = 0,
          std::enable_if_t<std::is_arithmetic<T>::value> * = nullptr) const {
     this->gatherImpl(&values, 1, root);
   }
   /* ------------------------------------------------------------------------ */
   template <typename Tensor, typename T>
   inline void
   gather(Tensor & values, Array<T> & gathered,
          std::enable_if_t<is_tensor<Tensor>::value> * = nullptr) const {
     AKANTU_DEBUG_ASSERT(values.size() == gathered.getNbComponent(),
                         "The array size is not correct");
     gathered.resize(psize);
     this->gatherImpl(values.data(), values.size(), gathered.storage(),
                      gathered.getNbComponent());
   }
 
   template <typename T>
   inline void
   gather(T values, Array<T> & gathered,
          std::enable_if_t<std::is_arithmetic<T>::value> * = nullptr) const {
     this->gatherImpl(&values, 1, gathered.storage(), 1);
   }
 
   /* ------------------------------------------------------------------------ */
   template <typename T>
   inline void gatherV(Array<T> & values, const Array<Int> & sizes,
                       int root = 0) const {
     this->gatherVImpl(values.storage(), sizes.storage(), root);
   }
 
   /* ------------------------------------------------------------------------ */
   template <typename T>
   inline void broadcast(Array<T> & values, int root = 0) const {
     this->broadcastImpl(values.storage(),
                         values.size() * values.getNbComponent(), root);
   }
   template <bool is_static>
   inline void broadcast(CommunicationBufferTemplated<is_static> & values,
                         int root = 0) const {
     this->broadcastImpl(values.storage(), values.size(), root);
   }
   template <typename T> inline void broadcast(T & values, int root = 0) const {
     this->broadcastImpl(&values, 1, root);
   }
 
   /* ------------------------------------------------------------------------ */
   void barrier() const;
   CommunicationRequest asyncBarrier() const;
 
   /* ------------------------------------------------------------------------ */
   /* Request handling                                                         */
   /* ------------------------------------------------------------------------ */
   bool test(CommunicationRequest & request) const;
   bool testAll(std::vector<CommunicationRequest> & request) const;
   void wait(CommunicationRequest & request) const;
   void waitAll(std::vector<CommunicationRequest> & requests) const;
   UInt waitAny(std::vector<CommunicationRequest> & requests) const;
   inline void freeCommunicationRequest(CommunicationRequest & request) const;
   inline void
   freeCommunicationRequest(std::vector<CommunicationRequest> & requests) const;
 
   template <typename T, typename MsgProcessor, typename TagGen>
   inline void
   receiveAnyNumber(std::vector<CommunicationRequest> & send_requests,
                    Array<T> receive_buffer, MsgProcessor && processor,
                    TagGen && tag_gen) const;
 
 protected:
   template <typename T>
   void
   sendImpl(const T * buffer, Int size, Int receiver, Int tag,
            const CommunicationMode & mode = CommunicationMode::_auto) const;
 
   template <typename T>
   void receiveImpl(T * buffer, Int size, Int sender, Int tag) const;
 
   template <typename T>
   CommunicationRequest asyncSendImpl(
       const T * buffer, Int size, Int receiver, Int tag,
       const CommunicationMode & mode = CommunicationMode::_auto) const;
 
   template <typename T>
   CommunicationRequest asyncReceiveImpl(T * buffer, Int size, Int sender,
                                         Int tag) const;
 
   template <typename T>
   void allReduceImpl(T * values, int nb_values,
                      const SynchronizerOperation & op) const;
 
   template <typename T> void allGatherImpl(T * values, int nb_values) const;
   template <typename T> void allGatherVImpl(T * values, int * nb_values) const;
 
   template <typename T>
   void reduceImpl(T * values, int nb_values, const SynchronizerOperation & op,
                   int root = 0) const;
   template <typename T>
   void gatherImpl(T * values, int nb_values, int root = 0) const;
 
   template <typename T>
   void gatherImpl(T * values, int nb_values, T * gathered,
                   int nb_gathered = 0) const;
 
   template <typename T>
   void gatherVImpl(T * values, int * nb_values, int root = 0) const;
 
   template <typename T>
   void broadcastImpl(T * values, int nb_values, int root = 0) const;
 
   /* ------------------------------------------------------------------------ */
   /* Accessors                                                                */
   /* ------------------------------------------------------------------------ */
 public:
   Int getNbProc() const { return psize; };
   Int whoAmI() const { return prank; };
 
   static Communicator & getStaticCommunicator();
   static Communicator & getStaticCommunicator(int & argc, char **& argv);
 
   int getMaxTag() const;
   int getMinTag() const;
 
   AKANTU_GET_MACRO(CommunicatorData, (*communicator_data), decltype(auto));
 
   /* ------------------------------------------------------------------------ */
   /* Class Members                                                            */
   /* ------------------------------------------------------------------------ */
 private:
   static std::unique_ptr<Communicator> static_communicator;
 
 protected:
   Int prank{0};
   Int psize{1};
   std::unique_ptr<CommunicatorInternalData> communicator_data;
 };
 
 inline std::ostream & operator<<(std::ostream & stream,
                                  const CommunicationRequest & _this) {
   _this.printself(stream);
   return stream;
 }
 
 } // namespace akantu
 
 #include "communicator_inline_impl.hh"
 
 #endif /* __AKANTU_STATIC_COMMUNICATOR_HH__ */
diff --git a/src/synchronizer/communicator_dummy_inline_impl.cc b/src/synchronizer/communicator_dummy_inline_impl.cc
index 9b92a14fd..79aead7f4 100644
--- a/src/synchronizer/communicator_dummy_inline_impl.cc
+++ b/src/synchronizer/communicator_dummy_inline_impl.cc
@@ -1,118 +1,117 @@
 /**
- * @file   static_communicator_dummy.hh
+ * @file   communicator_dummy_inline_impl.cc
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
- * @date creation: Fri Jun 18 2010
- * @date last modification: Wed Jan 13 2016
+ * @date creation: Tue Nov 07 2017
+ * @date last modification: Fri Nov 10 2017
  *
  * @brief  Dummy communicator to make everything work im sequential
  *
  * @section LICENSE
  *
- * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
- * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
- * Solides)
+ * 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
+ * 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
+ * A PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 #include "communicator.hh"
 /* -------------------------------------------------------------------------- */
 #include <cstring>
 #include <type_traits>
 #include <vector>
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 
 Communicator::Communicator(int & /*argc*/, char **& /*argv*/,
                            const private_member & /*unused*/) {}
 
 template <typename T>
 void Communicator::sendImpl(const T *, Int, Int, Int,
                             const CommunicationMode &) const {}
 template <typename T>
 void Communicator::receiveImpl(T *, Int, Int, Int) const {}
 
 template <typename T>
 CommunicationRequest
 Communicator::asyncSendImpl(const T *, Int, Int, Int,
                             const CommunicationMode &) const {
   return std::shared_ptr<InternalCommunicationRequest>(
       new InternalCommunicationRequest(0, 0));
 }
 
 template <typename T>
 CommunicationRequest Communicator::asyncReceiveImpl(T *, Int, Int, Int) const {
   return std::shared_ptr<InternalCommunicationRequest>(
       new InternalCommunicationRequest(0, 0));
 }
 
 template <typename T>
 void Communicator::probe(Int, Int, CommunicationStatus &) const {}
 template <typename T>
 bool Communicator::asyncProbe(Int, Int, CommunicationStatus &) const {
   return true;
 }
 
 bool Communicator::test(CommunicationRequest &) const { return true; }
 bool Communicator::testAll(std::vector<CommunicationRequest> &) const {
   return true;
 }
 void Communicator::wait(CommunicationRequest &) const {}
 void Communicator::waitAll(std::vector<CommunicationRequest> &) const {}
 UInt Communicator::waitAny(std::vector<CommunicationRequest> &) const {
   return UInt(-1);
 }
 
 void Communicator::barrier() const {}
 CommunicationRequest Communicator::asyncBarrier() const {
   return std::shared_ptr<InternalCommunicationRequest>(
       new InternalCommunicationRequest(0, 0));
 }
 
 template <typename T>
 void Communicator::reduceImpl(T *, int, const SynchronizerOperation &,
                               int) const {}
 
 template <typename T>
 void Communicator::allReduceImpl(T *, int,
                                  const SynchronizerOperation &) const {}
 
 template <typename T> inline void Communicator::allGatherImpl(T *, int) const {}
 template <typename T>
 inline void Communicator::allGatherVImpl(T *, int *) const {}
 
 template <typename T>
 inline void Communicator::gatherImpl(T *, int, int) const {}
 template <typename T>
 void Communicator::gatherImpl(T * values, int nb_values, T * gathered,
                               int) const {
   static_assert(std::is_trivially_copyable<T>{},
                 "Cannot send this type of data");
   std::memcpy(gathered, values, nb_values);
 }
 
 template <typename T>
 inline void Communicator::gatherVImpl(T *, int *, int) const {}
 template <typename T>
 inline void Communicator::broadcastImpl(T *, int, int) const {}
 
 int Communicator::getMaxTag() const { return std::numeric_limits<int>::max(); }
 int Communicator::getMinTag() const { return 0; }
 
 } // namespace akantu
diff --git a/src/synchronizer/communicator_event_handler.hh b/src/synchronizer/communicator_event_handler.hh
index 9265521c7..f740ed40e 100644
--- a/src/synchronizer/communicator_event_handler.hh
+++ b/src/synchronizer/communicator_event_handler.hh
@@ -1,58 +1,61 @@
 /**
  * @file   communicator_event_handler.hh
  *
- * @author Nicolas Richart
+ * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
- * @date creation  Wed Nov 15 2017
+ * @date creation: Fri Jun 18 2010
+ * @date last modification: Wed Nov 15 2017
  *
+ * @brief  Event handler of the communicator
  *
  * @section LICENSE
  *
- * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * 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
+ * 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
+ * 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_COMMUNICATOR_EVENT_HANDLER_HH__
 #define __AKANTU_COMMUNICATOR_EVENT_HANDLER_HH__
 
 namespace akantu {
 
 class Communicator;
 
 struct FinalizeCommunicatorEvent {
   explicit FinalizeCommunicatorEvent(const Communicator & comm)
       : communicator(comm) {}
   const Communicator & communicator;
 };
 
 class CommunicatorEventHandler {
 public:
   virtual ~CommunicatorEventHandler() = default;
   virtual void onCommunicatorFinalize() = 0;
 
 private:
   inline void sendEvent(const FinalizeCommunicatorEvent &) {
     this->onCommunicatorFinalize();
   }
 
   template <class EventHandler> friend class EventHandlerManager;
 };
 
 } // akantu
 
 #endif /* __AKANTU_COMMUNICATOR_EVENT_HANDLER_HH__ */
diff --git a/src/synchronizer/communicator_inline_impl.hh b/src/synchronizer/communicator_inline_impl.hh
index 3d669332b..7021cb145 100644
--- a/src/synchronizer/communicator_inline_impl.hh
+++ b/src/synchronizer/communicator_inline_impl.hh
@@ -1,88 +1,88 @@
 /**
- * @file   static_communicator_inline_impl.hh
+ * @file   communicator_inline_impl.hh
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
- * @date creation: Mon Sep 06 2010
- * @date last modification: Thu Dec 10 2015
+ * @date creation: Tue Feb 02 2016
+ * @date last modification: Tue Nov 07 2017
  *
  * @brief  implementation of inline functions
  *
  * @section LICENSE
  *
- * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
- * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
- * Solides)
+ * 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
+ * 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
+ * A PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
+
 /* -------------------------------------------------------------------------- */
 #include "communicator.hh"
 /* -------------------------------------------------------------------------- */
 
 #ifndef __AKANTU_STATIC_COMMUNICATOR_INLINE_IMPL_HH__
 #define __AKANTU_STATIC_COMMUNICATOR_INLINE_IMPL_HH__
 
 namespace akantu {
 /* -------------------------------------------------------------------------- */
 inline void
 Communicator::freeCommunicationRequest(CommunicationRequest & request) const {
   request.free();
 }
 
 /* -------------------------------------------------------------------------- */
 inline void Communicator::freeCommunicationRequest(
     std::vector<CommunicationRequest> & requests) const {
   std::vector<CommunicationRequest>::iterator it;
   for (it = requests.begin(); it != requests.end(); ++it) {
     it->free();
   }
 }
 
 /* -------------------------------------------------------------------------- */
 template <typename T, typename MsgProcessor, typename TagGen>
 inline void Communicator::receiveAnyNumber(
     std::vector<CommunicationRequest> & send_requests, Array<T> receive_buffer,
     MsgProcessor && processor, TagGen && tag_gen) const {
   CommunicationRequest barrier_request;
   bool got_all = false, are_send_finished = false;
   while (not got_all) {
     bool are_receives_ready = true;
     while (are_receives_ready) {
       auto && tag = std::forward<TagGen>(tag_gen)();
       CommunicationStatus status;
       are_receives_ready = asyncProbe<UInt>(_any_source, tag, status);
       if (are_receives_ready) {
         receive_buffer.resize(status.size());
         receive(receive_buffer, status.getSource(), tag);
         std::forward<MsgProcessor>(processor)(status.getSource(),
                                               receive_buffer);
       }
     }
 
     if (not are_send_finished) {
       are_send_finished = testAll(send_requests);
       if (are_send_finished)
         barrier_request = asyncBarrier();
     }
 
     if (are_send_finished) {
       got_all = test(barrier_request);
     }
   }
 }
 } // namespace akantu
 
 #endif /* __AKANTU_STATIC_COMMUNICATOR_INLINE_IMPL_HH__ */
diff --git a/src/synchronizer/communicator_mpi_inline_impl.cc b/src/synchronizer/communicator_mpi_inline_impl.cc
index 9bd9fcf51..fda048047 100644
--- a/src/synchronizer/communicator_mpi_inline_impl.cc
+++ b/src/synchronizer/communicator_mpi_inline_impl.cc
@@ -1,460 +1,459 @@
 /**
- * @file   static_communicator_mpi.cc
+ * @file   communicator_mpi_inline_impl.cc
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
- * @date creation: Sun Sep 26 2010
- * @date last modification: Thu Jan 21 2016
+ * @date creation: Tue Nov 07 2017
+ * @date last modification: Mon Dec 18 2017
  *
  * @brief  StaticCommunicatorMPI implementation
  *
  * @section LICENSE
  *
- * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
- * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
- * Solides)
+ * 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
+ * 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
+ * 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_iterators.hh"
 #include "communicator.hh"
 #include "mpi_communicator_data.hh"
 /* -------------------------------------------------------------------------- */
 #include <memory>
 #include <type_traits>
 #include <unordered_map>
 #include <vector>
 /* -------------------------------------------------------------------------- */
 #include <mpi.h>
 /* -------------------------------------------------------------------------- */
 
 #if (defined(__GNUC__) || defined(__GNUG__))
 #if AKA_GCC_VERSION < 60000
 namespace std {
 template <> struct hash<akantu::SynchronizerOperation> {
   using argument_type = akantu::SynchronizerOperation;
   size_t operator()(const argument_type & e) const noexcept {
     auto ue = underlying_type_t<argument_type>(e);
     return uh(ue);
   }
 
 private:
   const hash<underlying_type_t<argument_type>> uh{};
 };
 } // namespace std
 #endif
 #endif
 
 namespace akantu {
 
 class CommunicationRequestMPI : public InternalCommunicationRequest {
 public:
   CommunicationRequestMPI(UInt source, UInt dest)
       : InternalCommunicationRequest(source, dest),
         request(std::make_unique<MPI_Request>()) {}
   MPI_Request & getMPIRequest() { return *request; };
 
 private:
   std::unique_ptr<MPI_Request> request;
 };
 
 namespace {
   template <typename T> inline MPI_Datatype getMPIDatatype();
   MPI_Op getMPISynchronizerOperation(const SynchronizerOperation & op) {
     std::unordered_map<SynchronizerOperation, MPI_Op> _operations{
         {SynchronizerOperation::_sum, MPI_SUM},
         {SynchronizerOperation::_min, MPI_MIN},
         {SynchronizerOperation::_max, MPI_MAX},
         {SynchronizerOperation::_prod, MPI_PROD},
         {SynchronizerOperation::_land, MPI_LAND},
         {SynchronizerOperation::_band, MPI_BAND},
         {SynchronizerOperation::_lor, MPI_LOR},
         {SynchronizerOperation::_bor, MPI_BOR},
         {SynchronizerOperation::_lxor, MPI_LXOR},
         {SynchronizerOperation::_bxor, MPI_BXOR},
         {SynchronizerOperation::_min_loc, MPI_MINLOC},
         {SynchronizerOperation::_max_loc, MPI_MAXLOC},
         {SynchronizerOperation::_null, MPI_OP_NULL}};
     return _operations[op];
   }
 
   template <typename T> MPI_Datatype inline getMPIDatatype() {
     return MPI_DATATYPE_NULL;
   }
 
 #define SPECIALIZE_MPI_DATATYPE(type, mpi_type)                                \
   template <> MPI_Datatype inline getMPIDatatype<type>() { return mpi_type; }
 
 #define COMMA ,
   SPECIALIZE_MPI_DATATYPE(char, MPI_CHAR)
   SPECIALIZE_MPI_DATATYPE(float, MPI_FLOAT)
   SPECIALIZE_MPI_DATATYPE(double, MPI_DOUBLE)
   SPECIALIZE_MPI_DATATYPE(long double, MPI_LONG_DOUBLE)
   SPECIALIZE_MPI_DATATYPE(signed int, MPI_INT)
   SPECIALIZE_MPI_DATATYPE(NodeType, getMPIDatatype<Int>())
   SPECIALIZE_MPI_DATATYPE(unsigned int, MPI_UNSIGNED)
   SPECIALIZE_MPI_DATATYPE(signed long int, MPI_LONG)
   SPECIALIZE_MPI_DATATYPE(unsigned long int, MPI_UNSIGNED_LONG)
   SPECIALIZE_MPI_DATATYPE(signed long long int, MPI_LONG_LONG)
   SPECIALIZE_MPI_DATATYPE(unsigned long long int, MPI_UNSIGNED_LONG_LONG)
   SPECIALIZE_MPI_DATATYPE(SCMinMaxLoc<double COMMA int>, MPI_DOUBLE_INT)
   SPECIALIZE_MPI_DATATYPE(SCMinMaxLoc<float COMMA int>, MPI_FLOAT_INT)
   SPECIALIZE_MPI_DATATYPE(bool, MPI_CXX_BOOL)
 
   inline int getMPISource(int src) {
     if (src == _any_source)
       return MPI_ANY_SOURCE;
     return src;
   }
 
   decltype(auto) convertRequests(std::vector<CommunicationRequest> & requests) {
     std::vector<MPI_Request> mpi_requests(requests.size());
 
     for (auto && request_pair : zip(requests, mpi_requests)) {
       auto && req = std::get<0>(request_pair);
       auto && mpi_req = std::get<1>(request_pair);
       mpi_req = dynamic_cast<CommunicationRequestMPI &>(req.getInternal())
                     .getMPIRequest();
     }
     return mpi_requests;
   }
 
 } // namespace
 
 // this is ugly but shorten the code a lot
 #define MPIDATA                                                                \
   (*reinterpret_cast<MPICommunicatorData *>(communicator_data.get()))
 
 /* -------------------------------------------------------------------------- */
 /* Implementation                                                             */
 /* -------------------------------------------------------------------------- */
 
 /* -------------------------------------------------------------------------- */
 Communicator::Communicator(int & /*argc*/, char **& /*argv*/,
                            const private_member & /*unused*/)
     : communicator_data(std::make_unique<MPICommunicatorData>()) {
   prank = MPIDATA.rank();
   psize = MPIDATA.size();
 }
 
 /* -------------------------------------------------------------------------- */
 template <typename T>
 void Communicator::sendImpl(const T * buffer, Int size, Int receiver, Int tag,
                             const CommunicationMode & mode) const {
   MPI_Comm communicator = MPIDATA.getMPICommunicator();
   MPI_Datatype type = getMPIDatatype<T>();
 
   switch (mode) {
   case CommunicationMode::_auto:
     MPI_Send(buffer, size, type, receiver, tag, communicator);
     break;
   case CommunicationMode::_synchronous:
     MPI_Ssend(buffer, size, type, receiver, tag, communicator);
     break;
   case CommunicationMode::_ready:
     MPI_Rsend(buffer, size, type, receiver, tag, communicator);
     break;
   }
 }
 
 /* -------------------------------------------------------------------------- */
 template <typename T>
 void Communicator::receiveImpl(T * buffer, Int size, Int sender,
                                Int tag) const {
   MPI_Comm communicator = MPIDATA.getMPICommunicator();
   MPI_Status status;
   MPI_Datatype type = getMPIDatatype<T>();
   MPI_Recv(buffer, size, type, getMPISource(sender), tag, communicator,
            &status);
 }
 
 /* -------------------------------------------------------------------------- */
 template <typename T>
 CommunicationRequest
 Communicator::asyncSendImpl(const T * buffer, Int size, Int receiver, Int tag,
                             const CommunicationMode & mode) const {
   MPI_Comm communicator = MPIDATA.getMPICommunicator();
   auto * request = new CommunicationRequestMPI(prank, receiver);
   MPI_Request & req = request->getMPIRequest();
 
   MPI_Datatype type = getMPIDatatype<T>();
 
   switch (mode) {
   case CommunicationMode::_auto:
     MPI_Isend(buffer, size, type, receiver, tag, communicator, &req);
     break;
   case CommunicationMode::_synchronous:
     MPI_Issend(buffer, size, type, receiver, tag, communicator, &req);
     break;
   case CommunicationMode::_ready:
     MPI_Irsend(buffer, size, type, receiver, tag, communicator, &req);
     break;
   }
   return std::shared_ptr<InternalCommunicationRequest>(request);
 }
 
 /* -------------------------------------------------------------------------- */
 template <typename T>
 CommunicationRequest Communicator::asyncReceiveImpl(T * buffer, Int size,
                                                     Int sender, Int tag) const {
   MPI_Comm communicator = MPIDATA.getMPICommunicator();
   auto * request = new CommunicationRequestMPI(sender, prank);
   MPI_Datatype type = getMPIDatatype<T>();
 
   MPI_Request & req = request->getMPIRequest();
   MPI_Irecv(buffer, size, type, getMPISource(sender), tag, communicator, &req);
   return std::shared_ptr<InternalCommunicationRequest>(request);
 }
 
 /* -------------------------------------------------------------------------- */
 template <typename T>
 void Communicator::probe(Int sender, Int tag,
                          CommunicationStatus & status) const {
   MPI_Comm communicator = MPIDATA.getMPICommunicator();
   MPI_Status mpi_status;
   MPI_Probe(getMPISource(sender), tag, communicator, &mpi_status);
 
   MPI_Datatype type = getMPIDatatype<T>();
   int count;
   MPI_Get_count(&mpi_status, type, &count);
 
   status.setSource(mpi_status.MPI_SOURCE);
   status.setTag(mpi_status.MPI_TAG);
   status.setSize(count);
 }
 
 /* -------------------------------------------------------------------------- */
 template <typename T>
 bool Communicator::asyncProbe(Int sender, Int tag,
                               CommunicationStatus & status) const {
   MPI_Comm communicator = MPIDATA.getMPICommunicator();
   MPI_Status mpi_status;
   int test;
   MPI_Iprobe(getMPISource(sender), tag, communicator, &test, &mpi_status);
 
   if (not test)
     return false;
 
   MPI_Datatype type = getMPIDatatype<T>();
   int count;
   MPI_Get_count(&mpi_status, type, &count);
 
   status.setSource(mpi_status.MPI_SOURCE);
   status.setTag(mpi_status.MPI_TAG);
   status.setSize(count);
   return true;
 }
 
 /* -------------------------------------------------------------------------- */
 bool Communicator::test(CommunicationRequest & request) const {
   MPI_Status status;
   int flag;
   auto & req_mpi =
       dynamic_cast<CommunicationRequestMPI &>(request.getInternal());
   MPI_Request & req = req_mpi.getMPIRequest();
 
 #if !defined(AKANTU_NDEBUG)
   int ret =
 #endif
       MPI_Test(&req, &flag, &status);
 
   AKANTU_DEBUG_ASSERT(ret == MPI_SUCCESS, "Error in MPI_Test.");
   return (flag != 0);
 }
 
 /* -------------------------------------------------------------------------- */
 bool Communicator::testAll(std::vector<CommunicationRequest> & requests) const {
   int are_finished;
   auto && mpi_requests = convertRequests(requests);
   MPI_Testall(mpi_requests.size(), mpi_requests.data(), &are_finished,
               MPI_STATUSES_IGNORE);
   return are_finished != 0 ? true : false;
 }
 
 /* -------------------------------------------------------------------------- */
 void Communicator::wait(CommunicationRequest & request) const {
   MPI_Status status;
   auto & req_mpi =
       dynamic_cast<CommunicationRequestMPI &>(request.getInternal());
   MPI_Request & req = req_mpi.getMPIRequest();
   MPI_Wait(&req, &status);
 }
 
 /* -------------------------------------------------------------------------- */
 void Communicator::waitAll(std::vector<CommunicationRequest> & requests) const {
   auto && mpi_requests = convertRequests(requests);
   MPI_Waitall(mpi_requests.size(), mpi_requests.data(), MPI_STATUSES_IGNORE);
 }
 
 /* -------------------------------------------------------------------------- */
 UInt Communicator::waitAny(std::vector<CommunicationRequest> & requests) const {
   auto && mpi_requests = convertRequests(requests);
 
   int pos;
   MPI_Waitany(mpi_requests.size(), mpi_requests.data(), &pos,
               MPI_STATUSES_IGNORE);
 
   if (pos != MPI_UNDEFINED) {
     return pos;
   } else {
     return UInt(-1);
   }
 }
 
 /* -------------------------------------------------------------------------- */
 void Communicator::barrier() const {
   MPI_Comm communicator = MPIDATA.getMPICommunicator();
   MPI_Barrier(communicator);
 }
 
 /* -------------------------------------------------------------------------- */
 CommunicationRequest Communicator::asyncBarrier() const {
   MPI_Comm communicator = MPIDATA.getMPICommunicator();
   auto * request = new CommunicationRequestMPI(0, 0);
 
   MPI_Request & req = request->getMPIRequest();
   MPI_Ibarrier(communicator, &req);
 
   return std::shared_ptr<InternalCommunicationRequest>(request);
 }
 
 /* -------------------------------------------------------------------------- */
 template <typename T>
 void Communicator::reduceImpl(T * values, int nb_values,
                               const SynchronizerOperation & op,
                               int root) const {
   MPI_Comm communicator = MPIDATA.getMPICommunicator();
   MPI_Datatype type = getMPIDatatype<T>();
 
   MPI_Reduce(MPI_IN_PLACE, values, nb_values, type,
              getMPISynchronizerOperation(op), root, communicator);
 }
 
 /* -------------------------------------------------------------------------- */
 template <typename T>
 void Communicator::allReduceImpl(T * values, int nb_values,
                                  const SynchronizerOperation & op) const {
   MPI_Comm communicator = MPIDATA.getMPICommunicator();
   MPI_Datatype type = getMPIDatatype<T>();
 
   MPI_Allreduce(MPI_IN_PLACE, values, nb_values, type,
                 getMPISynchronizerOperation(op), communicator);
 }
 
 /* -------------------------------------------------------------------------- */
 template <typename T>
 void Communicator::allGatherImpl(T * values, int nb_values) const {
   MPI_Comm communicator = MPIDATA.getMPICommunicator();
   MPI_Datatype type = getMPIDatatype<T>();
 
   MPI_Allgather(MPI_IN_PLACE, nb_values, type, values, nb_values, type,
                 communicator);
 }
 
 /* -------------------------------------------------------------------------- */
 template <typename T>
 void Communicator::allGatherVImpl(T * values, int * nb_values) const {
   MPI_Comm communicator = MPIDATA.getMPICommunicator();
   std::vector<int> displs(psize);
   displs[0] = 0;
   for (int i = 1; i < psize; ++i) {
     displs[i] = displs[i - 1] + nb_values[i - 1];
   }
 
   MPI_Datatype type = getMPIDatatype<T>();
   MPI_Allgatherv(MPI_IN_PLACE, *nb_values, type, values, nb_values,
                  displs.data(), type, communicator);
 }
 
 /* -------------------------------------------------------------------------- */
 template <typename T>
 void Communicator::gatherImpl(T * values, int nb_values, int root) const {
   MPI_Comm communicator = MPIDATA.getMPICommunicator();
   T *send_buf = nullptr, *recv_buf = nullptr;
   if (prank == root) {
     send_buf = (T *)MPI_IN_PLACE;
     recv_buf = values;
   } else {
     send_buf = values;
   }
 
   MPI_Datatype type = getMPIDatatype<T>();
   MPI_Gather(send_buf, nb_values, type, recv_buf, nb_values, type, root,
              communicator);
 }
 
 /* -------------------------------------------------------------------------- */
 template <typename T>
 void Communicator::gatherImpl(T * values, int nb_values, T * gathered,
                               int nb_gathered) const {
   MPI_Comm communicator = MPIDATA.getMPICommunicator();
   T * send_buf = values;
   T * recv_buf = gathered;
 
   if (nb_gathered == 0)
     nb_gathered = nb_values;
 
   MPI_Datatype type = getMPIDatatype<T>();
   MPI_Gather(send_buf, nb_values, type, recv_buf, nb_gathered, type,
              this->prank, communicator);
 }
 
 /* -------------------------------------------------------------------------- */
 template <typename T>
 void Communicator::gatherVImpl(T * values, int * nb_values, int root) const {
   MPI_Comm communicator = MPIDATA.getMPICommunicator();
   int * displs = nullptr;
   if (prank == root) {
     displs = new int[psize];
     displs[0] = 0;
     for (int i = 1; i < psize; ++i) {
       displs[i] = displs[i - 1] + nb_values[i - 1];
     }
   }
 
   T *send_buf = nullptr, *recv_buf = nullptr;
   if (prank == root) {
     send_buf = (T *)MPI_IN_PLACE;
     recv_buf = values;
   } else
     send_buf = values;
 
   MPI_Datatype type = getMPIDatatype<T>();
 
   MPI_Gatherv(send_buf, *nb_values, type, recv_buf, nb_values, displs, type,
               root, communicator);
 
   if (prank == root) {
     delete[] displs;
   }
 }
 
 /* -------------------------------------------------------------------------- */
 template <typename T>
 void Communicator::broadcastImpl(T * values, int nb_values, int root) const {
   MPI_Comm communicator = MPIDATA.getMPICommunicator();
   MPI_Datatype type = getMPIDatatype<T>();
   MPI_Bcast(values, nb_values, type, root, communicator);
 }
 
 /* -------------------------------------------------------------------------- */
 int Communicator::getMaxTag() const { return MPIDATA.getMaxTag(); }
 int Communicator::getMinTag() const { return 0; }
 
 /* -------------------------------------------------------------------------- */
 
 } // namespace akantu
diff --git a/src/synchronizer/data_accessor.cc b/src/synchronizer/data_accessor.cc
index 3a51a7016..e80b72ce3 100644
--- a/src/synchronizer/data_accessor.cc
+++ b/src/synchronizer/data_accessor.cc
@@ -1,155 +1,154 @@
 /**
  * @file   data_accessor.cc
  *
  * @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Fri Jun 18 2010
- * @date last modification: Sun Oct 19 2014
+ * @date last modification: Tue Feb 20 2018
  *
  * @brief  data accessors constructor functions
  *
  * @section LICENSE
  *
- * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
- * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
- * Solides)
+ * 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
+ * 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
+ * A PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 #include "data_accessor.hh"
 #include "fe_engine.hh"
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 template <typename T, bool pack_helper>
 void DataAccessor<Element>::packUnpackNodalDataHelper(
     Array<T> & data, CommunicationBuffer & buffer,
     const Array<Element> & elements, const Mesh & mesh) {
   UInt nb_component = data.getNbComponent();
   UInt nb_nodes_per_element = 0;
 
   ElementType current_element_type = _not_defined;
   GhostType current_ghost_type = _casper;
   UInt * conn = nullptr;
 
   for (auto & el : elements) {
     if (el.type != current_element_type ||
         el.ghost_type != current_ghost_type) {
       current_element_type = el.type;
       current_ghost_type = el.ghost_type;
       conn = mesh.getConnectivity(el.type, el.ghost_type).storage();
       nb_nodes_per_element = Mesh::getNbNodesPerElement(el.type);
     }
 
     UInt el_offset = el.element * nb_nodes_per_element;
     for (UInt n = 0; n < nb_nodes_per_element; ++n) {
       UInt offset_conn = conn[el_offset + n];
       Vector<T> data_vect(data.storage() + offset_conn * nb_component,
                           nb_component);
 
       if (pack_helper)
         buffer << data_vect;
       else
         buffer >> data_vect;
     }
   }
 }
 
 /* ------------------------------------------------------------------------ */
 template <typename T, bool pack_helper>
 void DataAccessor<Element>::packUnpackElementalDataHelper(
     ElementTypeMapArray<T> & data_to_pack, CommunicationBuffer & buffer,
     const Array<Element> & element, bool per_quadrature_point_data,
     const FEEngine & fem) {
   ElementType current_element_type = _not_defined;
   GhostType current_ghost_type = _casper;
   UInt nb_quad_per_elem = 0;
   UInt nb_component = 0;
 
   Array<T> * vect = nullptr;
 
   for (auto & el : element) {
     if (el.type != current_element_type ||
         el.ghost_type != current_ghost_type) {
       current_element_type = el.type;
       current_ghost_type = el.ghost_type;
       vect = &data_to_pack(el.type, el.ghost_type);
 
       nb_quad_per_elem =
           per_quadrature_point_data
               ? fem.getNbIntegrationPoints(el.type, el.ghost_type)
               : 1;
       nb_component = vect->getNbComponent();
     }
 
     Vector<T> data(vect->storage() +
                        el.element * nb_component * nb_quad_per_elem,
                    nb_component * nb_quad_per_elem);
     if (pack_helper)
       buffer << data;
     else
       buffer >> data;
   }
 }
 
 /* -------------------------------------------------------------------------- */
 template <typename T, bool pack_helper>
 void DataAccessor<UInt>::packUnpackDOFDataHelper(Array<T> & data,
                                                  CommunicationBuffer & buffer,
                                                  const Array<UInt> & dofs) {
   T * data_ptr = data.storage();
   for (const auto & dof : dofs) {
     if (pack_helper)
       buffer << data_ptr[dof];
     else
       buffer >> data_ptr[dof];
   }
 }
 
 /* -------------------------------------------------------------------------- */
 #define DECLARE_HELPERS(T)                                                     \
   template void DataAccessor<Element>::packUnpackNodalDataHelper<T, false>(    \
       Array<T> & data, CommunicationBuffer & buffer,                           \
       const Array<Element> & elements, const Mesh & mesh);                     \
   template void DataAccessor<Element>::packUnpackNodalDataHelper<T, true>(     \
       Array<T> & data, CommunicationBuffer & buffer,                           \
       const Array<Element> & elements, const Mesh & mesh);                     \
   template void                                                                \
   DataAccessor<Element>::packUnpackElementalDataHelper<T, false>(              \
       ElementTypeMapArray<T> & data_to_pack, CommunicationBuffer & buffer,     \
       const Array<Element> & element, bool per_quadrature_point_data,          \
       const FEEngine & fem);                                                   \
   template void DataAccessor<Element>::packUnpackElementalDataHelper<T, true>( \
       ElementTypeMapArray<T> & data_to_pack, CommunicationBuffer & buffer,     \
       const Array<Element> & element, bool per_quadrature_point_data,          \
       const FEEngine & fem);                                                   \
   template void DataAccessor<UInt>::packUnpackDOFDataHelper<T, true>(          \
       Array<T> & data, CommunicationBuffer & buffer,                           \
       const Array<UInt> & dofs);                                               \
   template void DataAccessor<UInt>::packUnpackDOFDataHelper<T, false>(         \
       Array<T> & data, CommunicationBuffer & buffer, const Array<UInt> & dofs)
 
 /* -------------------------------------------------------------------------- */
 DECLARE_HELPERS(Real);
 DECLARE_HELPERS(UInt);
 DECLARE_HELPERS(bool);
 /* -------------------------------------------------------------------------- */
 
 } // akantu
diff --git a/src/synchronizer/data_accessor.hh b/src/synchronizer/data_accessor.hh
index cebcb66b3..78c956279 100644
--- a/src/synchronizer/data_accessor.hh
+++ b/src/synchronizer/data_accessor.hh
@@ -1,279 +1,278 @@
 /**
  * @file   data_accessor.hh
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Wed Sep 01 2010
- * @date last modification: Tue Dec 08 2015
+ * @date last modification: Sun Feb 04 2018
  *
  * @brief  Interface of accessors for pack_unpack system
  *
  * @section LICENSE
  *
- * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
- * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
- * Solides)
+ * 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
+ * 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
+ * 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 "communication_buffer.hh"
 #include "element.hh"
 /* -------------------------------------------------------------------------- */
 
 #ifndef __AKANTU_DATA_ACCESSOR_HH__
 #define __AKANTU_DATA_ACCESSOR_HH__
 
 namespace akantu {
 class FEEngine;
 } // akantu
 
 namespace akantu {
 
 class DataAccessorBase {
 public:
   DataAccessorBase() = default;
   virtual ~DataAccessorBase() = default;
 };
 
 template <class T> class DataAccessor : public virtual DataAccessorBase {
   /* ------------------------------------------------------------------------ */
   /* Constructors/Destructors                                                 */
   /* ------------------------------------------------------------------------ */
 public:
   DataAccessor() = default;
   ~DataAccessor() override = default;
 
   /* ------------------------------------------------------------------------ */
   /* Methods                                                                  */
   /* ------------------------------------------------------------------------ */
 public:
   /**
    * @brief get  the number of  data to exchange  for a given array of T
    * (elements or dofs) and a given akantu::SynchronizationTag
    */
   virtual UInt getNbData(const Array<T> & elements,
                          const SynchronizationTag & tag) const = 0;
 
   /**
    * @brief pack the data for a given array of T (elements or dofs) and a given
    * akantu::SynchronizationTag
    */
   virtual void packData(CommunicationBuffer & buffer, const Array<T> & element,
                         const SynchronizationTag & tag) const = 0;
 
   /**
    * @brief unpack the data for a given array of T (elements or dofs) and a
    * given akantu::SynchronizationTag
    */
   virtual void unpackData(CommunicationBuffer & buffer,
                           const Array<T> & element,
                           const SynchronizationTag & tag) = 0;
 };
 
 /* -------------------------------------------------------------------------- */
 /* Specialization                                                             */
 /* -------------------------------------------------------------------------- */
 template <> class DataAccessor<Element> : public virtual DataAccessorBase {
 public:
   DataAccessor() = default;
   ~DataAccessor() override = default;
 
   virtual UInt getNbData(const Array<Element> & elements,
                          const SynchronizationTag & tag) const = 0;
   virtual void packData(CommunicationBuffer & buffer,
                         const Array<Element> & element,
                         const SynchronizationTag & tag) const = 0;
   virtual void unpackData(CommunicationBuffer & buffer,
                           const Array<Element> & element,
                           const SynchronizationTag & tag) = 0;
 
   /* ------------------------------------------------------------------------ */
 public:
   template <typename T, bool pack_helper>
   static void
   packUnpackNodalDataHelper(Array<T> & data, CommunicationBuffer & buffer,
                             const Array<Element> & elements, const Mesh & mesh);
 
   /* ------------------------------------------------------------------------ */
   template <typename T, bool pack_helper>
   static void packUnpackElementalDataHelper(
       ElementTypeMapArray<T> & data_to_pack, CommunicationBuffer & buffer,
       const Array<Element> & element, bool per_quadrature_point_data,
       const FEEngine & fem);
 
   /* ------------------------------------------------------------------------ */
   template <typename T>
   static void
   packNodalDataHelper(const Array<T> & data, CommunicationBuffer & buffer,
                       const Array<Element> & elements, const Mesh & mesh) {
     packUnpackNodalDataHelper<T, true>(const_cast<Array<T> &>(data), buffer,
                                        elements, mesh);
   }
 
   template <typename T>
   static inline void
   unpackNodalDataHelper(Array<T> & data, CommunicationBuffer & buffer,
                         const Array<Element> & elements, const Mesh & mesh) {
     packUnpackNodalDataHelper<T, false>(data, buffer, elements, mesh);
   }
 
   /* ------------------------------------------------------------------------ */
   template <typename T>
   static inline void
   packElementalDataHelper(const ElementTypeMapArray<T> & data_to_pack,
                           CommunicationBuffer & buffer,
                           const Array<Element> & elements,
                           bool per_quadrature_point, const FEEngine & fem) {
     packUnpackElementalDataHelper<T, true>(
         const_cast<ElementTypeMapArray<T> &>(data_to_pack), buffer, elements,
         per_quadrature_point, fem);
   }
 
   template <typename T>
   static inline void
   unpackElementalDataHelper(ElementTypeMapArray<T> & data_to_unpack,
                             CommunicationBuffer & buffer,
                             const Array<Element> & elements,
                             bool per_quadrature_point, const FEEngine & fem) {
     packUnpackElementalDataHelper<T, false>(data_to_unpack, buffer, elements,
                                             per_quadrature_point, fem);
   }
 };
 
 /* -------------------------------------------------------------------------- */
 /* -------------------------------------------------------------------------- */
 template <> class DataAccessor<UInt> : public virtual DataAccessorBase {
 public:
   DataAccessor() = default;
   ~DataAccessor() override = default;
 
   virtual UInt getNbData(const Array<UInt> & elements,
                          const SynchronizationTag & tag) const = 0;
   virtual void packData(CommunicationBuffer & buffer,
                         const Array<UInt> & element,
                         const SynchronizationTag & tag) const = 0;
   virtual void unpackData(CommunicationBuffer & buffer,
                           const Array<UInt> & element,
                           const SynchronizationTag & tag) = 0;
   /* ------------------------------------------------------------------------ */
 public:
   template <typename T, bool pack_helper>
   static void packUnpackDOFDataHelper(Array<T> & data,
                                       CommunicationBuffer & buffer,
                                       const Array<UInt> & dofs);
 
   template <typename T>
   static inline void packDOFDataHelper(const Array<T> & data_to_pack,
                                        CommunicationBuffer & buffer,
                                        const Array<UInt> & dofs) {
     packUnpackDOFDataHelper<T, true>(const_cast<Array<T> &>(data_to_pack),
                                      buffer, dofs);
   }
 
   template <typename T>
   static inline void unpackDOFDataHelper(Array<T> & data_to_unpack,
                                          CommunicationBuffer & buffer,
                                          const Array<UInt> & dofs) {
     packUnpackDOFDataHelper<T, false>(data_to_unpack, buffer, dofs);
   }
 };
 
 /* -------------------------------------------------------------------------- */
 template <typename T> class AddOperation {
 public:
   inline T operator()(T & a, T & b) { return a + b; };
 };
 
 template <typename T> class IdentityOperation {
 public:
   inline T & operator()(T &, T & b) { return b; };
 };
 /* -------------------------------------------------------------------------- */
 
 /* -------------------------------------------------------------------------- */
 template <template <class> class Op, class T>
 class ReduceUIntDataAccessor : public virtual DataAccessor<UInt> {
   /* ------------------------------------------------------------------------ */
   /* Constructors/Destructors                                                 */
   /* ------------------------------------------------------------------------ */
 public:
   ReduceUIntDataAccessor(Array<T> & data, const SynchronizationTag & tag)
       : data(data), tag(tag) {}
 
   ~ReduceUIntDataAccessor() override = default;
 
   /* ------------------------------------------------------------------------ */
   /* Methods                                                                  */
   /* ------------------------------------------------------------------------ */
 public:
   /* ------------------------------------------------------------------------ */
   UInt getNbData(const Array<UInt> & elements,
                  const SynchronizationTag & tag) const override {
     if (tag != this->tag)
       return 0;
 
     Vector<T> tmp(data.getNbComponent());
     return elements.size() * CommunicationBuffer::sizeInBuffer(tmp);
   }
 
   /* ------------------------------------------------------------------------ */
   void packData(CommunicationBuffer & buffer, const Array<UInt> & elements,
                 const SynchronizationTag & tag) const override {
     if (tag != this->tag)
       return;
 
     auto data_it = data.begin(data.getNbComponent());
     for (auto el : elements) {
       buffer << Vector<T>(data_it[el]);
     }
   }
 
   /* ------------------------------------------------------------------------ */
   void unpackData(CommunicationBuffer & buffer, const Array<UInt> & elements,
                   const SynchronizationTag & tag) override {
     if (tag != this->tag)
       return;
 
     auto data_it = data.begin(data.getNbComponent());
     for (auto el : elements) {
       Vector<T> unpacked(data.getNbComponent());
       Vector<T> vect(data_it[el]);
       buffer >> unpacked;
 
       vect = oper(vect, unpacked);
     }
   }
 
 protected:
   /// data to (un)pack
   Array<T> & data;
 
   /// Tag to consider
   SynchronizationTag tag;
 
   /// reduction operator
   Op<Vector<T>> oper;
 };
 
 /* -------------------------------------------------------------------------- */
 template <class T>
 using SimpleUIntDataAccessor = ReduceUIntDataAccessor<IdentityOperation, T>;
 
 } // akantu
 
 #endif /* __AKANTU_DATA_ACCESSOR_HH__ */
diff --git a/src/synchronizer/dof_synchronizer.cc b/src/synchronizer/dof_synchronizer.cc
index 944332113..ed0a9bcf2 100644
--- a/src/synchronizer/dof_synchronizer.cc
+++ b/src/synchronizer/dof_synchronizer.cc
@@ -1,280 +1,279 @@
 /**
  * @file   dof_synchronizer.cc
  *
  * @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Fri Jun 17 2011
- * @date last modification: Wed Oct 21 2015
+ * @date last modification: Tue Feb 06 2018
  *
  * @brief  DOF synchronizing object implementation
  *
  * @section LICENSE
  *
- * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
- * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
- * Solides)
+ * 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
+ * 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
+ * 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 "dof_synchronizer.hh"
 #include "aka_iterators.hh"
 #include "dof_manager_default.hh"
 #include "mesh.hh"
 #include "node_synchronizer.hh"
 /* -------------------------------------------------------------------------- */
 #include <algorithm>
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 /**
  * A DOFSynchronizer needs a mesh and the number of degrees of freedom
  * per node to be created. In the constructor computes the local and global dof
  * number for each dof. The member
  * proc_informations (std vector) is resized with the number of mpi
  * processes. Each entry in the vector is a PerProcInformations object
  * that contains the interactions of the current mpi process (prank) with the
  * mpi process corresponding to the position of that entry. Every
  * ProcInformations object contains one array with the dofs that have
  * to be sent to prank and a second one with dofs that willl be received form
  * prank.
  * This information is needed for the asychronous communications. The
  * constructor sets up this information.
  */
 DOFSynchronizer::DOFSynchronizer(DOFManagerDefault & dof_manager, const ID & id,
                                  MemoryID memory_id)
     : SynchronizerImpl<UInt>(dof_manager.getCommunicator(), id, memory_id),
       root(0), dof_manager(dof_manager),
       root_dofs(0, 1, "dofs-to-receive-from-master"), dof_changed(true) {
   std::vector<ID> dof_ids = dof_manager.getDOFIDs();
 
   // Transfers nodes to global equation numbers in new schemes
   for (const ID & dof_id : dof_ids) {
     registerDOFs(dof_id);
   }
 
   this->initScatterGatherCommunicationScheme();
 }
 
 /* -------------------------------------------------------------------------- */
 DOFSynchronizer::~DOFSynchronizer() = default;
 
 /* -------------------------------------------------------------------------- */
 void DOFSynchronizer::registerDOFs(const ID & dof_id) {
   if (this->nb_proc == 1)
     return;
 
   if (dof_manager.getSupportType(dof_id) != _dst_nodal)
     return;
 
   using const_scheme_iterator = Communications<UInt>::const_scheme_iterator;
 
   const auto equation_numbers = dof_manager.getLocalEquationNumbers(dof_id);
 
   const auto & associated_nodes = dof_manager.getDOFsAssociatedNodes(dof_id);
   const auto & node_synchronizer = dof_manager.getMesh().getNodeSynchronizer();
   const auto & node_communications = node_synchronizer.getCommunications();
 
   auto transcode_node_to_global_dof_scheme =
       [this, &associated_nodes,
        &equation_numbers](const_scheme_iterator it, const_scheme_iterator end,
                           const CommunicationSendRecv & sr) -> void {
     for (; it != end; ++it) {
       auto & scheme = communications.createScheme(it->first, sr);
 
       const auto & node_scheme = it->second;
       for (auto & node : node_scheme) {
         auto an_begin = associated_nodes.begin();
         auto an_it = an_begin;
         auto an_end = associated_nodes.end();
 
         std::vector<UInt> global_dofs_per_node;
         while ((an_it = std::find(an_it, an_end, node)) != an_end) {
           UInt pos = an_it - an_begin;
           UInt local_eq_num = equation_numbers(pos);
           UInt global_eq_num =
               dof_manager.localToGlobalEquationNumber(local_eq_num);
           global_dofs_per_node.push_back(global_eq_num);
           ++an_it;
         }
 
         std::sort(global_dofs_per_node.begin(), global_dofs_per_node.end());
         std::transform(global_dofs_per_node.begin(), global_dofs_per_node.end(),
                        global_dofs_per_node.begin(), [this](UInt g) -> UInt {
                          UInt l = dof_manager.globalToLocalEquationNumber(g);
                          return l;
                        });
         for (auto & leqnum : global_dofs_per_node) {
           scheme.push_back(leqnum);
         }
       }
     }
   };
 
   for (auto sr_it = send_recv_t::begin(); sr_it != send_recv_t::end();
        ++sr_it) {
     auto ncs_it = node_communications.begin_scheme(*sr_it);
     auto ncs_end = node_communications.end_scheme(*sr_it);
 
     transcode_node_to_global_dof_scheme(ncs_it, ncs_end, *sr_it);
   }
 
   dof_changed = true;
 }
 
 /* -------------------------------------------------------------------------- */
 void DOFSynchronizer::initScatterGatherCommunicationScheme() {
   AKANTU_DEBUG_IN();
 
   if (this->nb_proc == 1) {
     dof_changed = false;
     AKANTU_DEBUG_OUT();
     return;
   }
 
   UInt nb_dofs = dof_manager.getLocalSystemSize();
 
   this->root_dofs.clear();
   this->master_receive_dofs.clear();
 
   Array<UInt> dofs_to_send;
   for (UInt n = 0; n < nb_dofs; ++n) {
     if (dof_manager.isLocalOrMasterDOF(n)) {
       auto & receive_per_proc = master_receive_dofs[this->root];
       UInt global_dof = dof_manager.localToGlobalEquationNumber(n);
 
       root_dofs.push_back(n);
       receive_per_proc.push_back(global_dof);
       dofs_to_send.push_back(global_dof);
     }
   }
 
   if (this->rank == UInt(this->root)) {
     Array<UInt> nb_dof_per_proc(this->nb_proc);
     communicator.gather(dofs_to_send.size(), nb_dof_per_proc);
 
     std::vector<CommunicationRequest> requests;
     for (UInt p = 0; p < nb_proc; ++p) {
       if (p == UInt(this->root))
         continue;
 
       auto & receive_per_proc = master_receive_dofs[p];
       receive_per_proc.resize(nb_dof_per_proc(p));
       if (nb_dof_per_proc(p) != 0)
         requests.push_back(communicator.asyncReceive(
             receive_per_proc, p,
             Tag::genTag(p, 0, Tag::_GATHER_INITIALIZATION, this->hash_id)));
     }
 
     communicator.waitAll(requests);
     communicator.freeCommunicationRequest(requests);
   } else {
     communicator.gather(dofs_to_send.size(), this->root);
     AKANTU_DEBUG(dblDebug,
                  "I have " << nb_dofs << " dofs (" << dofs_to_send.size()
                            << " to send to master proc");
 
     if (dofs_to_send.size() != 0)
       communicator.send(dofs_to_send, this->root,
                         Tag::genTag(this->rank, 0, Tag::_GATHER_INITIALIZATION,
                                     this->hash_id));
   }
 
   dof_changed = false;
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 bool DOFSynchronizer::hasChanged() {
   communicator.allReduce(dof_changed, SynchronizerOperation::_lor);
   return dof_changed;
 }
 
 /* -------------------------------------------------------------------------- */
 void DOFSynchronizer::onNodesAdded(const Array<UInt> & nodes_list) {
   auto dof_ids = dof_manager.getDOFIDs();
 
   const auto & node_synchronizer = dof_manager.getMesh().getNodeSynchronizer();
   const auto & node_communications = node_synchronizer.getCommunications();
 
   std::set<UInt> relevant_nodes;
   std::map<UInt, std::vector<UInt>> nodes_per_proc[2];
   for (auto sr_it = send_recv_t::begin(); sr_it != send_recv_t::end();
        ++sr_it) {
     auto sit = node_communications.begin_scheme(*sr_it);
     auto send = node_communications.end_scheme(*sr_it);
 
     for (; sit != send; ++sit) {
       auto proc = sit->first;
       const auto & scheme = sit->second;
       for (auto node : nodes_list) {
         if (scheme.find(node) == UInt(-1))
           continue;
         relevant_nodes.insert(node);
         nodes_per_proc[*sr_it][proc].push_back(node);
       }
     }
   }
 
   std::map<UInt, std::vector<UInt>> dofs_per_proc[2];
   for (auto & dof_id : dof_ids) {
     const auto & associated_nodes = dof_manager.getDOFsAssociatedNodes(dof_id);
     const auto & local_equation_numbers =
         dof_manager.getEquationsNumbers(dof_id);
 
     for (auto tuple : zip(associated_nodes, local_equation_numbers)) {
       UInt assoc_node;
       UInt local_eq_num;
       std::tie(assoc_node, local_eq_num) = tuple;
 
       for (auto sr_it = send_recv_t::begin(); sr_it != send_recv_t::end();
            ++sr_it) {
         for (auto & pair : nodes_per_proc[*sr_it]) {
           if (std::find(pair.second.end(), pair.second.end(), assoc_node) !=
               pair.second.end()) {
             dofs_per_proc[*sr_it][pair.first].push_back(local_eq_num);
           }
         }
       }
     }
   }
 
   for (auto sr_it = send_recv_t::begin(); sr_it != send_recv_t::end();
        ++sr_it) {
     for (auto & pair : dofs_per_proc[*sr_it]) {
       std::sort(pair.second.begin(), pair.second.end(),
                 [this](UInt la, UInt lb) -> bool {
                   UInt ga = dof_manager.localToGlobalEquationNumber(la);
                   UInt gb = dof_manager.localToGlobalEquationNumber(lb);
                   return ga < gb;
                 });
 
       auto & scheme = communications.getScheme(pair.first, *sr_it);
       for (auto leq : pair.second) {
         scheme.push_back(leq);
       }
     }
   }
   dof_changed = true;
 }
 
 /* -------------------------------------------------------------------------- */
 
 } // namespace akantu
diff --git a/src/synchronizer/dof_synchronizer.hh b/src/synchronizer/dof_synchronizer.hh
index 8fbd31a28..a5184a9e1 100644
--- a/src/synchronizer/dof_synchronizer.hh
+++ b/src/synchronizer/dof_synchronizer.hh
@@ -1,112 +1,111 @@
 /**
  * @file   dof_synchronizer.hh
  *
  * @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Fri Jun 17 2011
- * @date last modification: Tue Dec 08 2015
+ * @date last modification: Tue Feb 20 2018
  *
  * @brief  Synchronize Array of DOFs
  *
  * @section LICENSE
  *
- * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
- * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
- * Solides)
+ * 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
+ * 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
+ * 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_array.hh"
 #include "aka_common.hh"
 #include "synchronizer_impl.hh"
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 class Mesh;
 class DOFManagerDefault;
 }
 
 #ifndef __AKANTU_DOF_SYNCHRONIZER_HH__
 #define __AKANTU_DOF_SYNCHRONIZER_HH__
 
 namespace akantu {
 
 class DOFSynchronizer : public SynchronizerImpl<UInt> {
   /* ------------------------------------------------------------------------ */
   /* Constructors/Destructors                                                 */
   /* ------------------------------------------------------------------------ */
 public:
   DOFSynchronizer(DOFManagerDefault & dof_manager,
                   const ID & id = "dof_synchronizer", MemoryID memory_id = 0);
   ~DOFSynchronizer() override;
 
   virtual void registerDOFs(const ID & dof_id);
   /* ------------------------------------------------------------------------ */
   /* Methods                                                                  */
   /* ------------------------------------------------------------------------ */
 public:
   template <typename T>
   /// Gather the DOF value on the root proccessor
   void gather(const Array<T> & to_gather, Array<T> & gathered);
 
   /// Gather the DOF value on the root proccessor
   template <typename T> void gather(const Array<T> & to_gather);
 
   /// Scatter a DOF Array form root to all processors
   template <typename T>
   void scatter(Array<T> & scattered, const Array<T> & to_scatter);
 
   /// Scatter a DOF Array form root to all processors
   template <typename T> void scatter(Array<T> & scattered);
 
   template <typename T> void synchronize(Array<T> & vector) const;
 
   template <template <class> class Op, typename T>
   void reduceSynchronize(Array<T> & vector) const;
 
   void onNodesAdded(const Array<UInt> & nodes);
 
 protected:
   /// check if dof changed set on at least one processor
   bool hasChanged();
 
   /// init the scheme for scatter and gather operation, need extra memory
   void initScatterGatherCommunicationScheme();
 
   Int getRank(const UInt & /*node*/) const final { AKANTU_TO_IMPLEMENT(); }
 
 private:
   /// Root processor for scatter/gather operations
   Int root;
 
   /// information on the dofs
   DOFManagerDefault & dof_manager;
 
   /// dofs from root
   Array<UInt> root_dofs;
 
   /// Dofs received from slaves proc (only on master)
   std::map<UInt, Array<UInt>> master_receive_dofs;
 
   bool dof_changed;
 };
 } // akantu
 
 #include "dof_synchronizer_inline_impl.cc"
 
 #endif /* __AKANTU_DOF_SYNCHRONIZER_HH__ */
diff --git a/src/synchronizer/dof_synchronizer_inline_impl.cc b/src/synchronizer/dof_synchronizer_inline_impl.cc
index 9165512ca..1a6cd6d30 100644
--- a/src/synchronizer/dof_synchronizer_inline_impl.cc
+++ b/src/synchronizer/dof_synchronizer_inline_impl.cc
@@ -1,298 +1,297 @@
 /**
  * @file   dof_synchronizer_inline_impl.cc
  *
  * @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Fri Jun 17 2011
- * @date last modification: Tue Dec 09 2014
+ * @date last modification: Wed Nov 08 2017
  *
  * @brief  DOFSynchronizer inline implementation
  *
  * @section LICENSE
  *
- * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
- * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
- * Solides)
+ * 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
+ * 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
+ * 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 "communication_buffer.hh"
 #include "data_accessor.hh"
 #include "dof_manager_default.hh"
 #include "dof_synchronizer.hh"
 /* -------------------------------------------------------------------------- */
 #include <map>
 /* -------------------------------------------------------------------------- */
 
 #ifndef __AKANTU_DOF_SYNCHRONIZER_INLINE_IMPL_CC__
 #define __AKANTU_DOF_SYNCHRONIZER_INLINE_IMPL_CC__
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 template <typename T>
 void DOFSynchronizer::gather(const Array<T> & to_gather, Array<T> & gathered) {
   if (this->hasChanged())
     initScatterGatherCommunicationScheme();
 
   AKANTU_DEBUG_ASSERT(this->rank == UInt(this->root),
                       "This function cannot be called on a slave processor");
   AKANTU_DEBUG_ASSERT(to_gather.size() ==
                           this->dof_manager.getLocalSystemSize(),
                       "The array to gather does not have the correct size");
   AKANTU_DEBUG_ASSERT(gathered.size() == this->dof_manager.getSystemSize(),
                       "The gathered array does not have the correct size");
 
   if (this->nb_proc == 1) {
     gathered.copy(to_gather, true);
 
     AKANTU_DEBUG_OUT();
     return;
   }
 
   std::map<UInt, CommunicationBuffer> buffers;
   std::vector<CommunicationRequest> requests;
   for (UInt p = 0; p < this->nb_proc; ++p) {
     if (p == UInt(this->root))
       continue;
 
     auto receive_it = this->master_receive_dofs.find(p);
     AKANTU_DEBUG_ASSERT(receive_it != this->master_receive_dofs.end(),
                         "Could not find the receive list for dofs of proc "
                             << p);
     const Array<UInt> & receive_dofs = receive_it->second;
     if (receive_dofs.size() == 0)
       continue;
 
     CommunicationBuffer & buffer = buffers[p];
 
     buffer.resize(receive_dofs.size() * to_gather.getNbComponent() * sizeof(T));
 
     AKANTU_DEBUG_INFO(
         "Preparing to receive data for "
         << receive_dofs.size() << " dofs from processor " << p << " "
         << Tag::genTag(p, this->root, Tag::_GATHER, this->hash_id));
 
     requests.push_back(communicator.asyncReceive(
         buffer, p, Tag::genTag(p, this->root, Tag::_GATHER, this->hash_id)));
   }
 
   auto data_gathered_it = gathered.begin(to_gather.getNbComponent());
 
   { // copy master data
     auto data_to_gather_it = to_gather.begin(to_gather.getNbComponent());
     for (auto local_dof : root_dofs) {
       UInt global_dof = dof_manager.localToGlobalEquationNumber(local_dof);
 
       Vector<T> dof_data_gathered = data_gathered_it[global_dof];
       Vector<T> dof_data_to_gather = data_to_gather_it[local_dof];
       dof_data_gathered = dof_data_to_gather;
     }
   }
 
   auto rr = UInt(-1);
   while ((rr = communicator.waitAny(requests)) != UInt(-1)) {
     CommunicationRequest & request = requests[rr];
     UInt sender = request.getSource();
 
     AKANTU_DEBUG_ASSERT(this->master_receive_dofs.find(sender) !=
                                 this->master_receive_dofs.end() &&
                             buffers.find(sender) != buffers.end(),
                         "Missing infos concerning proc " << sender);
 
     const Array<UInt> & receive_dofs =
         this->master_receive_dofs.find(sender)->second;
     CommunicationBuffer & buffer = buffers[sender];
 
     for (auto global_dof : receive_dofs) {
       Vector<T> dof_data = data_gathered_it[global_dof];
       buffer >> dof_data;
     }
 
     requests.erase(requests.begin() + rr);
   }
 }
 
 /* -------------------------------------------------------------------------- */
 template <typename T> void DOFSynchronizer::gather(const Array<T> & to_gather) {
   AKANTU_DEBUG_IN();
 
   if (this->hasChanged())
     initScatterGatherCommunicationScheme();
 
   AKANTU_DEBUG_ASSERT(this->rank != UInt(this->root),
                       "This function cannot be called on the root processor");
   AKANTU_DEBUG_ASSERT(to_gather.size() ==
                           this->dof_manager.getLocalSystemSize(),
                       "The array to gather does not have the correct size");
 
   if (this->root_dofs.size() == 0) {
     AKANTU_DEBUG_OUT();
     return;
   }
   CommunicationBuffer buffer(this->root_dofs.size() *
                              to_gather.getNbComponent() * sizeof(T));
 
   auto data_it = to_gather.begin(to_gather.getNbComponent());
   for (auto dof : this->root_dofs) {
     Vector<T> data = data_it[dof];
     buffer << data;
   }
 
   AKANTU_DEBUG_INFO("Gathering data for "
                     << to_gather.size() << " dofs on processor " << this->root
                     << " "
                     << Tag::genTag(this->rank, 0, Tag::_GATHER, this->hash_id));
 
   communicator.send(buffer, this->root,
                     Tag::genTag(this->rank, 0, Tag::_GATHER, this->hash_id));
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <typename T>
 void DOFSynchronizer::scatter(Array<T> & scattered,
                               const Array<T> & to_scatter) {
   AKANTU_DEBUG_IN();
 
   if (this->hasChanged())
     initScatterGatherCommunicationScheme();
   AKANTU_DEBUG_ASSERT(this->rank == UInt(this->root),
                       "This function cannot be called on a slave processor");
   AKANTU_DEBUG_ASSERT(scattered.size() ==
                           this->dof_manager.getLocalSystemSize(),
                       "The scattered array does not have the correct size");
   AKANTU_DEBUG_ASSERT(to_scatter.size() == this->dof_manager.getSystemSize(),
                       "The array to scatter does not have the correct size");
 
   if (this->nb_proc == 1) {
     scattered.copy(to_scatter, true);
     AKANTU_DEBUG_OUT();
     return;
   }
 
   std::map<UInt, CommunicationBuffer> buffers;
   std::vector<CommunicationRequest> requests;
 
   for (UInt p = 0; p < nb_proc; ++p) {
     auto data_to_scatter_it = to_scatter.begin(to_scatter.getNbComponent());
 
     if (p == this->rank) {
       auto data_scattered_it = scattered.begin(to_scatter.getNbComponent());
 
       // copy the data for the local processor
       for (auto local_dof : root_dofs) {
         auto global_dof = dof_manager.localToGlobalEquationNumber(local_dof);
 
         Vector<T> dof_data_to_scatter = data_to_scatter_it[global_dof];
         Vector<T> dof_data_scattered = data_scattered_it[local_dof];
         dof_data_scattered = dof_data_to_scatter;
       }
 
       continue;
     }
 
     const Array<UInt> & receive_dofs =
         this->master_receive_dofs.find(p)->second;
 
     // prepare the send buffer
     CommunicationBuffer & buffer = buffers[p];
     buffer.resize(receive_dofs.size() * scattered.getNbComponent() * sizeof(T));
 
     // pack the data
     for (auto global_dof : receive_dofs) {
       Vector<T> dof_data_to_scatter = data_to_scatter_it[global_dof];
       buffer << dof_data_to_scatter;
     }
 
     // send the data
     requests.push_back(communicator.asyncSend(
         buffer, p, Tag::genTag(p, 0, Tag::_SCATTER, this->hash_id)));
   }
 
   // wait a clean communications
   communicator.waitAll(requests);
   communicator.freeCommunicationRequest(requests);
 
   // synchronize slave and ghost nodes
   synchronize(scattered);
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <typename T> void DOFSynchronizer::scatter(Array<T> & scattered) {
   AKANTU_DEBUG_IN();
 
   if (this->hasChanged())
     this->initScatterGatherCommunicationScheme();
   AKANTU_DEBUG_ASSERT(this->rank != UInt(this->root),
                       "This function cannot be called on the root processor");
   AKANTU_DEBUG_ASSERT(scattered.size() ==
                           this->dof_manager.getLocalSystemSize(),
                       "The scattered array does not have the correct size");
 
   // prepare the data
   auto data_scattered_it = scattered.begin(scattered.getNbComponent());
   CommunicationBuffer buffer(this->root_dofs.size() *
                              scattered.getNbComponent() * sizeof(T));
 
   // receive the data
   communicator.receive(
       buffer, this->root,
       Tag::genTag(this->rank, 0, Tag::_SCATTER, this->hash_id));
 
   // unpack the data
   for (auto local_dof : root_dofs) {
     Vector<T> dof_data_scattered = data_scattered_it[local_dof];
     buffer >> dof_data_scattered;
   }
 
   // synchronize the ghosts
   synchronize(scattered);
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <typename T>
 void DOFSynchronizer::synchronize(Array<T> & dof_values_to_synchronize) const {
   AKANTU_DEBUG_IN();
 
   SimpleUIntDataAccessor<T> data_accessor(dof_values_to_synchronize,
                                           _gst_whatever);
   this->synchronizeOnce(data_accessor, _gst_whatever);
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <template <class> class Op, typename T>
 void DOFSynchronizer::reduceSynchronize(Array<T> & dof_vector) const {
   AKANTU_DEBUG_IN();
 
   ReduceUIntDataAccessor<Op, T> data_accessor(dof_vector, _gst_whatever);
   this->synchronizeOnce(data_accessor, _gst_whatever);
 
   AKANTU_DEBUG_OUT();
 }
 
 } // akantu
 
 #endif /* __AKANTU_DOF_SYNCHRONIZER_INLINE_IMPL_CC__ */
diff --git a/src/synchronizer/element_info_per_processor.cc b/src/synchronizer/element_info_per_processor.cc
index a1ae4e5a4..b39152c38 100644
--- a/src/synchronizer/element_info_per_processor.cc
+++ b/src/synchronizer/element_info_per_processor.cc
@@ -1,109 +1,110 @@
 /**
  * @file   element_info_per_processor.cc
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
- * @date   Fri Mar 11 14:56:42 2016
+ * @date creation: Wed Mar 16 2016
+ * @date last modification: Tue Nov 07 2017
  *
- * @brief
+ * @brief  Helper class to distribute a mesh
  *
  * @section LICENSE
  *
- * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * 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
+ * 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
+ * A PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 #include "element_info_per_processor.hh"
 #include "communicator.hh"
 #include "element_synchronizer.hh"
 /* -------------------------------------------------------------------------- */
 #include <algorithm>
 #include <iostream>
 #include <map>
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 ElementInfoPerProc::ElementInfoPerProc(ElementSynchronizer & synchronizer,
                                        UInt message_cnt, UInt root,
                                        ElementType type)
     : MeshAccessor(synchronizer.getMesh()), synchronizer(synchronizer),
       rank(synchronizer.getCommunicator().whoAmI()),
       nb_proc(synchronizer.getCommunicator().getNbProc()), root(root),
       type(type), message_count(message_cnt), mesh(synchronizer.getMesh()),
       comm(synchronizer.getCommunicator()) {}
 
 /* -------------------------------------------------------------------------- */
 void ElementInfoPerProc::fillCommunicationScheme(
     const Array<UInt> & partition) {
   AKANTU_DEBUG_IN();
 
   Element element;
   element.type = this->type;
 
   auto & communications = this->synchronizer.getCommunications();
   auto part = partition.begin();
 
   std::map<UInt, Array<Element>> send_array_per_proc;
   for (UInt lel = 0; lel < nb_local_element; ++lel) {
     UInt nb_send = *part;
     ++part;
 
     element.element = lel;
     element.ghost_type = _not_ghost;
     for (UInt p = 0; p < nb_send; ++p, ++part) {
       UInt proc = *part;
 
       AKANTU_DEBUG(dblAccessory,
                    "Must send : " << element << " to proc " << proc);
       send_array_per_proc[proc].push_back(element);
     }
   }
 
   for (auto & send_schemes : send_array_per_proc) {
     if (send_schemes.second.size() == 0)
       continue;
     auto & scheme = communications.createSendScheme(send_schemes.first);
     scheme.append(send_schemes.second);
   }
 
   std::map<UInt, Array<Element>> recv_array_per_proc;
 
   for (UInt gel = 0; gel < nb_ghost_element; ++gel, ++part) {
     UInt proc = *part;
     element.element = gel;
     element.ghost_type = _ghost;
     AKANTU_DEBUG(dblAccessory,
                  "Must recv : " << element << " from proc " << proc);
     recv_array_per_proc[proc].push_back(element);
   }
 
   for (auto & recv_schemes : recv_array_per_proc) {
     if (recv_schemes.second.size() == 0)
       continue;
     auto & scheme = communications.createRecvScheme(recv_schemes.first);
     scheme.append(recv_schemes.second);
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 
 } // namespace akantu
diff --git a/src/synchronizer/element_info_per_processor.hh b/src/synchronizer/element_info_per_processor.hh
index df7c8c21b..a31e70d41 100644
--- a/src/synchronizer/element_info_per_processor.hh
+++ b/src/synchronizer/element_info_per_processor.hh
@@ -1,144 +1,145 @@
 /**
  * @file   element_info_per_processor.hh
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
- * @date   Fri Mar 11 14:45:15 2016
+ * @date creation: Wed Mar 16 2016
+ * @date last modification: Tue Nov 07 2017
  *
  * @brief  Helper classes to create the distributed synchronizer and distribute
- *         a mesh
+ * a mesh
  *
  * @section LICENSE
  *
- * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * 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
+ * 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
+ * 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 "communication_buffer.hh"
 #include "mesh.hh"
 #include "mesh_accessor.hh"
 /* -------------------------------------------------------------------------- */
 
 #ifndef __AKANTU_ELEMENT_INFO_PER_PROCESSOR_HH__
 #define __AKANTU_ELEMENT_INFO_PER_PROCESSOR_HH__
 
 namespace akantu {
 class ElementSynchronizer;
 class Communicator;
 class MeshPartition;
 }
 
 /* -------------------------------------------------------------------------- */
 namespace akantu {
 
 class ElementInfoPerProc : protected MeshAccessor {
 public:
   ElementInfoPerProc(ElementSynchronizer & synchronizer, UInt message_cnt,
                      UInt root, ElementType type);
 
   virtual void synchronizeConnectivities() = 0;
   virtual void synchronizePartitions() = 0;
   virtual void synchronizeTags() = 0;
   virtual void synchronizeGroups() = 0;
 
 protected:
   void fillCommunicationScheme(const Array<UInt> & partition);
 
   template <class CommunicationBuffer>
   void fillElementGroupsFromBuffer(CommunicationBuffer & buffer);
 
   template <typename T, typename BufferType>
   void fillMeshDataTemplated(BufferType & buffer, const std::string & tag_name,
                              UInt nb_component);
 
   template <typename BufferType>
   void fillMeshData(BufferType & buffer, const std::string & tag_name,
                     const MeshDataTypeCode & type_code, UInt nb_component);
 
 protected:
   ElementSynchronizer & synchronizer;
 
   UInt rank{0};
   UInt nb_proc{1};
 
   UInt root{0};
 
   ElementType type{_not_defined};
 
   UInt nb_tags{0};
   UInt nb_nodes_per_element{0};
   UInt nb_element{0};
 
   UInt nb_local_element{0};
   UInt nb_ghost_element{0};
 
   UInt message_count{0};
   Mesh & mesh;
   const Communicator & comm;
 };
 
 /* -------------------------------------------------------------------------- */
 class MasterElementInfoPerProc : protected ElementInfoPerProc {
 public:
   MasterElementInfoPerProc(ElementSynchronizer & synchronizer, UInt message_cnt,
                            UInt root, ElementType type,
                            const MeshPartition & partition);
 
   void synchronizeConnectivities() override;
   void synchronizePartitions() override;
   void synchronizeTags() override;
   void synchronizeGroups() override;
 
 protected:
   template <typename T>
   void fillTagBufferTemplated(std::vector<DynamicCommunicationBuffer> & buffers,
                               const std::string & tag_name);
   void fillTagBuffer(std::vector<DynamicCommunicationBuffer> & buffers,
                      const std::string & tag_name);
 
 private:
   const MeshPartition & partition;
 
   Vector<UInt> all_nb_local_element;
   Vector<UInt> all_nb_ghost_element;
   Vector<UInt> all_nb_element_to_send;
 };
 
 /* -------------------------------------------------------------------------- */
 class SlaveElementInfoPerProc : protected ElementInfoPerProc {
 public:
   SlaveElementInfoPerProc(ElementSynchronizer & synchronizer, UInt message_cnt,
                           UInt root);
 
   void synchronizeConnectivities() override;
   void synchronizePartitions() override;
   void synchronizeTags() override;
   void synchronizeGroups() override;
 
   bool needSynchronize();
 
 private:
   UInt nb_element_to_receive{0};
 };
 
 } // akantu
 
 #include "element_info_per_processor_tmpl.hh"
 
 #endif /* __AKANTU_ELEMENT_INFO_PER_PROCESSOR_HH__ */
diff --git a/src/synchronizer/element_info_per_processor_tmpl.hh b/src/synchronizer/element_info_per_processor_tmpl.hh
index 299a61f4a..3fb055721 100644
--- a/src/synchronizer/element_info_per_processor_tmpl.hh
+++ b/src/synchronizer/element_info_per_processor_tmpl.hh
@@ -1,145 +1,147 @@
 /**
  * @file   element_info_per_processor_tmpl.hh
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
- * @date   Fri Mar 11 15:03:12 2016
+ * @date creation: Wed Mar 16 2016
+ * @date last modification: Tue Feb 20 2018
  *
- * @brief
+ * @brief  Helper classes to create the distributed synchronizer and distribute
+ * a mesh
  *
  * @section LICENSE
  *
- * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * 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
+ * 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
+ * A PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 #include "element_group.hh"
 #include "element_info_per_processor.hh"
 #include "mesh.hh"
 /* -------------------------------------------------------------------------- */
 
 #ifndef __AKANTU_ELEMENT_INFO_PER_PROCESSOR_TMPL_HH__
 #define __AKANTU_ELEMENT_INFO_PER_PROCESSOR_TMPL_HH__
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 template <typename T, typename BufferType>
 void ElementInfoPerProc::fillMeshDataTemplated(BufferType & buffer,
                                                const std::string & tag_name,
                                                UInt nb_component) {
 
   AKANTU_DEBUG_ASSERT(this->mesh.getNbElement(this->type) == nb_local_element,
                       "Did not got enought informations for the tag "
                           << tag_name << " and the element type " << this->type
                           << ":"
                           << "_not_ghost."
                           << " Got " << nb_local_element << " values, expected "
                           << mesh.getNbElement(this->type));
   MeshData & mesh_data = this->getMeshData();
   mesh_data.registerElementalData<T>(tag_name);
   Array<T> & data = mesh_data.getElementalDataArrayAlloc<T>(
       tag_name, this->type, _not_ghost, nb_component);
 
   data.resize(nb_local_element);
   /// unpacking the data, element by element
   for (UInt i(0); i < nb_local_element; ++i) {
     for (UInt j(0); j < nb_component; ++j) {
       buffer >> data(i, j);
     }
   }
 
   AKANTU_DEBUG_ASSERT(mesh.getNbElement(this->type, _ghost) == nb_ghost_element,
                       "Did not got enought informations for the tag "
                           << tag_name << " and the element type " << this->type
                           << ":"
                           << "_ghost."
                           << " Got " << nb_ghost_element << " values, expected "
                           << mesh.getNbElement(this->type, _ghost));
 
   Array<T> & data_ghost = mesh_data.getElementalDataArrayAlloc<T>(
       tag_name, this->type, _ghost, nb_component);
   data_ghost.resize(nb_ghost_element);
 
   /// unpacking the ghost data, element by element
   for (UInt j(0); j < nb_ghost_element; ++j) {
     for (UInt k(0); k < nb_component; ++k) {
       buffer >> data_ghost(j, k);
     }
   }
 }
 
 /* -------------------------------------------------------------------------- */
 template <typename BufferType>
 void ElementInfoPerProc::fillMeshData(BufferType & buffer,
                                       const std::string & tag_name,
                                       const MeshDataTypeCode & type_code,
                                       UInt nb_component) {
 #define AKANTU_DISTRIBUTED_SYNHRONIZER_TAG_DATA(r, extra_param, elem)          \
   case BOOST_PP_TUPLE_ELEM(2, 0, elem): {                                      \
     fillMeshDataTemplated<BOOST_PP_TUPLE_ELEM(2, 1, elem)>(buffer, tag_name,   \
                                                            nb_component);      \
     break;                                                                     \
   }
 
   switch (type_code) {
     BOOST_PP_SEQ_FOR_EACH(AKANTU_DISTRIBUTED_SYNHRONIZER_TAG_DATA, ,
                           AKANTU_MESH_DATA_TYPES)
   default:
     AKANTU_ERROR("Could not determine the type of tag" << tag_name << "!");
     break;
   }
 #undef AKANTU_DISTRIBUTED_SYNHRONIZER_TAG_DATA
 }
 
 /* -------------------------------------------------------------------------- */
 template <class CommunicationBuffer>
 void ElementInfoPerProc::fillElementGroupsFromBuffer(
     CommunicationBuffer & buffer) {
   AKANTU_DEBUG_IN();
 
   Element el;
   el.type = type;
 
   for (auto ghost_type : ghost_types) {
     UInt nb_element = mesh.getNbElement(type, ghost_type);
     el.ghost_type = ghost_type;
 
     for (UInt e = 0; e < nb_element; ++e) {
       el.element = e;
 
       std::vector<std::string> element_to_group;
       buffer >> element_to_group;
 
       AKANTU_DEBUG_ASSERT(e < mesh.getNbElement(type, ghost_type),
                           "The mesh does not have the element " << e);
 
       for (auto && element : element_to_group) {
         mesh.getElementGroup(element).add(el, false, false);
       }
     }
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 
 } // akantu
 
 #endif /* __AKANTU_ELEMENT_INFO_PER_PROCESSOR_TMPL_HH__ */
diff --git a/src/synchronizer/element_synchronizer.cc b/src/synchronizer/element_synchronizer.cc
index 32698e302..a0e65e5cc 100644
--- a/src/synchronizer/element_synchronizer.cc
+++ b/src/synchronizer/element_synchronizer.cc
@@ -1,369 +1,368 @@
 /**
  * @file   element_synchronizer.cc
  *
  * @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
  * @author Dana Christen <dana.christen@epfl.ch>
  * @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  * @author Marco Vocialta <marco.vocialta@epfl.ch>
  *
  * @date creation: Wed Sep 01 2010
- * @date last modification: Fri Jan 22 2016
+ * @date last modification: Tue Feb 20 2018
  *
  * @brief  implementation of a  communicator using a static_communicator for
  * real
  * send/receive
  *
  * @section LICENSE
  *
- * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
- * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
- * Solides)
+ * 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
+ * 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
+ * A PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 #include "element_synchronizer.hh"
 #include "aka_common.hh"
 #include "mesh.hh"
 #include "mesh_utils.hh"
 /* -------------------------------------------------------------------------- */
 #include <algorithm>
 #include <iostream>
 #include <map>
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 ElementSynchronizer::ElementSynchronizer(Mesh & mesh, const ID & id,
                                          MemoryID memory_id,
                                          bool register_to_event_manager,
                                          EventHandlerPriority event_priority)
     : SynchronizerImpl<Element>(mesh.getCommunicator(), id, memory_id),
       mesh(mesh), element_to_prank("element_to_prank", id, memory_id) {
   AKANTU_DEBUG_IN();
 
   if (register_to_event_manager)
     this->mesh.registerEventHandler(*this, event_priority);
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 ElementSynchronizer::ElementSynchronizer(const ElementSynchronizer & other,
                                          const ID & id,
                                          bool register_to_event_manager,
                                          EventHandlerPriority event_priority)
     : SynchronizerImpl<Element>(other, id), mesh(other.mesh),
       element_to_prank("element_to_prank", id, other.memory_id) {
   AKANTU_DEBUG_IN();
 
   element_to_prank.copy(other.element_to_prank);
 
   if (register_to_event_manager)
     this->mesh.registerEventHandler(*this, event_priority);
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 ElementSynchronizer::~ElementSynchronizer() = default;
 
 /* -------------------------------------------------------------------------- */
 void ElementSynchronizer::substituteElements(
     const std::map<Element, Element> & old_to_new_elements) {
   auto found_element_end = old_to_new_elements.end();
 
   // substitute old elements with new ones
   for (auto && sr : iterate_send_recv) {
     for (auto && scheme_pair : communications.iterateSchemes(sr)) {
       auto & list = scheme_pair.second;
       for (auto & el : list) {
         auto found_element_it = old_to_new_elements.find(el);
         if (found_element_it != found_element_end)
           el = found_element_it->second;
       }
     }
   }
 }
 
 /* -------------------------------------------------------------------------- */
 void ElementSynchronizer::onElementsChanged(
     const Array<Element> & old_elements_list,
     const Array<Element> & new_elements_list, const ElementTypeMapArray<UInt> &,
     const ChangedElementsEvent &) {
   // create a map to link old elements to new ones
   std::map<Element, Element> old_to_new_elements;
 
   for (UInt el = 0; el < old_elements_list.size(); ++el) {
     AKANTU_DEBUG_ASSERT(old_to_new_elements.find(old_elements_list(el)) ==
                             old_to_new_elements.end(),
                         "The same element cannot appear twice in the list");
 
     old_to_new_elements[old_elements_list(el)] = new_elements_list(el);
   }
 
   substituteElements(old_to_new_elements);
 
   communications.invalidateSizes();
 }
 
 /* -------------------------------------------------------------------------- */
 void ElementSynchronizer::onElementsRemoved(
     const Array<Element> & element_to_remove,
     const ElementTypeMapArray<UInt> & new_numbering,
     const RemovedElementsEvent &) {
   AKANTU_DEBUG_IN();
 
   this->removeElements(element_to_remove);
   this->renumberElements(new_numbering);
 
   communications.invalidateSizes();
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void ElementSynchronizer::buildElementToPrank() {
   AKANTU_DEBUG_IN();
 
   UInt spatial_dimension = mesh.getSpatialDimension();
   element_to_prank.initialize(mesh, _spatial_dimension = spatial_dimension,
                               _element_kind = _ek_not_defined,
                               _with_nb_element = true, _default_value = rank);
 
   /// assign prank to all ghost elements
   for (auto && scheme : communications.iterateSchemes(_recv)) {
     auto & recv = scheme.second;
     auto proc = scheme.first;
 
     for (auto & element : recv) {
       element_to_prank(element) = proc;
     }
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 Int ElementSynchronizer::getRank(const Element & element) const {
   if (not element_to_prank.exists(element.type, element.ghost_type)) {
     // Nicolas: Ok This is nasty I know....
     const_cast<ElementSynchronizer *>(this)->buildElementToPrank();
   }
 
   return element_to_prank(element);
 }
 
 /* -------------------------------------------------------------------------- */
 void ElementSynchronizer::reset() {
   AKANTU_DEBUG_IN();
 
   communications.resetSchemes();
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void ElementSynchronizer::removeElements(
     const Array<Element> & element_to_remove) {
   AKANTU_DEBUG_IN();
 
   std::vector<CommunicationRequest> send_requests;
   std::map<UInt, Array<UInt>> list_of_elements_per_proc;
 
   auto filter_list = [](const Array<UInt> & keep, Array<Element> & list) {
     Array<Element> new_list;
     for (UInt e = 0; e < keep.size() - 1; ++e) {
       Element & el = list(keep(e));
       new_list.push_back(el);
     }
     list.copy(new_list);
   };
 
   // Handling ghost elements
   for (auto && scheme_pair : communications.iterateSchemes(_recv)) {
     auto proc = scheme_pair.first;
     auto & recv = scheme_pair.second;
     Array<UInt> & keep_list = list_of_elements_per_proc[proc];
 
     auto rem_it = element_to_remove.begin();
     auto rem_end = element_to_remove.end();
 
     for (auto && pair : enumerate(recv)) {
       const auto & el = std::get<1>(pair);
       auto pos = std::find(rem_it, rem_end, el);
 
       if (pos == rem_end) {
         keep_list.push_back(std::get<0>(pair));
       }
     }
 
     keep_list.push_back(UInt(-1)); // To no send empty arrays
 
     auto && tag = Tag::genTag(proc, 0, Tag::_MODIFY_SCHEME, this->hash_id);
     AKANTU_DEBUG_INFO("Sending a message of size "
                       << keep_list.size() << " to proc " << proc << " TAG("
                       << tag << ")");
     send_requests.push_back(this->communicator.asyncSend(keep_list, proc, tag));
 
 #ifndef AKANTU_NDEBUG
     auto old_size = recv.size();
 #endif
     filter_list(keep_list, recv);
 
     AKANTU_DEBUG_INFO("I had " << old_size << " elements to recv from proc "
                                << proc << " and " << keep_list.size()
                                << " elements to keep. I have " << recv.size()
                                << " elements left.");
   }
 
   for (auto && scheme_pair : communications.iterateSchemes(_send)) {
     auto proc = scheme_pair.first;
     auto & send = scheme_pair.second;
 
     CommunicationStatus status;
     auto && tag = Tag::genTag(rank, 0, Tag::_MODIFY_SCHEME, this->hash_id);
     AKANTU_DEBUG_INFO("Getting number of elements of proc "
                       << proc << " to keep - TAG(" << tag << ")");
     this->communicator.probe<UInt>(proc, tag, status);
     Array<UInt> keep_list(status.size());
 
     AKANTU_DEBUG_INFO("Receiving list of elements ("
                       << keep_list.size() << " elements) to keep for proc "
                       << proc << " TAG(" << tag << ")");
     this->communicator.receive(keep_list, proc, tag);
 
 #ifndef AKANTU_NDEBUG
     auto old_size = send.size();
 #endif
     filter_list(keep_list, send);
 
     AKANTU_DEBUG_INFO("I had " << old_size << " elements to send to proc "
                                << proc << " and " << keep_list.size()
                                << " elements to keep. I have " << send.size()
                                << " elements left.");
   }
 
   this->communicator.waitAll(send_requests);
   this->communicator.freeCommunicationRequest(send_requests);
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void ElementSynchronizer::renumberElements(
     const ElementTypeMapArray<UInt> & new_numbering) {
   for (auto && sr : iterate_send_recv) {
     for (auto && scheme_pair : communications.iterateSchemes(sr)) {
       auto & list = scheme_pair.second;
       for (auto && el : list) {
         if (new_numbering.exists(el.type, el.ghost_type))
           el.element = new_numbering(el);
       }
     }
   }
 }
 
 /* -------------------------------------------------------------------------- */
 UInt ElementSynchronizer::sanityCheckDataSize(
     const Array<Element> & elements, const SynchronizationTag &) const {
   UInt size = 0;
   size += sizeof(SynchronizationTag); // tag
   size += sizeof(UInt);               // comm_desc.getNbData();
   size += sizeof(UInt);               // comm_desc.getProc();
   size += sizeof(UInt);               // mesh.getCommunicator().whoAmI();
 
   // barycenters
   size += (elements.size() * mesh.getSpatialDimension() * sizeof(Real));
   return size;
 }
 
 /* -------------------------------------------------------------------------- */
 void ElementSynchronizer::packSanityCheckData(
     CommunicationDescriptor<Element> & comm_desc) const {
   auto & buffer = comm_desc.getBuffer();
   buffer << comm_desc.getTag();
   buffer << comm_desc.getNbData();
   buffer << comm_desc.getProc();
   buffer << mesh.getCommunicator().whoAmI();
 
   auto & send_element = comm_desc.getScheme();
 
   /// pack barycenters in debug mode
   for (auto && element : send_element) {
     Vector<Real> barycenter(mesh.getSpatialDimension());
     mesh.getBarycenter(element, barycenter);
     buffer << barycenter;
   }
 }
 
 /* -------------------------------------------------------------------------- */
 void ElementSynchronizer::unpackSanityCheckData(
     CommunicationDescriptor<Element> & comm_desc) const {
   auto & buffer = comm_desc.getBuffer();
   const auto & tag = comm_desc.getTag();
 
   auto nb_data = comm_desc.getNbData();
   auto proc = comm_desc.getProc();
   auto rank = mesh.getCommunicator().whoAmI();
 
   decltype(nb_data) recv_nb_data;
   decltype(proc) recv_proc;
   decltype(rank) recv_rank;
 
   SynchronizationTag t;
   buffer >> t;
   buffer >> recv_nb_data;
   buffer >> recv_proc;
   buffer >> recv_rank;
 
   AKANTU_DEBUG_ASSERT(
       t == tag, "The tag received does not correspond to the tag expected");
 
   AKANTU_DEBUG_ASSERT(
       nb_data == recv_nb_data,
       "The nb_data received does not correspond to the nb_data expected");
 
   AKANTU_DEBUG_ASSERT(UInt(recv_rank) == proc,
                       "The rank received does not correspond to the proc");
 
   AKANTU_DEBUG_ASSERT(recv_proc == UInt(rank),
                       "The proc received does not correspond to the rank");
 
   auto & recv_element = comm_desc.getScheme();
   auto spatial_dimension = mesh.getSpatialDimension();
 
   for (auto && element : recv_element) {
     Vector<Real> barycenter_loc(spatial_dimension);
     mesh.getBarycenter(element, barycenter_loc);
 
     Vector<Real> barycenter(spatial_dimension);
     buffer >> barycenter;
 
     auto dist = barycenter_loc.distance(barycenter);
     if (not Math::are_float_equal(dist, 0.))
       AKANTU_EXCEPTION("Unpacking an unknown value for the element "
                        << element << "(barycenter " << barycenter_loc
                        << " != buffer " << barycenter << ") [" << dist
                        << "] - tag: " << tag << " comm from " << proc << " to "
                        << rank);
   }
 }
 
 /* -------------------------------------------------------------------------- */
 } // namespace akantu
diff --git a/src/synchronizer/element_synchronizer.hh b/src/synchronizer/element_synchronizer.hh
index 8764beb79..d72058515 100644
--- a/src/synchronizer/element_synchronizer.hh
+++ b/src/synchronizer/element_synchronizer.hh
@@ -1,216 +1,215 @@
 /**
  * @file   element_synchronizer.hh
  *
  * @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
  * @author Dana Christen <dana.christen@epfl.ch>
  * @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  * @author Marco Vocialta <marco.vocialta@epfl.ch>
  *
  * @date creation: Fri Jun 18 2010
- * @date last modification: Tue Dec 08 2015
+ * @date last modification: Tue Feb 20 2018
  *
  * @brief  Main element synchronizer
  *
  * @section LICENSE
  *
- * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
- * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
- * Solides)
+ * 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
+ * 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
+ * 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_ELEMENT_SYNCHRONIZER_HH__
 #define __AKANTU_ELEMENT_SYNCHRONIZER_HH__
 
 /* -------------------------------------------------------------------------- */
 #include "aka_array.hh"
 #include "aka_common.hh"
 #include "mesh_partition.hh"
 #include "synchronizer_impl.hh"
 
 namespace akantu {
 class Mesh;
 }
 
 /* -------------------------------------------------------------------------- */
 namespace akantu {
 
 class ElementSynchronizer : public SynchronizerImpl<Element>,
                             public MeshEventHandler {
   /* ------------------------------------------------------------------------ */
   /* Constructors/Destructors                                                 */
   /* ------------------------------------------------------------------------ */
 public:
   ElementSynchronizer(Mesh & mesh, const ID & id = "element_synchronizer",
                       MemoryID memory_id = 0,
                       bool register_to_event_manager = true,
                       EventHandlerPriority event_priority = _ehp_synchronizer);
 
   ElementSynchronizer(const ElementSynchronizer & other,
                       const ID & id = "element_synchronizer_copy",
                       bool register_to_event_manager = true,
                       EventHandlerPriority event_priority = _ehp_synchronizer);
 
 public:
   ~ElementSynchronizer() override;
 
   friend class ElementInfoPerProc;
   /* ------------------------------------------------------------------------ */
   /* Methods                                                                  */
   /* ------------------------------------------------------------------------ */
 public:
   /* ------------------------------------------------------------------------ */
   /// mesh event handler onElementsChanged
   void onElementsChanged(const Array<Element> & old_elements_list,
                          const Array<Element> & new_elements_list,
                          const ElementTypeMapArray<UInt> & new_numbering,
                          const ChangedElementsEvent & event) override;
 
   /// mesh event handler onRemovedElement
   void onElementsRemoved(const Array<Element> & element_list,
                          const ElementTypeMapArray<UInt> & new_numbering,
                          const RemovedElementsEvent & event) override;
   /// mesh event handler onNodesAdded
   void onNodesAdded(const Array<UInt> & /* nodes_list*/,
                     const NewNodesEvent & /*event*/) override{};
 
   /// mesh event handler onRemovedNodes
   void onNodesRemoved(const Array<UInt> & /*nodes_list*/,
                       const Array<UInt> & /*new_numbering*/,
                       const RemovedNodesEvent & /*event*/) override{};
 
   /// mesh event handler onElementsAdded
   void onElementsAdded(const Array<Element> & /*elements_list*/,
                        const NewElementsEvent & /*event*/) override{};
 
 protected:
   /// reset send and recv element lists
   void reset();
 
   /// remove elements from the synchronizer without renumbering them
   void removeElements(const Array<Element> & element_to_remove);
 
   /// renumber the elements in the synchronizer
   void renumberElements(const ElementTypeMapArray<UInt> & new_numbering);
 
   /// build processor to element correspondence
   void buildElementToPrank();
 
 protected:
   /// fill the nodes type vector
   void fillNodesType(const MeshData & mesh_data,
                      DynamicCommunicationBuffer * buffers,
                      const std::string & tag_name, const ElementType & el_type,
                      const Array<UInt> & partition_num);
 
   template <typename T>
   void fillTagBufferTemplated(const MeshData & mesh_data,
                               DynamicCommunicationBuffer * buffers,
                               const std::string & tag_name,
                               const ElementType & el_type,
                               const Array<UInt> & partition_num,
                               const CSR<UInt> & ghost_partition);
 
   void fillTagBuffer(const MeshData & mesh_data,
                      DynamicCommunicationBuffer * buffers,
                      const std::string & tag_name, const ElementType & el_type,
                      const Array<UInt> & partition_num,
                      const CSR<UInt> & ghost_partition);
 
   /// function that handels the MeshData to be split (root side)
   static void synchronizeTagsSend(ElementSynchronizer & communicator, UInt root,
                                   Mesh & mesh, UInt nb_tags,
                                   const ElementType & type,
                                   const Array<UInt> & partition_num,
                                   const CSR<UInt> & ghost_partition,
                                   UInt nb_local_element, UInt nb_ghost_element);
 
   /// function that handles the MeshData to be split (other nodes)
   static void synchronizeTagsRecv(ElementSynchronizer & communicator, UInt root,
                                   Mesh & mesh, UInt nb_tags,
                                   const ElementType & type,
                                   UInt nb_local_element, UInt nb_ghost_element);
 
   /// function that handles the preexisting groups in the mesh
   static void synchronizeElementGroups(ElementSynchronizer & communicator,
                                        UInt root, Mesh & mesh,
                                        const ElementType & type,
                                        const Array<UInt> & partition_num,
                                        const CSR<UInt> & ghost_partition,
                                        UInt nb_element);
 
   /// function that handles the preexisting groups in the mesh
   static void synchronizeElementGroups(ElementSynchronizer & communicator,
                                        UInt root, Mesh & mesh,
                                        const ElementType & type);
 
   /// function that handles the preexisting groups in the mesh
   static void synchronizeNodeGroupsMaster(ElementSynchronizer & communicator,
                                           UInt root, Mesh & mesh);
 
   /// function that handles the preexisting groups in the mesh
   static void synchronizeNodeGroupsSlaves(ElementSynchronizer & communicator,
                                           UInt root, Mesh & mesh);
 
   template <class CommunicationBuffer>
   static void fillNodeGroupsFromBuffer(ElementSynchronizer & communicator,
                                        Mesh & mesh,
                                        CommunicationBuffer & buffer);
 
   /// substitute elements in the send and recv arrays
   void
   substituteElements(const std::map<Element, Element> & old_to_new_elements);
 
   /* ------------------------------------------------------------------------ */
   /* Sanity checks                                                            */
   /* ------------------------------------------------------------------------ */
   UInt sanityCheckDataSize(const Array<Element> & elements,
                            const SynchronizationTag & tag) const override;
   /* ------------------------------------------------------------------------ */
   void packSanityCheckData(
       CommunicationDescriptor<Element> & comm_desc) const override;
   /* ------------------------------------------------------------------------ */
   void unpackSanityCheckData(
       CommunicationDescriptor<Element> & comm_desc) const override;
 
   /* ------------------------------------------------------------------------ */
   /* Accessors                                                                */
   /* ------------------------------------------------------------------------ */
 public:
   AKANTU_GET_MACRO(Mesh, mesh, Mesh &);
   AKANTU_GET_MACRO(ElementToRank, element_to_prank,
                    const ElementTypeMapArray<Int> &);
 
   Int getRank(const Element & element) const final;
   /* ------------------------------------------------------------------------ */
   /* Class Members                                                            */
   /* ------------------------------------------------------------------------ */
 protected:
   /// reference to the underlying mesh
   Mesh & mesh;
 
   friend class FacetSynchronizer;
 
   ElementTypeMapArray<Int> element_to_prank;
 };
 
 /* -------------------------------------------------------------------------- */
 } // namespace akantu
 
 #endif /* __AKANTU_ELEMENT_SYNCHRONIZER_HH__ */
diff --git a/src/synchronizer/facet_synchronizer.cc b/src/synchronizer/facet_synchronizer.cc
index 9fef0f160..6c65293ee 100644
--- a/src/synchronizer/facet_synchronizer.cc
+++ b/src/synchronizer/facet_synchronizer.cc
@@ -1,514 +1,531 @@
 /**
  * @file   facet_synchronizer.cc
  *
+ * @author Nicolas Richart <nicolas.richart@epfl.ch>
  * @author Marco Vocialta <marco.vocialta@epfl.ch>
  *
+ * @date creation: Wed Nov 05 2014
+ * @date last modification: Fri Jan 26 2018
  *
  * @brief  Facet synchronizer for parallel simulations with cohesive elments
  *
  * @section LICENSE
  *
- * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * Copyright (©) 2015-2018 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
+ * Akantu is free  software: you can redistribute it and/or  modify it under the
+ * terms  of the  GNU Lesser  General Public  License as published by  the Free
+ * Software Foundation, either version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * Akantu is  distributed in the  hope that it  will be useful, but  WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
+ * details.
+ *
+ * You should  have received  a copy  of the GNU  Lesser General  Public License
+ * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
+ *
  */
+
 /* -------------------------------------------------------------------------- */
 #include "facet_synchronizer.hh"
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 FacetSynchronizer::FacetSynchronizer(
     Mesh & mesh, const ElementSynchronizer & element_synchronizer,
     const ID & id, MemoryID memory_id)
     : ElementSynchronizer(mesh, id, memory_id) {
 
   const auto & comm = mesh.getCommunicator();
   auto spatial_dimension = mesh.getSpatialDimension();
 
   element_to_prank.initialize(mesh, _spatial_dimension = spatial_dimension - 1,
                               _ghost_type = _ghost, _with_nb_element = true,
                               _default_value = rank);
 
   for (auto && scheme_pair :
        element_synchronizer.communications.iterateSchemes(_recv)) {
     auto proc = std::get<0>(scheme_pair);
     const auto & scheme = std::get<1>(scheme_pair);
 
     for (auto && elem : scheme) {
       const auto & facet_to_element =
           mesh.getSubelementToElement(elem.type, elem.ghost_type);
       Vector<Element> facets = facet_to_element.begin(
           facet_to_element.getNbComponent())[elem.element];
 
       for (UInt f = 0; f < facets.size(); ++f) {
         auto & facet = facets(f);
         if (facet == ElementNull)
           continue;
 
         if (facet.ghost_type == _not_ghost)
           continue;
 
         auto & facet_rank = element_to_prank(facet);
         if ((proc < UInt(facet_rank)) || (UInt(facet_rank) == rank))
           facet_rank = proc;
       }
     }
   }
 
   ElementTypeMapArray<UInt> facet_global_connectivities(
       "facet_global_connectivities", id, memory_id);
   facet_global_connectivities.initialize(
       mesh, _spatial_dimension = spatial_dimension - 1, _with_nb_element = true,
       _with_nb_nodes_per_element = true);
   mesh.getGlobalConnectivity(facet_global_connectivities);
 
   /// init facet check tracking
   ElementTypeMapArray<bool> facet_checked("facet_checked", id, memory_id);
   std::vector<CommunicationRequest> send_requests;
 
   std::map<UInt, ElementTypeMapArray<UInt>> send_facets;
   std::map<UInt, ElementTypeMapArray<UInt>> connectivities;
 
   for (auto && sr : iterate_send_recv) {
     GhostType interesting_ghost_type = sr == _send ? _not_ghost : _ghost;
     for (auto && scheme_pair :
          element_synchronizer.communications.iterateSchemes(sr)) {
       facet_checked.initialize(mesh, _spatial_dimension = spatial_dimension - 1,
                                _ghost_type = interesting_ghost_type,
                                _with_nb_element = true, _default_value = false);
 
       auto && proc = scheme_pair.first;
       auto & elements = scheme_pair.second;
       auto & facet_scheme = communications.createScheme(proc, sr);
 
       // this creates empty arrays...
       auto & facet_send_elements = send_facets[proc];
       auto & connectivities_for_proc = connectivities[proc];
       if (sr == _send) {
         connectivities_for_proc.setID(id + ":connectivities_for_proc:");
         connectivities_for_proc.initialize(
             mesh, _spatial_dimension = spatial_dimension - 1,
             _with_nb_nodes_per_element = true);
 
         facet_send_elements.setID(id + ":facet_send_elements");
         facet_send_elements.initialize(
             mesh, _spatial_dimension = spatial_dimension - 1);
       }
 
       for (auto && element : elements) {
         const auto & facet_to_element =
             mesh.getSubelementToElement(element.type, element.ghost_type);
         Vector<Element> facets = facet_to_element.begin(
             facet_to_element.getNbComponent())[element.element];
 
         for (UInt f = 0; f < facets.size(); ++f) {
           auto & facet = facets(f);
           if (facet == ElementNull)
             continue;
 
           if (facet.ghost_type != interesting_ghost_type)
             continue;
 
           if (sr == _recv && UInt(element_to_prank(facet)) != proc)
             continue;
 
           auto & checked = facet_checked(facet);
           if (checked)
             continue;
 
           checked = true;
 
           if (sr == _recv) {
             facet_scheme.push_back(facet);
           } else {
             facet_send_elements(facet.type, facet.ghost_type)
                 .push_back(facet.element);
           }
 
           auto & global_conn =
               facet_global_connectivities(facet.type, facet.ghost_type);
           Vector<UInt> conn =
               global_conn.begin(global_conn.getNbComponent())[facet.element];
           std::sort(conn.storage(), conn.storage() + conn.size());
           connectivities_for_proc(facet.type, facet.ghost_type).push_back(conn);
         }
       }
     }
   }
 
   /// do every communication by element type
   for (auto && type : mesh.elementTypes(spatial_dimension - 1)) {
 
     for (auto && pair : connectivities) {
       auto proc = std::get<0>(pair);
       const auto & connectivities_for_proc = std::get<1>(pair);
       auto && tag = Tag::genTag(proc, proc, 1337);
       send_requests.push_back(
           comm.asyncSend(connectivities_for_proc(type, _ghost), proc, tag,
                          CommunicationMode::_synchronous));
     }
 
     auto nb_nodes_per_facet = Mesh::getNbNodesPerElement(type);
 
     Array<UInt> buffer;
     Element facet{type, 0, _not_ghost};
 
     comm.receiveAnyNumber(
         send_requests, buffer,
         [&](auto && proc, auto && message) {
           auto & local_connectivities = connectivities[proc](type, _not_ghost);
           auto & list = send_facets[proc](type, _not_ghost);
           auto & send_scheme = communications.getScheme(proc, _send);
 
           std::vector<bool> checked(list.size(), false);
 
           for (auto && c_to_match : make_view(message, nb_nodes_per_facet)) {
 #if !defined(AKANTU_NDEBUG)
             bool found = false;
 #endif
             for (auto && pair : enumerate(
                      make_view(local_connectivities, nb_nodes_per_facet))) {
               UInt f;
               Vector<UInt> local_conn;
               std::tie(f, local_conn) = pair;
 
               if (checked[f])
                 continue;
 
               if (c_to_match == local_conn) {
 #if !defined(AKANTU_NDEBUG)
                 found = true;
 #endif
                 checked[f] = true;
                 facet.element = list(f);
                 send_scheme.push_back(facet);
                 break;
               }
             }
             AKANTU_DEBUG_ASSERT(found, "facet not found");
           }
         },
         [&]() { return Tag::genTag(rank, rank, 1337); });
   }
 }
 
 // /* --------------------------------------------------------------------------
 // */ void FacetSynchronizer::setupFacetSynchronization(
 //     ElementSynchronizer & distributed_synchronizer) {
 //   AKANTU_DEBUG_IN();
 
 //   Array<Element> * distrib_send_element =
 //   distributed_synchronizer.send_element; Array<Element> *
 //   distrib_recv_element = distributed_synchronizer.recv_element;
 
 //   /// build rank to facet correspondance
 //   ElementTypeMapArray<UInt> rank_to_facet("rank_to_facet", id);
 //   initRankToFacet(rank_to_facet);
 //   buildRankToFacet(rank_to_facet, distrib_recv_element);
 
 //   /// generate temp_send/recv element arrays with their connectivity
 //   Array<ElementTypeMapArray<UInt> *> temp_send_element(nb_proc);
 //   Array<ElementTypeMapArray<UInt> *> temp_recv_element(nb_proc);
 //   Array<ElementTypeMapArray<UInt> *> send_connectivity(nb_proc);
 //   Array<ElementTypeMapArray<UInt> *> recv_connectivity(nb_proc);
 
 //   UInt spatial_dimension = mesh.getSpatialDimension();
 
 //   for (UInt p = 0; p < nb_proc; ++p) {
 //     if (p == rank)
 //       continue;
 //     std::stringstream sstr;
 //     sstr << p;
 
 //     temp_send_element(p) = new ElementTypeMapArray<UInt>(
 //         "temp_send_element_proc_" + sstr.str(), id);
 //     mesh.initElementTypeMapArray(*temp_send_element(p), 1,
 //                                  spatial_dimension - 1);
 
 //     temp_recv_element(p) = new ElementTypeMapArray<UInt>(
 //         "temp_recv_element_proc_" + sstr.str(), id);
 //     mesh.initElementTypeMapArray(*temp_recv_element(p), 1,
 //                                  spatial_dimension - 1);
 
 //     send_connectivity(p) = new ElementTypeMapArray<UInt>(
 //         "send_connectivity_proc_" + sstr.str(), id);
 //     mesh.initElementTypeMapArray(*send_connectivity(p), 1,
 //                                  spatial_dimension - 1, true);
 
 //     recv_connectivity(p) = new ElementTypeMapArray<UInt>(
 //         "recv_connectivity_proc_" + sstr.str(), id);
 //     mesh.initElementTypeMapArray(*recv_connectivity(p), 1,
 //                                  spatial_dimension - 1, true);
 //   }
 
 //   /// build global connectivity arrays
 //   getFacetGlobalConnectivity<_not_ghost>(distributed_synchronizer,
 //                                          rank_to_facet, distrib_send_element,
 //                                          send_connectivity,
 //                                          temp_send_element);
 
 //   getFacetGlobalConnectivity<_ghost>(distributed_synchronizer, rank_to_facet,
 //                                      distrib_recv_element, recv_connectivity,
 //                                      temp_recv_element);
 
 //   /// build send/recv facet arrays
 //   buildSendElementList(send_connectivity, recv_connectivity,
 //   temp_send_element); buildRecvElementList(temp_recv_element);
 
 // #ifndef AKANTU_NDEBUG
 //   /// count recv facets for each processor
 //   Array<UInt> nb_facets_recv(nb_proc);
 //   nb_facets_recv.clear();
 
 //   Mesh::type_iterator first = mesh.firstType(spatial_dimension - 1, _ghost);
 //   Mesh::type_iterator last = mesh.lastType(spatial_dimension - 1, _ghost);
 
 //   for (; first != last; ++first) {
 //     const Array<UInt> & r_to_f = rank_to_facet(*first, _ghost);
 //     UInt nb_facet = r_to_f.getSize();
 
 //     for (UInt f = 0; f < nb_facet; ++f) {
 //       UInt proc = r_to_f(f);
 //       if (proc != rank)
 //         ++nb_facets_recv(proc);
 //     }
 //   }
 
 //   for (UInt p = 0; p < nb_proc; ++p) {
 //     AKANTU_DEBUG_ASSERT(nb_facets_recv(p) == recv_element[p].getSize(),
 //                         "Wrong number of recv facets");
 //   }
 
 // #endif
 
 //   for (UInt p = 0; p < nb_proc; ++p) {
 //     delete temp_send_element(p);
 //     delete temp_recv_element(p);
 //     delete send_connectivity(p);
 //     delete recv_connectivity(p);
 //   }
 
 //   AKANTU_DEBUG_OUT();
 // }
 
 // /* --------------------------------------------------------------------------
 // */ void FacetSynchronizer::buildSendElementList(
 //     const Array<ElementTypeMapArray<UInt> *> & send_connectivity,
 //     const Array<ElementTypeMapArray<UInt> *> & recv_connectivity,
 //     const Array<ElementTypeMapArray<UInt> *> & temp_send_element) {
 //   AKANTU_DEBUG_IN();
 
 //   StaticCommunicator & comm = StaticCommunicator::getStaticCommunicator();
 
 //   UInt spatial_dimension = mesh.getSpatialDimension();
 
 //   GhostType ghost_type = _ghost;
 
 //   Mesh::type_iterator first = mesh.firstType(spatial_dimension - 1,
 //   ghost_type); Mesh::type_iterator last = mesh.lastType(spatial_dimension -
 //   1, ghost_type);
 
 //   /// do every communication by element type
 //   for (; first != last; ++first) {
 
 //     ElementType facet_type = *first;
 
 //     std::vector<CommunicationRequest *> send_requests;
 //     UInt * send_size = new UInt[nb_proc];
 
 //     /// send asynchronous data
 //     for (UInt p = 0; p < nb_proc; ++p) {
 //       if (p == rank)
 //         continue;
 
 //       const Array<UInt> & recv_conn =
 //           (*recv_connectivity(p))(facet_type, _ghost);
 //       send_size[p] = recv_conn.getSize();
 
 //       /// send connectivity size
 //       send_requests.push_back(
 //           comm.asyncSend(send_size + p, 1, p, Tag::genTag(rank, p, 0)));
 
 //       /// send connectivity data
 //       send_requests.push_back(comm.asyncSend(
 //           recv_conn.storage(), recv_conn.getSize() *
 //           recv_conn.getNbComponent(), p, Tag::genTag(rank, p, 1)));
 //     }
 
 //     UInt * recv_size = new UInt[nb_proc];
 //     UInt nb_nodes_per_facet = Mesh::getNbNodesPerElement(facet_type);
 
 //     /// receive data
 //     for (UInt p = 0; p < nb_proc; ++p) {
 //       if (p == rank)
 //         continue;
 
 //       /// receive connectivity size
 //       comm.receive(recv_size + p, 1, p, Tag::genTag(p, rank, 0));
 
 //       Array<UInt> conn_to_match(recv_size[p], nb_nodes_per_facet);
 
 //       /// receive connectivity
 //       comm.receive(conn_to_match.storage(),
 //                    conn_to_match.getSize() * conn_to_match.getNbComponent(),
 //                    p, Tag::genTag(p, rank, 1));
 
 //       const Array<UInt> & send_conn =
 //           (*send_connectivity(p))(facet_type, _not_ghost);
 //       const Array<UInt> & list =
 //           (*temp_send_element(p))(facet_type, _not_ghost);
 //       UInt nb_local_facets = send_conn.getSize();
 
 //       AKANTU_DEBUG_ASSERT(nb_local_facets == list.getSize(),
 //                           "connectivity and facet list have different
 //                           sizes");
 
 //       Array<bool> checked(nb_local_facets);
 //       checked.clear();
 
 //       Element facet(facet_type, 0, _not_ghost, _ek_regular);
 
 //       Array<UInt>::iterator<Vector<UInt>> c_to_match_it =
 //           conn_to_match.begin(nb_nodes_per_facet);
 //       Array<UInt>::iterator<Vector<UInt>> c_to_match_end =
 //           conn_to_match.end(nb_nodes_per_facet);
 
 //       /// for every sent facet of other processors, find the
 //       /// corresponding one in the local send connectivity data in
 //       /// order to build the send_element arrays
 //       for (; c_to_match_it != c_to_match_end; ++c_to_match_it) {
 
 //         Array<UInt>::const_iterator<Vector<UInt>> c_local_it =
 //             send_conn.begin(nb_nodes_per_facet);
 //         Array<UInt>::const_iterator<Vector<UInt>> c_local_end =
 //             send_conn.end(nb_nodes_per_facet);
 
 //         for (UInt f = 0; f < nb_local_facets; ++f, ++c_local_it) {
 //           if (checked(f))
 //             continue;
 
 //           if ((*c_to_match_it) == (*c_local_it)) {
 //             checked(f) = true;
 //             facet.element = list(f);
 //             send_element[p].push_back(facet);
 //             break;
 //           }
 //         }
 //         AKANTU_DEBUG_ASSERT(c_local_it != c_local_end, "facet not found");
 //       }
 //     }
 
 //     /// wait for all communications to be done and free the
 //     /// communication request array
 //     comm.waitAll(send_requests);
 //     comm.freeCommunicationRequest(send_requests);
 
 //     delete[] send_size;
 //     delete[] recv_size;
 //   }
 
 //   AKANTU_DEBUG_OUT();
 // }
 
 // /* --------------------------------------------------------------------------
 // */ void FacetSynchronizer::buildRecvElementList(
 //     const Array<ElementTypeMapArray<UInt> *> & temp_recv_element) {
 //   AKANTU_DEBUG_IN();
 
 //   UInt spatial_dimension = mesh.getSpatialDimension();
 
 //   for (UInt p = 0; p < nb_proc; ++p) {
 //     if (p == rank)
 //       continue;
 
 //     GhostType ghost_type = _ghost;
 
 //     Mesh::type_iterator first =
 //         mesh.firstType(spatial_dimension - 1, ghost_type);
 //     Mesh::type_iterator last = mesh.lastType(spatial_dimension - 1,
 //     ghost_type);
 
 //     for (; first != last; ++first) {
 //       ElementType facet_type = *first;
 
 //       const Array<UInt> & list =
 //           (*temp_recv_element(p))(facet_type, ghost_type);
 //       UInt nb_local_facets = list.getSize();
 
 //       Element facet(facet_type, 0, ghost_type, _ek_regular);
 
 //       for (UInt f = 0; f < nb_local_facets; ++f) {
 //         facet.element = list(f);
 //         recv_element[p].push_back(facet);
 //       }
 //     }
 //   }
 
 //   AKANTU_DEBUG_OUT();
 // }
 
 // void FacetSynchronizer::initRankToFacet(
 //     ElementTypeMapArray<UInt> & rank_to_facet) {
 //   AKANTU_DEBUG_IN();
 
 //   auto spatial_dimension = mesh.getSpatialDimension();
 
 //   for (; first != last; ++first) {
 //     ElementType type = *first;
 //     UInt nb_facet = mesh.getNbElement(type, ghost_type);
 
 //     Array<UInt> & rank_to_f = rank_to_facet(type, ghost_type);
 //     rank_to_f.resize(nb_facet);
 
 //     for (UInt f = 0; f < nb_facet; ++f)
 //       rank_to_f(f) = rank;
 //   }
 
 //   AKANTU_DEBUG_OUT();
 // }
 
 // /* --------------------------------------------------------------------------
 // */ void FacetSynchronizer::buildRankToFacet(
 //     ElementTypeMapArray<UInt> & rank_to_facet,
 //     const Array<Element> * elements) {
 //   AKANTU_DEBUG_IN();
 
 //   for (UInt p = 0; p < nb_proc; ++p) {
 //     if (p == rank)
 //       continue;
 //     const Array<Element> & elem = elements[p];
 //     UInt nb_element = elem.getSize();
 
 //     for (UInt el = 0; el < nb_element; ++el) {
 //       ElementType type = elem(el).type;
 //       GhostType gt = elem(el).ghost_type;
 //       UInt el_index = elem(el).element;
 
 //       const Array<Element> & facet_to_element =
 //           mesh.getSubelementToElement(type, gt);
 //       UInt nb_facets_per_element = Mesh::getNbFacetsPerElement(type);
 //       ElementType facet_type = Mesh::getFacetType(type);
 
 //       for (UInt f = 0; f < nb_facets_per_element; ++f) {
 //         const Element & facet = facet_to_element(el_index, f);
 //         if (facet == ElementNull)
 //           continue;
 //         UInt facet_index = facet.element;
 //         GhostType facet_gt = facet.ghost_type;
 
 //         if (facet_gt == _not_ghost)
 //           continue;
 
 //         Array<UInt> & t_to_f = rank_to_facet(facet_type, facet_gt);
 //         if ((p < t_to_f(facet_index)) || (t_to_f(facet_index) == rank))
 //           t_to_f(facet_index) = p;
 //       }
 //     }
 //   }
 
 //   AKANTU_DEBUG_OUT();
 // }
 
 } // namespace akantu
diff --git a/src/synchronizer/facet_synchronizer_inline_impl.cc b/src/synchronizer/facet_synchronizer_inline_impl.cc
index 35656bd14..7d5c21329 100644
--- a/src/synchronizer/facet_synchronizer_inline_impl.cc
+++ b/src/synchronizer/facet_synchronizer_inline_impl.cc
@@ -1,127 +1,143 @@
 /**
  * @file   facet_synchronizer_inline_impl.cc
  *
+ * @author Nicolas Richart <nicolas.richart@epfl.ch>
  * @author Marco Vocialta <marco.vocialta@epfl.ch>
  *
+ * @date creation: Wed Nov 05 2014
+ * @date last modification: Tue Nov 07 2017
  *
  * @brief  facet synchronizer inline implementation
  *
  * @section LICENSE
  *
- * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * Copyright (©) 2015-2018 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
+ * Akantu is free  software: you can redistribute it and/or  modify it under the
+ * terms  of the  GNU Lesser  General Public  License as published by  the Free
+ * Software Foundation, either version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * Akantu is  distributed in the  hope that it  will be useful, but  WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
+ * details.
+ *
+ * You should  have received  a copy  of the GNU  Lesser General  Public License
+ * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
+ *
  */
 
 /* -------------------------------------------------------------------------- */
 // template<GhostType ghost_facets>
 // inline void FacetSynchronizer::getFacetGlobalConnectivity(const
 // DistributedSynchronizer & distributed_synchronizer,
 //                                                        const
 //                                                        ElementTypeMapArray<UInt>
 //                                                        & rank_to_facet,
 //                                                        const Array<Element> *
 //                                                        elements,
 //                                                        Array<ElementTypeMapArray<UInt>
 //                                                        *> & connectivity,
 //                                                        Array<ElementTypeMapArray<UInt>
 //                                                        *> & facets) {
 //   AKANTU_DEBUG_IN();
 
 //   UInt spatial_dimension = mesh.getSpatialDimension();
 
 //   /// init facet check tracking
 //   ElementTypeMapArray<bool> facet_checked("facet_checked", id);
 
 //   mesh.initElementTypeMapArray(facet_checked, 1, spatial_dimension - 1);
 
 //   Mesh::type_iterator first = mesh.firstType(spatial_dimension - 1,
 //   ghost_facets);
 //   Mesh::type_iterator last  = mesh.lastType(spatial_dimension - 1,
 //   ghost_facets);
 
 //   for (; first != last; ++first) {
 //     ElementType type = *first;
 //     Array<bool> & f_checked = facet_checked(type, ghost_facets);
 //     UInt nb_facet = mesh.getNbElement(type, ghost_facets);
 //     f_checked.resize(nb_facet);
 //   }
 
 //   const Array<UInt> & nodes_global_ids =
 //     distributed_synchronizer.mesh.getGlobalNodesIds();
 
 //   /// loop on every processor
 //   for (UInt p = 0; p < nb_proc; ++p) {
 //     if (p == rank) continue;
 
 //     /// reset facet check
 //     Mesh::type_iterator first = mesh.firstType(spatial_dimension - 1,
 //     ghost_facets);
 //     Mesh::type_iterator last  = mesh.lastType(spatial_dimension - 1,
 //     ghost_facets);
 
 //     for (; first != last; ++first) {
 //       ElementType type = *first;
 //       Array<bool> & f_checked = facet_checked(type, ghost_facets);
 //       f_checked.clear();
 //     }
 
 //     ElementTypeMapArray<UInt> & global_conn = (*connectivity(p));
 //     const Array<Element> & elem = elements[p];
 //     ElementTypeMapArray<UInt> & facet_list = (*facets(p));
 
 //     UInt nb_element = elem.getSize();
 
 //     /// loop on every send/recv element
 //     for (UInt el = 0; el < nb_element; ++el) {
 //       ElementType type = elem(el).type;
 //       GhostType gt = elem(el).ghost_type;
 //       UInt el_index = elem(el).element;
 
 //       const Array<Element> & facet_to_element =
 //      mesh.getSubelementToElement(type, gt);
 //       UInt nb_facets_per_element = Mesh::getNbFacetsPerElement(type);
 //       ElementType facet_type = Mesh::getFacetType(type);
 //       UInt nb_nodes_per_facet = Mesh::getNbNodesPerElement(facet_type);
 //       Vector<UInt> conn_tmp(nb_nodes_per_facet);
 
 //       /// loop on every facet of the element
 //       for (UInt f = 0; f < nb_facets_per_element; ++f) {
 
 //      const Element & facet = facet_to_element(el_index, f);
 //      if (facet == ElementNull) continue;
 //      UInt facet_index = facet.element;
 //      GhostType facet_gt = facet.ghost_type;
 
 //      const Array<UInt> & t_to_f = rank_to_facet(facet_type, facet_gt);
 
 //      /// exclude not ghost facets, facets assigned to other
 //      /// processors
 //      if (facet_gt != ghost_facets) continue;
 //      if ((facet_gt == _ghost) && (t_to_f(facet_index) != p)) continue;
 
 //      /// exclude facets that have already been added
 //      Array<bool> & f_checked = facet_checked(facet_type, facet_gt);
 //      if (f_checked(facet_index)) continue;
 //      else f_checked(facet_index) = true;
 
 //      /// add facet index
 //      Array<UInt> & f_list = facet_list(facet_type, facet_gt);
 //      f_list.push_back(facet_index);
 
 //      /// add sorted facet global connectivity
 //      const Array<UInt> & conn = mesh.getConnectivity(facet_type, facet_gt);
 //      Array<UInt> & g_conn = global_conn(facet_type, facet_gt);
 
 //      for (UInt n = 0; n < nb_nodes_per_facet; ++n)
 //        conn_tmp(n) = nodes_global_ids(conn(facet_index, n));
 
 //      std::sort(conn_tmp.storage(), conn_tmp.storage() + nb_nodes_per_facet);
 
 //      g_conn.push_back(conn_tmp);
 //       }
 //     }
 //   }
 
 //   AKANTU_DEBUG_OUT();
 // }
diff --git a/src/synchronizer/grid_synchronizer.cc b/src/synchronizer/grid_synchronizer.cc
index 2a2896e8f..1c4045304 100644
--- a/src/synchronizer/grid_synchronizer.cc
+++ b/src/synchronizer/grid_synchronizer.cc
@@ -1,543 +1,542 @@
 /**
  * @file   grid_synchronizer.cc
  *
  * @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Mon Oct 03 2011
- * @date last modification: Fri Jan 22 2016
+ * @date last modification: Tue Nov 07 2017
  *
  * @brief  implementation of the grid synchronizer
  *
  * @section LICENSE
  *
- * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
- * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
- * Solides)
+ * 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
+ * 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
+ * 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 "grid_synchronizer.hh"
 #include "aka_grid_dynamic.hh"
 #include "communicator.hh"
 #include "fe_engine.hh"
 #include "integration_point.hh"
 #include "mesh.hh"
 #include "mesh_io.hh"
 #include <iostream>
 
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 template <class E>
 void GridSynchronizer::createGridSynchronizer(const SpatialGrid<E> & grid) {
   AKANTU_DEBUG_IN();
 
   const Communicator & comm = this->mesh.getCommunicator();
   UInt nb_proc = comm.getNbProc();
   UInt my_rank = comm.whoAmI();
 
   if (nb_proc == 1)
     return;
 
   UInt spatial_dimension = this->mesh.getSpatialDimension();
 
   Tensor3<Real> bounding_boxes(spatial_dimension, 2, nb_proc);
   Matrix<Real> my_bounding_box = bounding_boxes(my_rank);
 
   const auto & lower = grid.getLowerBounds();
   const auto & upper = grid.getUpperBounds();
   const auto & spacing = grid.getSpacing();
 
   Vector<Real>(my_bounding_box(0)) = lower - spacing;
   Vector<Real>(my_bounding_box(1)) = upper + spacing;
 
   AKANTU_DEBUG_INFO(
       "Exchange of bounding box to detect the overlapping regions.");
 
   comm.allGather(bounding_boxes);
 
   std::vector<bool> intersects_proc(nb_proc);
   std::fill(intersects_proc.begin(), intersects_proc.end(), true);
 
   Matrix<Int> first_cells(spatial_dimension, nb_proc);
   Matrix<Int> last_cells(spatial_dimension, nb_proc);
 
   std::map<UInt, ElementTypeMapArray<UInt>> element_per_proc;
 
   // check the overlapping between my box and the one from other processors
   for (UInt p = 0; p < nb_proc; ++p) {
     if (p == my_rank)
       continue;
 
     Matrix<Real> proc_bounding_box = bounding_boxes(p);
 
     bool intersects = false;
     Vector<Int> first_cell_p = first_cells(p);
     Vector<Int> last_cell_p = last_cells(p);
     for (UInt s = 0; s < spatial_dimension; ++s) {
       // check overlapping of grid
       intersects =
           Math::intersects(my_bounding_box(s, 0), my_bounding_box(s, 1),
                            proc_bounding_box(s, 0), proc_bounding_box(s, 1));
 
       intersects_proc[p] = intersects_proc[p] & intersects;
 
       if (intersects) {
         AKANTU_DEBUG_INFO("I intersects with processor "
                           << p << " in direction " << s);
 
         // is point 1 of proc p in the dimension s in the range ?
         bool point1 =
             Math::is_in_range(proc_bounding_box(s, 0), my_bounding_box(s, 0),
                               my_bounding_box(s, 1));
 
         // is point 2 of proc p in the dimension s in the range ?
         bool point2 =
             Math::is_in_range(proc_bounding_box(s, 1), my_bounding_box(s, 0),
                               my_bounding_box(s, 1));
 
         Real start = 0.;
         Real end = 0.;
 
         if (point1 && !point2) {
           /* |-----------|         my_bounding_box(i)
            *       |-----------|   proc_bounding_box(i)
            *       1           2
            */
           start = proc_bounding_box(s, 0);
           end = my_bounding_box(s, 1);
 
           AKANTU_DEBUG_INFO("Intersection scheme 1 in direction "
                             << s << " with processor " << p << " [" << start
                             << ", " << end << "]");
         } else if (point1 && point2) {
           /* |-----------------|   my_bounding_box(i)
            *   |-----------|       proc_bounding_box(i)
            *   1           2
            */
           start = proc_bounding_box(s, 0);
           end = proc_bounding_box(s, 1);
 
           AKANTU_DEBUG_INFO("Intersection scheme 2 in direction "
                             << s << " with processor " << p << " [" << start
                             << ", " << end << "]");
         } else if (!point1 && point2) {
           /*       |-----------|   my_bounding_box(i)
            * |-----------|         proc_bounding_box(i)
            * 1           2
            */
           start = my_bounding_box(s, 0);
           end = proc_bounding_box(s, 1);
 
           AKANTU_DEBUG_INFO("Intersection scheme 3 in direction "
                             << s << " with processor " << p << " [" << start
                             << ", " << end << "]");
         } else {
           /*   |-----------|       my_bounding_box(i)
            * |-----------------|   proc_bounding_box(i)
            * 1                 2
            */
           start = my_bounding_box(s, 0);
           end = my_bounding_box(s, 1);
 
           AKANTU_DEBUG_INFO("Intersection scheme 4 in direction "
                             << s << " with processor " << p << " [" << start
                             << ", " << end << "]");
         }
 
         first_cell_p(s) = grid.getCellID(start, s);
         last_cell_p(s) = grid.getCellID(end, s);
       }
     }
 
     // create the list of cells in the overlapping
     using CellID = typename SpatialGrid<E>::CellID;
 
     std::vector<CellID> cell_ids;
 
     if (intersects_proc[p]) {
       AKANTU_DEBUG_INFO("I intersects with processor " << p);
 
       CellID cell_id(spatial_dimension);
 
       // for (UInt i = 0; i < spatial_dimension; ++i) {
       //   if(first_cell_p[i] != 0) --first_cell_p[i];
       //   if(last_cell_p[i] != 0) ++last_cell_p[i];
       // }
 
       for (Int fd = first_cell_p(0); fd <= last_cell_p(0); ++fd) {
         cell_id.setID(0, fd);
         if (spatial_dimension == 1) {
           cell_ids.push_back(cell_id);
         } else {
           for (Int sd = first_cell_p(1); sd <= last_cell_p(1); ++sd) {
             cell_id.setID(1, sd);
             if (spatial_dimension == 2) {
               cell_ids.push_back(cell_id);
             } else {
               for (Int ld = first_cell_p(2); ld <= last_cell_p(2); ++ld) {
                 cell_id.setID(2, ld);
                 cell_ids.push_back(cell_id);
               }
             }
           }
         }
       }
 
       // get the list of elements in the cells of the overlapping
       std::set<Element> to_send;
       for (auto & cur_cell_id : cell_ids) {
         auto & cell = grid.getCell(cur_cell_id);
         for (auto & element : cell) {
           to_send.insert(element);
         }
       }
 
       AKANTU_DEBUG_INFO("I have prepared " << to_send.size()
                                            << " elements to send to processor "
                                            << p);
       auto & scheme = this->getCommunications().createSendScheme(p);
       std::stringstream sstr;
       sstr << "element_per_proc_" << p;
       element_per_proc.emplace(
           std::piecewise_construct, std::forward_as_tuple(p),
           std::forward_as_tuple(sstr.str(), id, memory_id));
 
       ElementTypeMapArray<UInt> & elempproc = element_per_proc[p];
 
       for (auto elem : to_send) {
         ElementType type = elem.type;
         UInt nb_nodes_per_element = mesh.getNbNodesPerElement(type);
 
         // /!\ this part must be slow due to the access in the
         // ElementTypeMapArray<UInt>
         if (!elempproc.exists(type, _not_ghost))
           elempproc.alloc(0, nb_nodes_per_element, type, _not_ghost);
 
         Vector<UInt> global_connect(nb_nodes_per_element);
         Vector<UInt> local_connect = mesh.getConnectivity(type).begin(
             nb_nodes_per_element)[elem.element];
 
         for (UInt i = 0; i < nb_nodes_per_element; ++i) {
           global_connect(i) = mesh.getNodeGlobalId(local_connect(i));
           AKANTU_DEBUG_ASSERT(
               global_connect(i) < mesh.getNbGlobalNodes(),
               "This global node send in the connectivity does not seem correct "
                   << global_connect(i) << " corresponding to "
                   << local_connect(i) << " from element " << elem.element);
         }
 
         elempproc(type).push_back(global_connect);
         scheme.push_back(elem);
       }
     }
   }
 
   AKANTU_DEBUG_INFO("I have finished to compute intersection,"
                     << " no it's time to communicate with my neighbors");
 
   /**
    * Sending loop, sends the connectivity asynchronously to all concerned proc
    */
   std::vector<CommunicationRequest> isend_requests;
   Tensor3<UInt> space(2, _max_element_type, nb_proc);
 
   for (UInt p = 0; p < nb_proc; ++p) {
     if (p == my_rank)
       continue;
 
     if (not intersects_proc[p])
       continue;
 
     Matrix<UInt> info_proc = space(p);
     auto & elempproc = element_per_proc[p];
     UInt count = 0;
 
     for (auto type : elempproc.elementTypes(_all_dimensions, _not_ghost)) {
       Array<UInt> & conn = elempproc(type, _not_ghost);
 
       Vector<UInt> info = info_proc((UInt)type);
       info[0] = (UInt)type;
       info[1] = conn.size() * conn.getNbComponent();
 
       AKANTU_DEBUG_INFO(
           "I have " << conn.size() << " elements of type " << type
                     << " to send to processor " << p << " (communication tag : "
                     << Tag::genTag(my_rank, count, DATA_TAG) << ")");
 
       isend_requests.push_back(
           comm.asyncSend(info, p, Tag::genTag(my_rank, count, SIZE_TAG)));
 
       if (info[1] != 0)
         isend_requests.push_back(comm.asyncSend<UInt>(
             conn, p, Tag::genTag(my_rank, count, DATA_TAG)));
 
       ++count;
     }
 
     Vector<UInt> info = info_proc((UInt)_not_defined);
     info[0] = (UInt)_not_defined;
     info[1] = 0;
     isend_requests.push_back(
         comm.asyncSend(info, p, Tag::genTag(my_rank, count, SIZE_TAG)));
   }
 
   /**
    * Receives the connectivity and store them in the ghosts elements
    */
   MeshAccessor mesh_accessor(mesh);
   auto & global_nodes_ids = mesh_accessor.getNodesGlobalIds();
   auto & nodes_type = mesh_accessor.getNodesType();
 
   std::vector<CommunicationRequest> isend_nodes_requests;
   Vector<UInt> nb_nodes_to_recv(nb_proc);
 
   UInt nb_total_nodes_to_recv = 0;
   UInt nb_current_nodes = global_nodes_ids.size();
 
   NewNodesEvent new_nodes;
   NewElementsEvent new_elements;
 
   std::map<UInt, std::vector<UInt>> ask_nodes_per_proc;
 
   for (UInt p = 0; p < nb_proc; ++p) {
     nb_nodes_to_recv(p) = 0;
     if (p == my_rank)
       continue;
 
     if (!intersects_proc[p])
       continue;
 
     auto & scheme = this->getCommunications().createRecvScheme(p);
 
     ask_nodes_per_proc.emplace(std::piecewise_construct,
                                std::forward_as_tuple(p),
                                std::forward_as_tuple(0));
 
     auto & ask_nodes = ask_nodes_per_proc[p];
     UInt count = 0;
 
     ElementType type = _not_defined;
     do {
       Vector<UInt> info(2);
       comm.receive(info, p, Tag::genTag(p, count, SIZE_TAG));
 
       type = (ElementType)info[0];
 
       if (type == _not_defined)
         break;
 
       UInt nb_nodes_per_element = mesh.getNbNodesPerElement(type);
       UInt nb_element = info[1] / nb_nodes_per_element;
 
       Array<UInt> tmp_conn(nb_element, nb_nodes_per_element);
       tmp_conn.clear();
       if (info[1] != 0)
         comm.receive<UInt>(tmp_conn, p, Tag::genTag(p, count, DATA_TAG));
 
       AKANTU_DEBUG_INFO("I will receive "
                         << nb_element << " elements of type "
                         << ElementType(info[0]) << " from processor " << p
                         << " (communication tag : "
                         << Tag::genTag(p, count, DATA_TAG) << ")");
 
       auto & ghost_connectivity = mesh_accessor.getConnectivity(type, _ghost);
       auto & ghost_counter = mesh_accessor.getGhostsCounters(type, _ghost);
 
       UInt nb_ghost_element = ghost_connectivity.size();
       Element element{type, 0, _ghost};
 
       Vector<UInt> conn(nb_nodes_per_element);
       for (UInt el = 0; el < nb_element; ++el) {
         UInt nb_node_to_ask_for_elem = 0;
 
         for (UInt n = 0; n < nb_nodes_per_element; ++n) {
           UInt gn = tmp_conn(el, n);
           UInt ln = global_nodes_ids.find(gn);
 
           AKANTU_DEBUG_ASSERT(gn < mesh.getNbGlobalNodes(),
                               "This global node seems not correct "
                                   << gn << " from element " << el << " node "
                                   << n);
 
           if (ln == UInt(-1)) {
             global_nodes_ids.push_back(gn);
             nodes_type.push_back(_nt_pure_gost); // pure ghost node
             ln = nb_current_nodes;
 
             new_nodes.getList().push_back(ln);
             ++nb_current_nodes;
             ask_nodes.push_back(gn);
             ++nb_node_to_ask_for_elem;
           }
           conn[n] = ln;
         }
 
         // all the nodes are already known locally, the element should
         // already exists
         auto c = UInt(-1);
         if (nb_node_to_ask_for_elem == 0) {
           c = ghost_connectivity.find(conn);
           element.element = c;
         }
 
         if (c == UInt(-1)) {
           element.element = nb_ghost_element;
           ++nb_ghost_element;
           ghost_connectivity.push_back(conn);
           ghost_counter.push_back(1);
           new_elements.getList().push_back(element);
         } else {
           ++ghost_counter(c);
         }
 
         scheme.push_back(element);
       }
 
       count++;
     } while (type != _not_defined);
 
     AKANTU_DEBUG_INFO("I have "
                       << ask_nodes.size()
                       << " missing nodes for elements coming from processor "
                       << p << " (communication tag : "
                       << Tag::genTag(my_rank, 0, ASK_NODES_TAG) << ")");
 
     ask_nodes.push_back(UInt(-1));
 
     isend_nodes_requests.push_back(
         comm.asyncSend(ask_nodes, p, Tag::genTag(my_rank, 0, ASK_NODES_TAG)));
     nb_nodes_to_recv(p) = ask_nodes.size() - 1;
     nb_total_nodes_to_recv += nb_nodes_to_recv(p);
   }
 
   comm.waitAll(isend_requests);
   comm.freeCommunicationRequest(isend_requests);
 
   /**
    * Sends requested nodes to proc
    */
   auto & nodes = const_cast<Array<Real> &>(mesh.getNodes());
   UInt nb_nodes = nodes.size();
 
   std::vector<CommunicationRequest> isend_coordinates_requests;
   std::map<UInt, Array<Real>> nodes_to_send_per_proc;
   for (UInt p = 0; p < nb_proc; ++p) {
     if (p == my_rank || !intersects_proc[p])
       continue;
 
     Array<UInt> asked_nodes;
     CommunicationStatus status;
     AKANTU_DEBUG_INFO("Waiting list of nodes to send to processor "
                       << p << "(communication tag : "
                       << Tag::genTag(p, 0, ASK_NODES_TAG) << ")");
 
     comm.probe<UInt>(p, Tag::genTag(p, 0, ASK_NODES_TAG), status);
     UInt nb_nodes_to_send = status.size();
     asked_nodes.resize(nb_nodes_to_send);
 
     AKANTU_DEBUG_INFO("I have " << nb_nodes_to_send - 1
                                 << " nodes to send to processor " << p
                                 << " (communication tag : "
                                 << Tag::genTag(p, 0, ASK_NODES_TAG) << ")");
 
     AKANTU_DEBUG_INFO("Getting list of nodes to send to processor "
                       << p << " (communication tag : "
                       << Tag::genTag(p, 0, ASK_NODES_TAG) << ")");
 
     comm.receive(asked_nodes, p, Tag::genTag(p, 0, ASK_NODES_TAG));
 
     nb_nodes_to_send--;
     asked_nodes.resize(nb_nodes_to_send);
 
     nodes_to_send_per_proc.emplace(std::piecewise_construct,
                                    std::forward_as_tuple(p),
                                    std::forward_as_tuple(0, spatial_dimension));
 
     auto & nodes_to_send = nodes_to_send_per_proc[p];
     auto node_it = nodes.begin(spatial_dimension);
 
     for (UInt n = 0; n < nb_nodes_to_send; ++n) {
       UInt ln = global_nodes_ids.find(asked_nodes(n));
       AKANTU_DEBUG_ASSERT(ln != UInt(-1),
                           "The node [" << asked_nodes(n)
                                        << "] requested by proc " << p
                                        << " was not found locally!");
       nodes_to_send.push_back(node_it + ln);
     }
 
     if (nb_nodes_to_send != 0) {
       AKANTU_DEBUG_INFO("Sending the "
                         << nb_nodes_to_send << " nodes to processor " << p
                         << " (communication tag : "
                         << Tag::genTag(p, 0, SEND_NODES_TAG) << ")");
 
       isend_coordinates_requests.push_back(comm.asyncSend(
           nodes_to_send, p, Tag::genTag(my_rank, 0, SEND_NODES_TAG)));
     }
 #if not defined(AKANTU_NDEBUG)
     else {
       AKANTU_DEBUG_INFO("No nodes to send to processor " << p);
     }
 #endif
   }
 
   comm.waitAll(isend_nodes_requests);
   comm.freeCommunicationRequest(isend_nodes_requests);
 
   nodes.resize(nb_total_nodes_to_recv + nb_nodes);
   for (UInt p = 0; p < nb_proc; ++p) {
     if ((p != my_rank) && (nb_nodes_to_recv(p) > 0)) {
       AKANTU_DEBUG_INFO("Receiving the "
                         << nb_nodes_to_recv(p) << " nodes from processor " << p
                         << " (communication tag : "
                         << Tag::genTag(p, 0, SEND_NODES_TAG) << ")");
 
       Vector<Real> nodes_to_recv(nodes.storage() + nb_nodes * spatial_dimension,
                                  nb_nodes_to_recv(p) * spatial_dimension);
       comm.receive(nodes_to_recv, p, Tag::genTag(p, 0, SEND_NODES_TAG));
       nb_nodes += nb_nodes_to_recv(p);
     }
 #if not defined(AKANTU_NDEBUG)
     else {
       if (p != my_rank) {
         AKANTU_DEBUG_INFO("No nodes to receive from processor " << p);
       }
     }
 #endif
   }
 
   comm.waitAll(isend_coordinates_requests);
   comm.freeCommunicationRequest(isend_coordinates_requests);
 
   mesh.sendEvent(new_nodes);
   mesh.sendEvent(new_elements);
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template void GridSynchronizer::createGridSynchronizer<IntegrationPoint>(
     const SpatialGrid<IntegrationPoint> & grid);
 
 template void GridSynchronizer::createGridSynchronizer<Element>(
     const SpatialGrid<Element> & grid);
 
 } // namespace akantu
diff --git a/src/synchronizer/grid_synchronizer.hh b/src/synchronizer/grid_synchronizer.hh
index 1005d0654..62b0b039c 100644
--- a/src/synchronizer/grid_synchronizer.hh
+++ b/src/synchronizer/grid_synchronizer.hh
@@ -1,103 +1,102 @@
 /**
  * @file   grid_synchronizer.hh
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Fri Jun 18 2010
- * @date last modification: Tue Dec 08 2015
+ * @date last modification: Wed Nov 08 2017
  *
  * @brief  Synchronizer based on spatial grid
  *
  * @section LICENSE
  *
- * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
- * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
- * Solides)
+ * 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
+ * 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
+ * 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 "element_synchronizer.hh"
 #include "synchronizer_registry.hh"
 
 /* -------------------------------------------------------------------------- */
 
 #ifndef __AKANTU_GRID_SYNCHRONIZER_HH__
 #define __AKANTU_GRID_SYNCHRONIZER_HH__
 
 namespace akantu {
 
 class Mesh;
 template <class T> class SpatialGrid;
 
 class GridSynchronizer : public ElementSynchronizer {
   /* ------------------------------------------------------------------------ */
   /* Constructors/Destructors                                                 */
   /* ------------------------------------------------------------------------ */
 public:
   template <typename E>
   GridSynchronizer(Mesh & mesh, const SpatialGrid<E> & grid,
                    const ID & id = "grid_synchronizer", MemoryID memory_id = 0,
                    const bool register_to_event_manager = true,
                    EventHandlerPriority event_priority = _ehp_synchronizer);
 
   template <typename E>
   GridSynchronizer(Mesh & mesh, const SpatialGrid<E> & grid,
                    SynchronizerRegistry & synchronizer_registry,
                    const std::set<SynchronizationTag> & tags_to_register,
                    const ID & id = "grid_synchronizer", MemoryID memory_id = 0,
                    const bool register_to_event_manager = true,
                    EventHandlerPriority event_priority = _ehp_synchronizer);
 
   ~GridSynchronizer() override = default;
 
   /* ------------------------------------------------------------------------ */
   /* Methods                                                                  */
   /* ------------------------------------------------------------------------ */
 private:
   /**
    *Create the Grid Synchronizer:
    *Compute intersection and send info to neighbours that will be stored in
    *ghosts elements
    */
   template <typename E>
   void createGridSynchronizer(const SpatialGrid<E> & grid);
 
 protected:
   /// Define the tags that will be used in the send and receive instructions
   enum CommTags {
     SIZE_TAG = 0,
     DATA_TAG = 1,
     ASK_NODES_TAG = 2,
     SEND_NODES_TAG = 3
   };
 
   /* ------------------------------------------------------------------------ */
   /* Accessors                                                                */
   /* ------------------------------------------------------------------------ */
 public:
   /* ------------------------------------------------------------------------ */
   /* Class Members                                                            */
   /* ------------------------------------------------------------------------ */
 private:
 };
 
 } // namespace akantu
 
 #include "grid_synchronizer_tmpl.hh"
 
 #endif /* __AKANTU_GRID_SYNCHRONIZER_HH__ */
diff --git a/src/synchronizer/grid_synchronizer_tmpl.hh b/src/synchronizer/grid_synchronizer_tmpl.hh
index fc33da1fe..32500b7f4 100644
--- a/src/synchronizer/grid_synchronizer_tmpl.hh
+++ b/src/synchronizer/grid_synchronizer_tmpl.hh
@@ -1,73 +1,75 @@
 /**
  * @file   grid_synchronizer_tmpl.hh
  *
- * @author Nicolas Richart
+ * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
- * @date creation  Tue Jun 20 2017
+ * @date creation: Thu Jul 06 2017
+ * @date last modification: Wed Aug 09 2017
  *
- * @brief A Documented file.
+ * @brief  implementation of the templated part of the grid syncrhonizers
  *
  * @section LICENSE
  *
- * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * 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
+ * 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
+ * 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 "grid_synchronizer.hh"
 
 #ifndef __AKANTU_GRID_SYNCHRONIZER_TMPL_HH__
 #define __AKANTU_GRID_SYNCHRONIZER_TMPL_HH__
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 template <typename E>
 GridSynchronizer::GridSynchronizer(Mesh & mesh, const SpatialGrid<E> & grid,
                                    const ID & id, MemoryID memory_id,
                                    const bool register_to_event_manager,
                                    EventHandlerPriority event_priority)
     : ElementSynchronizer(mesh, id, memory_id, register_to_event_manager,
                           event_priority) {
   AKANTU_DEBUG_IN();
 
   this->createGridSynchronizer(grid);
 
   AKANTU_DEBUG_OUT();
 }
 
 template <typename E>
 GridSynchronizer::GridSynchronizer(
     Mesh & mesh, const SpatialGrid<E> & grid,
     SynchronizerRegistry & synchronizer_registry,
     const std::set<SynchronizationTag> & tags_to_register, const ID & id,
     MemoryID memory_id, const bool register_to_event_manager,
     EventHandlerPriority event_priority)
     : GridSynchronizer(mesh, grid, id, memory_id, register_to_event_manager,
                        event_priority) {
   AKANTU_DEBUG_IN();
 
   // Register the tags if any
   for (auto & tag : tags_to_register) {
     synchronizer_registry.registerSynchronizer(*this, tag);
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 } // namespace akantu
 
 #endif /* __AKANTU_GRID_SYNCHRONIZER_TMPL_HH__ */
diff --git a/src/synchronizer/master_element_info_per_processor.cc b/src/synchronizer/master_element_info_per_processor.cc
index b3b91967a..74053d36e 100644
--- a/src/synchronizer/master_element_info_per_processor.cc
+++ b/src/synchronizer/master_element_info_per_processor.cc
@@ -1,461 +1,463 @@
 /**
  * @file   master_element_info_per_processor.cc
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
- * @date   Fri Mar 11 14:57:13 2016
+ * @date creation: Wed Mar 16 2016
+ * @date last modification: Tue Feb 20 2018
  *
- * @brief
+ * @brief  Helper class to distribute a mesh
  *
  * @section LICENSE
  *
- * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * 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
+ * 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
+ * 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_iterators.hh"
 #include "communicator.hh"
 #include "element_group.hh"
 #include "element_info_per_processor.hh"
 #include "element_synchronizer.hh"
 #include "mesh_iterators.hh"
 #include "mesh_utils.hh"
 /* -------------------------------------------------------------------------- */
 #include <algorithm>
 #include <iostream>
 #include <map>
 #include <tuple>
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 MasterElementInfoPerProc::MasterElementInfoPerProc(
     ElementSynchronizer & synchronizer, UInt message_cnt, UInt root,
     ElementType type, const MeshPartition & partition)
     : ElementInfoPerProc(synchronizer, message_cnt, root, type),
       partition(partition), all_nb_local_element(nb_proc, 0),
       all_nb_ghost_element(nb_proc, 0), all_nb_element_to_send(nb_proc, 0) {
   Vector<UInt> size(5);
   size(0) = (UInt)type;
 
   if (type != _not_defined) {
     nb_nodes_per_element = Mesh::getNbNodesPerElement(type);
     nb_element = mesh.getNbElement(type);
     const auto & partition_num =
         this->partition.getPartition(this->type, _not_ghost);
     const auto & ghost_partition =
         this->partition.getGhostPartitionCSR()(this->type, _not_ghost);
 
     for (UInt el = 0; el < nb_element; ++el) {
       this->all_nb_local_element[partition_num(el)]++;
       for (auto part = ghost_partition.begin(el);
            part != ghost_partition.end(el); ++part) {
         this->all_nb_ghost_element[*part]++;
       }
       this->all_nb_element_to_send[partition_num(el)] +=
           ghost_partition.getNbCols(el) + 1;
     }
 
     /// tag info
     std::vector<std::string> tag_names;
     this->getMeshData().getTagNames(tag_names, type);
     this->nb_tags = tag_names.size();
 
     size(4) = nb_tags;
 
     for (UInt p = 0; p < nb_proc; ++p) {
       if (p != root) {
         size(1) = this->all_nb_local_element[p];
         size(2) = this->all_nb_ghost_element[p];
         size(3) = this->all_nb_element_to_send[p];
         AKANTU_DEBUG_INFO(
             "Sending connectivities informations to proc "
             << p << " TAG("
             << Tag::genTag(this->rank, this->message_count, Tag::_SIZES)
             << ")");
         comm.send(size, p,
                   Tag::genTag(this->rank, this->message_count, Tag::_SIZES));
       } else {
         this->nb_local_element = this->all_nb_local_element[p];
         this->nb_ghost_element = this->all_nb_ghost_element[p];
       }
     }
   } else {
     for (UInt p = 0; p < this->nb_proc; ++p) {
       if (p != this->root) {
         AKANTU_DEBUG_INFO(
             "Sending empty connectivities informations to proc "
             << p << " TAG("
             << Tag::genTag(this->rank, this->message_count, Tag::_SIZES)
             << ")");
         comm.send(size, p,
                   Tag::genTag(this->rank, this->message_count, Tag::_SIZES));
       }
     }
   }
 }
 
 /* ------------------------------------------------------------------------ */
 void MasterElementInfoPerProc::synchronizeConnectivities() {
   const auto & partition_num =
       this->partition.getPartition(this->type, _not_ghost);
   const auto & ghost_partition =
       this->partition.getGhostPartitionCSR()(this->type, _not_ghost);
 
   std::vector<Array<UInt>> buffers(this->nb_proc);
 
   const auto & connectivities =
       this->mesh.getConnectivity(this->type, _not_ghost);
 
   /// copying the local connectivity
   for (auto && part_conn :
        zip(partition_num,
            make_view(connectivities, this->nb_nodes_per_element))) {
     auto && part = std::get<0>(part_conn);
     auto && conn = std::get<1>(part_conn);
     for (UInt i = 0; i < conn.size(); ++i) {
       buffers[part].push_back(conn[i]);
     }
   }
 
   /// copying the connectivity of ghost element
   for (auto && tuple :
        enumerate(make_view(connectivities, this->nb_nodes_per_element))) {
     auto && el = std::get<0>(tuple);
     auto && conn = std::get<1>(tuple);
     for (auto part = ghost_partition.begin(el); part != ghost_partition.end(el);
          ++part) {
       UInt proc = *part;
       for (UInt i = 0; i < conn.size(); ++i) {
         buffers[proc].push_back(conn[i]);
       }
     }
   }
 
 #ifndef AKANTU_NDEBUG
   for (auto p : arange(this->nb_proc)) {
     UInt size = this->nb_nodes_per_element *
                 (this->all_nb_local_element[p] + this->all_nb_ghost_element[p]);
     AKANTU_DEBUG_ASSERT(
         buffers[p].size() == size,
         "The connectivity data packed in the buffer are not correct");
   }
 #endif
 
   /// send all connectivity and ghost information to all processors
   std::vector<CommunicationRequest> requests;
   for (auto p : arange(this->nb_proc)) {
     if (p == this->root)
       continue;
     auto && tag =
         Tag::genTag(this->rank, this->message_count, Tag::_CONNECTIVITY);
     AKANTU_DEBUG_INFO("Sending connectivities to proc " << p << " TAG(" << tag
                                                         << ")");
     requests.push_back(comm.asyncSend(buffers[p], p, tag));
   }
 
   Array<UInt> & old_nodes = this->getNodesGlobalIds();
 
   /// create the renumbered connectivity
   AKANTU_DEBUG_INFO("Renumbering local connectivities");
   MeshUtils::renumberMeshNodes(mesh, buffers[root], all_nb_local_element[root],
                                all_nb_ghost_element[root], type, old_nodes);
 
   comm.waitAll(requests);
   comm.freeCommunicationRequest(requests);
 }
 
 /* ------------------------------------------------------------------------ */
 void MasterElementInfoPerProc::synchronizePartitions() {
   const auto & partition_num =
       this->partition.getPartition(this->type, _not_ghost);
   const auto & ghost_partition =
       this->partition.getGhostPartitionCSR()(this->type, _not_ghost);
 
   std::vector<Array<UInt>> buffers(this->partition.getNbPartition());
 
   /// splitting the partition information to send them to processors
   Vector<UInt> count_by_proc(nb_proc, 0);
   for (UInt el = 0; el < nb_element; ++el) {
     UInt proc = partition_num(el);
     buffers[proc].push_back(ghost_partition.getNbCols(el));
 
     UInt i(0);
     for (auto part = ghost_partition.begin(el); part != ghost_partition.end(el);
          ++part, ++i) {
       buffers[proc].push_back(*part);
     }
   }
 
   for (UInt el = 0; el < nb_element; ++el) {
     UInt i(0);
     for (auto part = ghost_partition.begin(el); part != ghost_partition.end(el);
          ++part, ++i) {
       buffers[*part].push_back(partition_num(el));
     }
   }
 
 #ifndef AKANTU_NDEBUG
   for (UInt p = 0; p < this->nb_proc; ++p) {
     AKANTU_DEBUG_ASSERT(buffers[p].size() == (this->all_nb_ghost_element[p] +
                                               this->all_nb_element_to_send[p]),
                         "Data stored in the buffer are most probably wrong");
   }
 #endif
 
   std::vector<CommunicationRequest> requests;
   /// last data to compute the communication scheme
   for (UInt p = 0; p < this->nb_proc; ++p) {
     if (p == this->root)
       continue;
 
     auto && tag =
         Tag::genTag(this->rank, this->message_count, Tag::_PARTITIONS);
     AKANTU_DEBUG_INFO("Sending partition informations to proc " << p << " TAG("
                                                                 << tag << ")");
     requests.push_back(comm.asyncSend(buffers[p], p, tag));
   }
 
   if (Mesh::getSpatialDimension(this->type) ==
       this->mesh.getSpatialDimension()) {
     AKANTU_DEBUG_INFO("Creating communications scheme");
     this->fillCommunicationScheme(buffers[this->rank]);
   }
 
   comm.waitAll(requests);
   comm.freeCommunicationRequest(requests);
 }
 
 /* -------------------------------------------------------------------------- */
 void MasterElementInfoPerProc::synchronizeTags() {
   AKANTU_DEBUG_IN();
 
   if (this->nb_tags == 0) {
     AKANTU_DEBUG_OUT();
     return;
   }
 
   UInt mesh_data_sizes_buffer_length;
   auto & mesh_data = this->getMeshData();
 
   /// tag info
   std::vector<std::string> tag_names;
   mesh_data.getTagNames(tag_names, type);
   // Make sure the tags are sorted (or at least not in random order),
   // because they come from a map !!
   std::sort(tag_names.begin(), tag_names.end());
 
   // Sending information about the tags in mesh_data: name, data type and
   // number of components of the underlying array associated to the current
   // type
   DynamicCommunicationBuffer mesh_data_sizes_buffer;
   for (auto && tag_name : tag_names) {
     mesh_data_sizes_buffer << tag_name;
     mesh_data_sizes_buffer << mesh_data.getTypeCode(tag_name);
     mesh_data_sizes_buffer << mesh_data.getNbComponent(tag_name, type);
   }
 
   mesh_data_sizes_buffer_length = mesh_data_sizes_buffer.size();
   AKANTU_DEBUG_INFO(
       "Broadcasting the size of the information about the mesh data tags: ("
       << mesh_data_sizes_buffer_length << ").");
   comm.broadcast(mesh_data_sizes_buffer_length, root);
   AKANTU_DEBUG_INFO(
       "Broadcasting the information about the mesh data tags, addr "
       << (void *)mesh_data_sizes_buffer.storage());
 
   if (mesh_data_sizes_buffer_length != 0)
     comm.broadcast(mesh_data_sizes_buffer, root);
 
   if (mesh_data_sizes_buffer_length != 0) {
     // Sending the actual data to each processor
     std::vector<DynamicCommunicationBuffer> buffers(nb_proc);
     // Loop over each tag for the current type
     for (auto && tag_name : tag_names) {
       // Type code of the current tag (i.e. the tag named *names_it)
       this->fillTagBuffer(buffers, tag_name);
     }
 
     std::vector<CommunicationRequest> requests;
     for (UInt p = 0; p < nb_proc; ++p) {
       if (p == root)
         continue;
 
       auto && tag =
           Tag::genTag(this->rank, this->message_count, Tag::_MESH_DATA);
       AKANTU_DEBUG_INFO("Sending " << buffers[p].size()
                                    << " bytes of mesh data to proc " << p
                                    << " TAG(" << tag << ")");
 
       requests.push_back(comm.asyncSend(buffers[p], p, tag));
     }
 
     // Loop over each tag for the current type
     for (auto && tag_name : tag_names) {
       // Reinitializing the mesh data on the master
       this->fillMeshData(buffers[root], tag_name,
                          mesh_data.getTypeCode(tag_name),
                          mesh_data.getNbComponent(tag_name, type));
     }
 
     comm.waitAll(requests);
     comm.freeCommunicationRequest(requests);
     requests.clear();
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <typename T>
 void MasterElementInfoPerProc::fillTagBufferTemplated(
     std::vector<DynamicCommunicationBuffer> & buffers,
     const std::string & tag_name) {
   MeshData & mesh_data = this->getMeshData();
 
   const auto & data = mesh_data.getElementalDataArray<T>(tag_name, type);
   const auto & partition_num =
       this->partition.getPartition(this->type, _not_ghost);
   const auto & ghost_partition =
       this->partition.getGhostPartitionCSR()(this->type, _not_ghost);
 
   // Not possible to use the iterator because it potentially triggers the
   // creation of complex
   // type templates (such as akantu::Vector< std::vector<Element> > which don't
   // implement the right interface
   // (e.g. operator<< in that case).
   // typename Array<T>::template const_iterator< Vector<T> > data_it  =
   // data.begin(data.getNbComponent());
   // typename Array<T>::template const_iterator< Vector<T> > data_end =
   // data.end(data.getNbComponent());
 
   const T * data_it = data.storage();
   const T * data_end = data.storage() + data.size() * data.getNbComponent();
   const UInt * part = partition_num.storage();
 
   /// copying the data, element by element
   for (; data_it != data_end; ++part) {
     for (UInt j(0); j < data.getNbComponent(); ++j, ++data_it) {
       buffers[*part] << *data_it;
     }
   }
 
   data_it = data.storage();
   /// copying the data for the ghost element
   for (UInt el(0); data_it != data_end;
        data_it += data.getNbComponent(), ++el) {
     auto it = ghost_partition.begin(el);
     auto end = ghost_partition.end(el);
     for (; it != end; ++it) {
       UInt proc = *it;
       for (UInt j(0); j < data.getNbComponent(); ++j) {
         buffers[proc] << data_it[j];
       }
     }
   }
 }
 
 /* -------------------------------------------------------------------------- */
 void MasterElementInfoPerProc::fillTagBuffer(
     std::vector<DynamicCommunicationBuffer> & buffers,
     const std::string & tag_name) {
   MeshData & mesh_data = this->getMeshData();
 
 #define AKANTU_DISTRIBUTED_SYNHRONIZER_TAG_DATA(r, extra_param, elem)          \
   case BOOST_PP_TUPLE_ELEM(2, 0, elem): {                                      \
     this->fillTagBufferTemplated<BOOST_PP_TUPLE_ELEM(2, 1, elem)>(buffers,     \
                                                                   tag_name);   \
     break;                                                                     \
   }
 
   MeshDataTypeCode data_type_code = mesh_data.getTypeCode(tag_name);
   switch (data_type_code) {
     BOOST_PP_SEQ_FOR_EACH(AKANTU_DISTRIBUTED_SYNHRONIZER_TAG_DATA, ,
                           AKANTU_MESH_DATA_TYPES)
   default:
     AKANTU_ERROR("Could not obtain the type of tag" << tag_name << "!");
     break;
   }
 #undef AKANTU_DISTRIBUTED_SYNHRONIZER_TAG_DATA
 }
 
 /* -------------------------------------------------------------------------- */
 void MasterElementInfoPerProc::synchronizeGroups() {
   AKANTU_DEBUG_IN();
 
   std::vector<DynamicCommunicationBuffer> buffers(nb_proc);
 
   using ElementToGroup = std::vector<std::vector<std::string>>;
   ElementToGroup element_to_group(nb_element);
 
   for (auto & eg : ElementGroupsIterable(mesh)) {
     const auto & name = eg.getName();
 
     for (const auto & element : eg.getElements(type, _not_ghost)) {
       element_to_group[element].push_back(name);
     }
 
     auto eit = eg.begin(type, _not_ghost);
     if (eit != eg.end(type, _not_ghost))
       const_cast<Array<UInt> &>(eg.getElements(type)).empty();
   }
 
   const auto & partition_num =
       this->partition.getPartition(this->type, _not_ghost);
   const auto & ghost_partition =
       this->partition.getGhostPartitionCSR()(this->type, _not_ghost);
 
   /// copying the data, element by element
   for (auto && pair : zip(partition_num, element_to_group)) {
     buffers[std::get<0>(pair)] << std::get<1>(pair);
   }
 
   /// copying the data for the ghost element
   for (auto && pair : enumerate(element_to_group)) {
     auto && el = std::get<0>(pair);
     auto it = ghost_partition.begin(el);
     auto end = ghost_partition.end(el);
     for (; it != end; ++it) {
       UInt proc = *it;
       buffers[proc] << std::get<1>(pair);
     }
   }
 
   std::vector<CommunicationRequest> requests;
   for (UInt p = 0; p < this->nb_proc; ++p) {
     if (p == this->rank)
       continue;
 
     auto && tag = Tag::genTag(this->rank, p, Tag::_ELEMENT_GROUP);
     AKANTU_DEBUG_INFO("Sending element groups to proc " << p << " TAG(" << tag
                                                         << ")");
     requests.push_back(comm.asyncSend(buffers[p], p, tag));
   }
 
   this->fillElementGroupsFromBuffer(buffers[this->rank]);
 
   comm.waitAll(requests);
   comm.freeCommunicationRequest(requests);
   requests.clear();
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 
 } // namespace akantu
diff --git a/src/synchronizer/mpi_communicator_data.hh b/src/synchronizer/mpi_communicator_data.hh
index be387e22b..f85d30c8b 100644
--- a/src/synchronizer/mpi_communicator_data.hh
+++ b/src/synchronizer/mpi_communicator_data.hh
@@ -1,135 +1,134 @@
 /**
- * @file   mpi_type_wrapper.hh
+ * @file   mpi_communicator_data.hh
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Mon Jun 14 2010
- * @date last modification: Wed Oct 07 2015
+ * @date last modification: Mon Feb 05 2018
  *
  * @brief  Wrapper on MPI types to have a better separation between libraries
  *
  * @section LICENSE
  *
- * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
- * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
- * Solides)
+ * 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
+ * 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
+ * A PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 #if defined(__INTEL_COMPILER)
 //#pragma warning ( disable : 383 )
 #elif defined(__clang__) // test clang to be sure that when we test for gnu it
 // is only gnu
 #elif (defined(__GNUC__) || defined(__GNUG__))
 #if __cplusplus > 199711L
 #pragma GCC diagnostic push
 #pragma GCC diagnostic ignored "-Wliteral-suffix"
 #endif
 #endif
 
 #include <mpi.h>
 
 #if defined(__INTEL_COMPILER)
 //#pragma warning ( disable : 383 )
 #elif defined(__clang__) // test clang to be sure that when we test for gnu it
 // is only gnu
 #elif (defined(__GNUC__) || defined(__GNUG__))
 #if __cplusplus > 199711L
 #pragma GCC diagnostic pop
 #endif
 #endif
 
 /* -------------------------------------------------------------------------- */
 #include "communicator.hh"
 /* -------------------------------------------------------------------------- */
 #include <unordered_map>
 /* -------------------------------------------------------------------------- */
 
 #ifndef __AKANTU_MPI_TYPE_WRAPPER_HH__
 #define __AKANTU_MPI_TYPE_WRAPPER_HH__
 
 namespace akantu {
 
 class MPICommunicatorData : public CommunicatorInternalData {
 public:
   MPICommunicatorData() {
     MPI_Initialized(&is_externaly_initialized);
     if (!is_externaly_initialized) {
       MPI_Init(nullptr, nullptr); // valid according to the spec
     }
 
     MPI_Comm_create_errhandler(MPICommunicatorData::errorHandler,
                                &error_handler);
     MPI_Comm_set_errhandler(MPI_COMM_WORLD, error_handler);
     setMPICommunicator(MPI_COMM_WORLD);
   }
 
   ~MPICommunicatorData() override {
     if (not is_externaly_initialized) {
       MPI_Finalize();
     }
   }
 
   inline void setMPICommunicator(MPI_Comm comm) {
     MPI_Comm_set_errhandler(communicator, save_error_handler);
     communicator = comm;
     MPI_Comm_get_errhandler(comm, &save_error_handler);
     MPI_Comm_set_errhandler(comm, error_handler);
   }
 
   inline int rank() const {
     int prank;
     MPI_Comm_rank(communicator, &prank);
     return prank;
   }
 
   inline int size() const {
     int psize;
     MPI_Comm_size(communicator, &psize);
     return psize;
   }
 
   inline MPI_Comm getMPICommunicator() const { return communicator; }
   inline int getMaxTag() const {
     int flag;
     int * value;
     MPI_Comm_get_attr(communicator, MPI_TAG_UB, &value, &flag);
     AKANTU_DEBUG_ASSERT(flag, "No attribute MPI_TAG_UB.");
     return *value;
   }
 
 private:
   MPI_Comm communicator{MPI_COMM_WORLD};
   MPI_Errhandler save_error_handler{MPI_ERRORS_ARE_FATAL};
   static int is_externaly_initialized;
   /* ------------------------------------------------------------------------ */
   MPI_Errhandler error_handler;
 
   static void errorHandler(MPI_Comm * /*comm*/, int * error_code, ...) {
     char error_string[MPI_MAX_ERROR_STRING];
     int str_len;
     MPI_Error_string(*error_code, error_string, &str_len);
     AKANTU_CUSTOM_EXCEPTION_INFO(debug::CommunicationException(),
                                  "MPI failed with the error code "
                                      << *error_code << ": \"" << error_string
                                      << "\"");
   }
 };
 
 } // namespace akantu
 
 #endif /* __AKANTU_MPI_TYPE_WRAPPER_HH__ */
diff --git a/src/synchronizer/node_info_per_processor.cc b/src/synchronizer/node_info_per_processor.cc
index 3b4a73b32..bed5332f1 100644
--- a/src/synchronizer/node_info_per_processor.cc
+++ b/src/synchronizer/node_info_per_processor.cc
@@ -1,497 +1,499 @@
 /**
  * @file   node_info_per_processor.cc
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
- * @date   Fri Mar 11 15:49:43 2016
+ * @date creation: Wed Mar 16 2016
+ * @date last modification: Wed Nov 08 2017
  *
- * @brief
+ * @brief  Please type the brief for file: Helper classes to create the
+ * distributed synchronizer and distribute a mesh
  *
  * @section LICENSE
  *
- * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * 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
+ * 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
+ * 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 "node_info_per_processor.hh"
 #include "communicator.hh"
 #include "node_group.hh"
 #include "node_synchronizer.hh"
 /* -------------------------------------------------------------------------- */
 #include <algorithm>
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 NodeInfoPerProc::NodeInfoPerProc(NodeSynchronizer & synchronizer,
                                  UInt message_cnt, UInt root)
     : MeshAccessor(synchronizer.getMesh()), synchronizer(synchronizer),
       comm(synchronizer.getCommunicator()), rank(comm.whoAmI()),
       nb_proc(comm.getNbProc()), root(root), mesh(synchronizer.getMesh()),
       spatial_dimension(synchronizer.getMesh().getSpatialDimension()),
       message_count(message_cnt) {}
 
 /* -------------------------------------------------------------------------- */
 template <class CommunicationBuffer>
 void NodeInfoPerProc::fillNodeGroupsFromBuffer(CommunicationBuffer & buffer) {
   AKANTU_DEBUG_IN();
 
   std::vector<std::vector<std::string>> node_to_group;
 
   buffer >> node_to_group;
 
   AKANTU_DEBUG_ASSERT(node_to_group.size() == mesh.getNbGlobalNodes(),
                       "Not the good amount of nodes where transmitted");
 
   const auto & global_nodes = mesh.getGlobalNodesIds();
 
   auto nbegin = global_nodes.begin();
   auto nit = global_nodes.begin();
   auto nend = global_nodes.end();
   for (; nit != nend; ++nit) {
     auto it = node_to_group[*nit].begin();
     auto end = node_to_group[*nit].end();
 
     for (; it != end; ++it) {
       mesh.getNodeGroup(*it).add(nit - nbegin, false);
     }
   }
 
   GroupManager::const_node_group_iterator ngi = mesh.node_group_begin();
   GroupManager::const_node_group_iterator nge = mesh.node_group_end();
   for (; ngi != nge; ++ngi) {
     NodeGroup & ng = *(ngi->second);
     ng.optimize();
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void NodeInfoPerProc::fillNodesType() {
   AKANTU_DEBUG_IN();
 
   UInt nb_nodes = mesh.getNbNodes();
   Array<NodeType> & nodes_type = this->getNodesType();
 
   Array<UInt> nodes_set(nb_nodes);
   nodes_set.set(0);
 
   enum NodeSet {
     NORMAL_SET = 1,
     GHOST_SET = 2,
   };
 
   Array<bool> already_seen(nb_nodes, 1, false);
 
   for (UInt g = _not_ghost; g <= _ghost; ++g) {
     auto gt = (GhostType)g;
     UInt set = NORMAL_SET;
     if (gt == _ghost)
       set = GHOST_SET;
 
     already_seen.set(false);
     Mesh::type_iterator it =
         mesh.firstType(_all_dimensions, gt, _ek_not_defined);
     Mesh::type_iterator end =
         mesh.lastType(_all_dimensions, gt, _ek_not_defined);
     for (; it != end; ++it) {
       ElementType type = *it;
 
       UInt nb_nodes_per_element = Mesh::getNbNodesPerElement(type);
       UInt nb_element = mesh.getNbElement(type, gt);
       Array<UInt>::const_vector_iterator conn_it =
           mesh.getConnectivity(type, gt).begin(nb_nodes_per_element);
 
       for (UInt e = 0; e < nb_element; ++e, ++conn_it) {
         const Vector<UInt> & conn = *conn_it;
         for (UInt n = 0; n < nb_nodes_per_element; ++n) {
           AKANTU_DEBUG_ASSERT(conn(n) < nb_nodes,
                               "Node " << conn(n)
                                       << " bigger than number of nodes "
                                       << nb_nodes);
           if (!already_seen(conn(n))) {
             nodes_set(conn(n)) += set;
             already_seen(conn(n)) = true;
           }
         }
       }
     }
   }
 
   for (UInt i = 0; i < nb_nodes; ++i) {
     if (nodes_set(i) == NORMAL_SET)
       nodes_type(i) = _nt_normal;
     else if (nodes_set(i) == GHOST_SET)
       nodes_type(i) = _nt_pure_gost;
     else if (nodes_set(i) == (GHOST_SET + NORMAL_SET))
       nodes_type(i) = _nt_master;
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void NodeInfoPerProc::fillCommunicationScheme(const Array<UInt> & master_info) {
   AKANTU_DEBUG_IN();
 
   Communications<UInt> & communications =
       this->synchronizer.getCommunications();
 
   { // send schemes
     auto it = master_info.begin_reinterpret(2, master_info.size() / 2);
     auto end = master_info.end_reinterpret(2, master_info.size() / 2);
 
     std::map<UInt, Array<UInt>> send_array_per_proc;
 
     for (; it != end; ++it) {
       const Vector<UInt> & send_info = *it;
 
       send_array_per_proc[send_info(0)].push_back(send_info(1));
     }
 
     for (auto & send_schemes : send_array_per_proc) {
       auto & scheme = communications.createSendScheme(send_schemes.first);
 
       auto & sends = send_schemes.second;
       std::sort(sends.begin(), sends.end());
       std::transform(sends.begin(), sends.end(), sends.begin(),
                      [this](UInt g) -> UInt { return mesh.getNodeLocalId(g); });
       scheme.copy(sends);
     }
   }
 
   { // receive schemes
     const Array<NodeType> & nodes_type = this->getNodesType();
 
     std::map<UInt, Array<UInt>> recv_array_per_proc;
 
     UInt node = 0;
     for (auto & node_type : nodes_type) {
       if (Int(node_type) >= 0) {
         recv_array_per_proc[node_type].push_back(mesh.getNodeGlobalId(node));
       }
       ++node;
     }
 
     for (auto & recv_schemes : recv_array_per_proc) {
       auto & scheme = communications.createRecvScheme(recv_schemes.first);
 
       auto & recvs = recv_schemes.second;
       std::sort(recvs.begin(), recvs.end());
       std::transform(recvs.begin(), recvs.end(), recvs.begin(),
                      [this](UInt g) -> UInt { return mesh.getNodeLocalId(g); });
 
       scheme.copy(recvs);
     }
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 /* -------------------------------------------------------------------------- */
 
 /* -------------------------------------------------------------------------- */
 MasterNodeInfoPerProc::MasterNodeInfoPerProc(NodeSynchronizer & synchronizer,
                                              UInt message_cnt, UInt root)
     : NodeInfoPerProc(synchronizer, message_cnt, root) {
   UInt nb_global_nodes = this->mesh.getNbGlobalNodes();
   this->comm.broadcast(nb_global_nodes, this->root);
 }
 
 /* -------------------------------------------------------------------------- */
 void MasterNodeInfoPerProc::synchronizeNodes() {
   this->nodes_per_proc.resize(nb_proc);
   this->nb_nodes_per_proc.resize(nb_proc);
 
   Array<Real> local_nodes(0, spatial_dimension);
   Array<Real> & nodes = this->getNodes();
 
   for (UInt p = 0; p < nb_proc; ++p) {
     UInt nb_nodes = 0;
     //      UInt * buffer;
     Array<Real> * nodes_to_send;
 
     Array<UInt> & nodespp = nodes_per_proc[p];
     if (p != root) {
       nodes_to_send = new Array<Real>(0, spatial_dimension);
       AKANTU_DEBUG_INFO("Receiving number of nodes from proc "
                         << p << " " << Tag::genTag(p, 0, Tag::_NB_NODES));
       comm.receive(nb_nodes, p, Tag::genTag(p, 0, Tag::_NB_NODES));
       nodespp.resize(nb_nodes);
       this->nb_nodes_per_proc(p) = nb_nodes;
 
       AKANTU_DEBUG_INFO("Receiving list of nodes from proc "
                         << p << " " << Tag::genTag(p, 0, Tag::_NODES));
       comm.receive(nodespp, p, Tag::genTag(p, 0, Tag::_NODES));
     } else {
       Array<UInt> & local_ids = this->getNodesGlobalIds();
       this->nb_nodes_per_proc(p) = local_ids.size();
       nodespp.copy(local_ids);
       nodes_to_send = &local_nodes;
     }
 
     Array<UInt>::const_scalar_iterator it = nodespp.begin();
     Array<UInt>::const_scalar_iterator end = nodespp.end();
     /// get the coordinates for the selected nodes
     for (; it != end; ++it) {
       Vector<Real> coord(nodes.storage() + spatial_dimension * *it,
                          spatial_dimension);
       nodes_to_send->push_back(coord);
     }
 
     if (p != root) { /// send them for distant processors
       AKANTU_DEBUG_INFO("Sending coordinates to proc "
                         << p << " "
                         << Tag::genTag(this->rank, 0, Tag::_COORDINATES));
       comm.send(*nodes_to_send, p,
                 Tag::genTag(this->rank, 0, Tag::_COORDINATES));
       delete nodes_to_send;
     }
   }
 
   /// construct the local nodes coordinates
   nodes.copy(local_nodes);
 }
 
 /* -------------------------------------------------------------------------- */
 void MasterNodeInfoPerProc::synchronizeTypes() {
   //           <global_id,     <proc, local_id> >
   std::multimap<UInt, std::pair<UInt, UInt>> nodes_to_proc;
   std::vector<Array<NodeType>> nodes_type_per_proc(nb_proc);
 
   // arrays containing pairs of (proc, node)
   std::vector<Array<UInt>> nodes_to_send_per_proc(nb_proc);
   for (UInt p = 0; p < nb_proc; ++p) {
     nodes_type_per_proc[p].resize(nb_nodes_per_proc(p));
   }
 
   this->fillNodesType();
 
   for (UInt p = 0; p < nb_proc; ++p) {
     auto & nodes_types = nodes_type_per_proc[p];
     if (p != root) {
       AKANTU_DEBUG_INFO(
           "Receiving first nodes types from proc "
           << p << " "
           << Tag::genTag(this->rank, this->message_count, Tag::_NODES_TYPE));
       comm.receive(nodes_types, p, Tag::genTag(p, 0, Tag::_NODES_TYPE));
     } else {
       nodes_types.copy(this->getNodesType());
     }
 
     // stack all processors claiming to be master for a node
     for (UInt local_node = 0; local_node < nb_nodes_per_proc(p); ++local_node) {
       if (nodes_types(local_node) == _nt_master) {
         UInt global_node = nodes_per_proc[p](local_node);
         nodes_to_proc.insert(
             std::make_pair(global_node, std::make_pair(p, local_node)));
       }
     }
   }
 
   for (UInt i = 0; i < mesh.getNbGlobalNodes(); ++i) {
     auto it_range = nodes_to_proc.equal_range(i);
     if (it_range.first == nodes_to_proc.end() || it_range.first->first != i)
       continue;
 
     // pick the first processor out of the multi-map as the actual master
     UInt master_proc = (it_range.first)->second.first;
     for (auto it_node = it_range.first; it_node != it_range.second; ++it_node) {
       UInt proc = it_node->second.first;
       UInt node = it_node->second.second;
       if (proc != master_proc) {
         // store the info on all the slaves for a given master
         nodes_type_per_proc[proc](node) = NodeType(master_proc);
         nodes_to_send_per_proc[master_proc].push_back(proc);
         nodes_to_send_per_proc[master_proc].push_back(i);
       }
     }
   }
 
   std::vector<CommunicationRequest> requests_send_type;
   std::vector<CommunicationRequest> requests_send_master_info;
   for (UInt p = 0; p < nb_proc; ++p) {
     if (p != root) {
       AKANTU_DEBUG_INFO("Sending nodes types to proc "
                         << p << " "
                         << Tag::genTag(this->rank, 0, Tag::_NODES_TYPE));
       requests_send_type.push_back(
           comm.asyncSend(nodes_type_per_proc[p], p,
                          Tag::genTag(this->rank, 0, Tag::_NODES_TYPE)));
 
       auto & nodes_to_send = nodes_to_send_per_proc[p];
 
       /// push back an element to avoid a send of size 0
       nodes_to_send.push_back(-1);
 
       AKANTU_DEBUG_INFO("Sending nodes master info to proc "
                         << p << " "
                         << Tag::genTag(this->rank, 1, Tag::_NODES_TYPE));
       requests_send_master_info.push_back(comm.asyncSend(
           nodes_to_send, p, Tag::genTag(this->rank, 1, Tag::_NODES_TYPE)));
     } else {
       this->getNodesType().copy(nodes_type_per_proc[p]);
 
       this->fillCommunicationScheme(nodes_to_send_per_proc[root]);
     }
   }
 
   comm.waitAll(requests_send_type);
   comm.freeCommunicationRequest(requests_send_type);
   requests_send_type.clear();
 
   comm.waitAll(requests_send_master_info);
   comm.freeCommunicationRequest(requests_send_master_info);
 }
 
 /* -------------------------------------------------------------------------- */
 void MasterNodeInfoPerProc::synchronizeGroups() {
   AKANTU_DEBUG_IN();
 
   UInt nb_total_nodes = mesh.getNbGlobalNodes();
 
   DynamicCommunicationBuffer buffer;
 
   using NodeToGroup = std::vector<std::vector<std::string>>;
   NodeToGroup node_to_group;
   node_to_group.resize(nb_total_nodes);
 
   GroupManager::const_node_group_iterator ngi = mesh.node_group_begin();
   GroupManager::const_node_group_iterator nge = mesh.node_group_end();
   for (; ngi != nge; ++ngi) {
     NodeGroup & ng = *(ngi->second);
 
     std::string name = ngi->first;
 
     NodeGroup::const_node_iterator nit = ng.begin();
     NodeGroup::const_node_iterator nend = ng.end();
     for (; nit != nend; ++nit) {
       node_to_group[*nit].push_back(name);
     }
 
     nit = ng.begin();
     if (nit != nend)
       ng.empty();
   }
 
   buffer << node_to_group;
 
   std::vector<CommunicationRequest> requests;
   for (UInt p = 0; p < nb_proc; ++p) {
     if (p == this->rank)
       continue;
     AKANTU_DEBUG_INFO("Sending node groups to proc "
                       << p << " "
                       << Tag::genTag(this->rank, p, Tag::_NODE_GROUP));
     requests.push_back(comm.asyncSend(
         buffer, p, Tag::genTag(this->rank, p, Tag::_NODE_GROUP)));
   }
 
   this->fillNodeGroupsFromBuffer(buffer);
 
   comm.waitAll(requests);
   comm.freeCommunicationRequest(requests);
   requests.clear();
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 /* -------------------------------------------------------------------------- */
 
 /* -------------------------------------------------------------------------- */
 SlaveNodeInfoPerProc::SlaveNodeInfoPerProc(NodeSynchronizer & synchronizer,
                                            UInt message_cnt, UInt root)
     : NodeInfoPerProc(synchronizer, message_cnt, root) {
   UInt nb_global_nodes = 0;
   comm.broadcast(nb_global_nodes, root);
   this->setNbGlobalNodes(nb_global_nodes);
 }
 
 /* -------------------------------------------------------------------------- */
 void SlaveNodeInfoPerProc::synchronizeNodes() {
   AKANTU_DEBUG_INFO("Sending list of nodes to proc "
                     << root << " " << Tag::genTag(this->rank, 0, Tag::_NB_NODES)
                     << " " << Tag::genTag(this->rank, 0, Tag::_NODES));
   Array<UInt> & local_ids = this->getNodesGlobalIds();
   Array<Real> & nodes = this->getNodes();
 
   UInt nb_nodes = local_ids.size();
   comm.send(nb_nodes, root, Tag::genTag(this->rank, 0, Tag::_NB_NODES));
   comm.send(local_ids, root, Tag::genTag(this->rank, 0, Tag::_NODES));
 
   /* --------<<<<-COORDINATES---------------------------------------------- */
   nodes.resize(nb_nodes);
   AKANTU_DEBUG_INFO("Receiving coordinates from proc "
                     << root << " " << Tag::genTag(root, 0, Tag::_COORDINATES));
   comm.receive(nodes, root, Tag::genTag(root, 0, Tag::_COORDINATES));
 }
 
 /* -------------------------------------------------------------------------- */
 void SlaveNodeInfoPerProc::synchronizeTypes() {
   this->fillNodesType();
 
   Array<NodeType> & nodes_types = this->getNodesType();
 
   AKANTU_DEBUG_INFO("Sending first nodes types to proc "
                     << root << ""
                     << Tag::genTag(this->rank, 0, Tag::_NODES_TYPE));
   comm.send(nodes_types, root, Tag::genTag(this->rank, 0, Tag::_NODES_TYPE));
 
   AKANTU_DEBUG_INFO("Receiving nodes types from proc "
                     << root << " " << Tag::genTag(root, 0, Tag::_NODES_TYPE));
   comm.receive(nodes_types, root, Tag::genTag(root, 0, Tag::_NODES_TYPE));
 
   AKANTU_DEBUG_INFO("Receiving nodes master info from proc "
                     << root << " " << Tag::genTag(root, 1, Tag::_NODES_TYPE));
   CommunicationStatus status;
   comm.probe<UInt>(root, Tag::genTag(root, 1, Tag::_NODES_TYPE), status);
 
   Array<UInt> nodes_master_info(status.size());
 
   comm.receive(nodes_master_info, root, Tag::genTag(root, 1, Tag::_NODES_TYPE));
 
   nodes_master_info.resize(nodes_master_info.size() - 1);
 
   this->fillCommunicationScheme(nodes_master_info);
 }
 
 /* -------------------------------------------------------------------------- */
 void SlaveNodeInfoPerProc::synchronizeGroups() {
   AKANTU_DEBUG_IN();
 
   AKANTU_DEBUG_INFO("Receiving node groups from proc "
                     << root << " "
                     << Tag::genTag(root, this->rank, Tag::_NODE_GROUP));
 
   CommunicationStatus status;
   comm.probe<char>(root, Tag::genTag(root, this->rank, Tag::_NODE_GROUP),
                    status);
 
   CommunicationBuffer buffer(status.size());
   comm.receive(buffer, root, Tag::genTag(root, this->rank, Tag::_NODE_GROUP));
 
   this->fillNodeGroupsFromBuffer(buffer);
 
   AKANTU_DEBUG_OUT();
 }
 
 } // akantu
diff --git a/src/synchronizer/node_info_per_processor.hh b/src/synchronizer/node_info_per_processor.hh
index da67e5479..1bb583524 100644
--- a/src/synchronizer/node_info_per_processor.hh
+++ b/src/synchronizer/node_info_per_processor.hh
@@ -1,107 +1,108 @@
 /**
  * @file   node_info_per_processor.hh
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
- * @date   Fri Mar 11 14:45:15 2016
+ * @date creation: Wed Mar 16 2016
+ * @date last modification: Wed Nov 08 2017
  *
  * @brief  Helper classes to create the distributed synchronizer and distribute
- *         a mesh
+ * a mesh
  *
  * @section LICENSE
  *
- * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * 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
+ * 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
+ * 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 "mesh_accessor.hh"
 /* -------------------------------------------------------------------------- */
 
 #ifndef __AKANTU_NODE_INFO_PER_PROCESSOR_HH__
 #define __AKANTU_NODE_INFO_PER_PROCESSOR_HH__
 
 namespace akantu {
 class NodeSynchronizer;
 class Communicator;
 }
 
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 
 class NodeInfoPerProc : protected MeshAccessor {
 public:
   NodeInfoPerProc(NodeSynchronizer & synchronizer, UInt message_cnt, UInt root);
 
   virtual void synchronizeNodes() = 0;
   virtual void synchronizeTypes() = 0;
   virtual void synchronizeGroups() = 0;
 
 protected:
   template <class CommunicationBuffer>
   void fillNodeGroupsFromBuffer(CommunicationBuffer & buffer);
   void fillNodesType();
 
   void fillCommunicationScheme(const Array<UInt> &);
 
 protected:
   NodeSynchronizer & synchronizer;
   const Communicator & comm;
   UInt rank;
   UInt nb_proc;
   UInt root;
 
   Mesh & mesh;
 
   UInt spatial_dimension;
 
   UInt message_count;
 };
 
 /* -------------------------------------------------------------------------- */
 class MasterNodeInfoPerProc : protected NodeInfoPerProc {
 public:
   MasterNodeInfoPerProc(NodeSynchronizer & synchronizer, UInt message_cnt,
                         UInt root);
 
   void synchronizeNodes() override;
   void synchronizeTypes() override;
   void synchronizeGroups() override;
 
 private:
   /// get the list of nodes to send and send them
   std::vector<Array<UInt>> nodes_per_proc;
   Array<UInt> nb_nodes_per_proc;
 };
 
 /* -------------------------------------------------------------------------- */
 class SlaveNodeInfoPerProc : protected NodeInfoPerProc {
 public:
   SlaveNodeInfoPerProc(NodeSynchronizer & synchronizer, UInt message_cnt,
                        UInt root);
 
   void synchronizeNodes() override;
   void synchronizeTypes() override;
   void synchronizeGroups() override;
 
 private:
 };
 
 } // akantu
 
 #endif /* __AKANTU_NODE_INFO_PER_PROCESSOR_HH__ */
diff --git a/src/synchronizer/node_synchronizer.cc b/src/synchronizer/node_synchronizer.cc
index 7610c7a3a..15c889ffb 100644
--- a/src/synchronizer/node_synchronizer.cc
+++ b/src/synchronizer/node_synchronizer.cc
@@ -1,121 +1,122 @@
 /**
  * @file   node_synchronizer.cc
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
- * @date   Fri Sep 23 12:01:24 2016
+ * @date creation: Fri Jun 18 2010
+ * @date last modification: Wed Nov 15 2017
  *
  * @brief  Implementation of the node synchronizer
  *
  * @section LICENSE
  *
- * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * 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
+ * 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
+ * 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 "node_synchronizer.hh"
 #include "mesh.hh"
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 NodeSynchronizer::NodeSynchronizer(Mesh & mesh, const ID & id,
                                    MemoryID memory_id,
                                    const bool register_to_event_manager,
                                    EventHandlerPriority event_priority)
     : SynchronizerImpl<UInt>(mesh.getCommunicator(), id, memory_id),
       mesh(mesh) {
   AKANTU_DEBUG_IN();
 
   if (register_to_event_manager) {
     this->mesh.registerEventHandler(*this, event_priority);
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 NodeSynchronizer::~NodeSynchronizer() = default;
 
 /* -------------------------------------------------------------------------- */
 void NodeSynchronizer::onNodesAdded(const Array<UInt> & nodes_list,
                                     const NewNodesEvent &) {
   std::map<UInt, std::vector<UInt>> nodes_per_proc;
   Array<UInt> sizes_per_proc(nb_proc, nb_proc, UInt(0));
   Vector<UInt> local_sizes_per_proc = sizes_per_proc.begin(nb_proc)[rank];
 
   for (auto & local_id : nodes_list) {
     auto type = mesh.getNodeType(local_id);
     if (type < 0)
       continue; // local, master or pure ghost
 
     auto global_id = mesh.getNodeGlobalId(local_id);
     auto proc = UInt(type);
     nodes_per_proc[proc].push_back(global_id);
     ++local_sizes_per_proc[proc];
 
     auto & scheme = communications.getScheme(proc, _recv);
     scheme.push_back(local_id);
   }
 
   communicator.allGather(sizes_per_proc);
   std::vector<CommunicationRequest> send_request_per_proc,
       recv_request_per_proc;
   std::map<UInt, std::vector<UInt>> nodes_needed_by_proc;
   for (UInt proc = 0; proc < nb_proc; ++proc) {
     auto size = sizes_per_proc(proc, rank);
     if (size == 0)
       continue;
 
     nodes_needed_by_proc[proc].resize(size);
     recv_request_per_proc.push_back(communicator.asyncReceive(
         nodes_needed_by_proc[proc], proc, Tag::genTag(rank, 0, 0)));
   }
 
   for (auto & pair : nodes_per_proc) {
     auto proc = pair.first;
     auto & nodes = pair.second;
 
     send_request_per_proc.push_back(
         communicator.asyncSend(nodes, proc, Tag::genTag(proc, 0, 0)));
   }
 
   UInt req_nb;
   while ((req_nb = communicator.waitAny(recv_request_per_proc)) != UInt(-1)) {
     auto & request = recv_request_per_proc[req_nb];
     auto proc = request.getSource();
 
     auto & nodes = nodes_needed_by_proc[proc];
 
     auto & scheme = communications.getScheme(proc, _send);
     for (auto global_id : nodes) {
       auto local_id = mesh.getNodeLocalId(global_id);
       AKANTU_DEBUG_ASSERT(local_id != UInt(-1),
                           "The global node "
                               << global_id << "is not known on rank " << rank);
       scheme.push_back(local_id);
     }
     recv_request_per_proc.erase(recv_request_per_proc.begin() + req_nb);
   }
 
   communicator.waitAll(send_request_per_proc);
   communicator.freeCommunicationRequest(send_request_per_proc);
 }
 
 } // namespace akantu
diff --git a/src/synchronizer/node_synchronizer.hh b/src/synchronizer/node_synchronizer.hh
index cc600ca2b..5378ef648 100644
--- a/src/synchronizer/node_synchronizer.hh
+++ b/src/synchronizer/node_synchronizer.hh
@@ -1,86 +1,87 @@
 /**
  * @file   node_synchronizer.hh
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
- * @date   Fri Sep 23 11:45:24 2016
+ * @date creation: Tue Nov 08 2016
+ * @date last modification: Tue Feb 20 2018
  *
  * @brief  Synchronizer for nodal information
  *
  * @section LICENSE
  *
- * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * 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
+ * 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
+ * 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 "mesh_events.hh"
 #include "synchronizer_impl.hh"
 /* -------------------------------------------------------------------------- */
 #include <unordered_map>
 /* -------------------------------------------------------------------------- */
 
 #ifndef __AKANTU_NODE_SYNCHRONIZER_HH__
 #define __AKANTU_NODE_SYNCHRONIZER_HH__
 
 namespace akantu {
 
 class NodeSynchronizer : public MeshEventHandler,
                          public SynchronizerImpl<UInt> {
 public:
   NodeSynchronizer(Mesh & mesh, const ID & id = "element_synchronizer",
                    MemoryID memory_id = 0,
                    const bool register_to_event_manager = true,
                    EventHandlerPriority event_priority = _ehp_synchronizer);
 
   ~NodeSynchronizer() override;
 
   friend class NodeInfoPerProc;
 
   /// function to implement to react on  akantu::NewNodesEvent
   void onNodesAdded(const Array<UInt> &, const NewNodesEvent &) override;
 
   /// function to implement to react on  akantu::RemovedNodesEvent
   void onNodesRemoved(const Array<UInt> &, const Array<UInt> &,
                       const RemovedNodesEvent &) override {}
   /// function to implement to react on  akantu::NewElementsEvent
   void onElementsAdded(const Array<Element> &,
                        const NewElementsEvent &) override {}
   /// function to implement to react on  akantu::RemovedElementsEvent
   void onElementsRemoved(const Array<Element> &,
                          const ElementTypeMapArray<UInt> &,
                          const RemovedElementsEvent &) override {}
   /// function to implement to react on  akantu::ChangedElementsEvent
   void onElementsChanged(const Array<Element> &, const Array<Element> &,
                          const ElementTypeMapArray<UInt> &,
                          const ChangedElementsEvent &) override {}
 
 public:
   AKANTU_GET_MACRO(Mesh, mesh, Mesh &);
 
 protected:
   Int getRank(const UInt & /*node*/) const final { AKANTU_TO_IMPLEMENT(); }
 
 protected:
   Mesh & mesh;
 
   // std::unordered_map<UInt, Int> node_to_prank;
 };
 
 } // namespace akantu
 
 #endif /* __AKANTU_NODE_SYNCHRONIZER_HH__ */
diff --git a/src/synchronizer/slave_element_info_per_processor.cc b/src/synchronizer/slave_element_info_per_processor.cc
index 0d9415e1a..e38400012 100644
--- a/src/synchronizer/slave_element_info_per_processor.cc
+++ b/src/synchronizer/slave_element_info_per_processor.cc
@@ -1,197 +1,198 @@
 /**
  * @file   slave_element_info_per_processor.cc
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
- * @date   Fri Mar 11 14:59:21 2016
+ * @date creation: Wed Mar 16 2016
+ * @date last modification: Tue Nov 07 2017
  *
- * @brief
+ * @brief  Helper class to distribute a mesh
  *
  * @section LICENSE
  *
- * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * 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
+ * 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
+ * A PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 #include "communicator.hh"
 #include "element_info_per_processor.hh"
 #include "element_synchronizer.hh"
 #include "mesh_utils.hh"
 /* -------------------------------------------------------------------------- */
 #include <algorithm>
 #include <iostream>
 #include <map>
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 SlaveElementInfoPerProc::SlaveElementInfoPerProc(
     ElementSynchronizer & synchronizer, UInt message_cnt, UInt root)
     : ElementInfoPerProc(synchronizer, message_cnt, root, _not_defined) {
 
   Vector<UInt> size(5);
   comm.receive(size, this->root,
                Tag::genTag(this->root, this->message_count, Tag::_SIZES));
 
   this->type = (ElementType)size[0];
   this->nb_local_element = size[1];
   this->nb_ghost_element = size[2];
   this->nb_element_to_receive = size[3];
   this->nb_tags = size[4];
 
   if (this->type != _not_defined)
     this->nb_nodes_per_element = Mesh::getNbNodesPerElement(type);
 }
 
 /* -------------------------------------------------------------------------- */
 
 bool SlaveElementInfoPerProc::needSynchronize() {
   return this->type != _not_defined;
 }
 
 /* -------------------------------------------------------------------------- */
 void SlaveElementInfoPerProc::synchronizeConnectivities() {
   Array<UInt> local_connectivity(
       (this->nb_local_element + this->nb_ghost_element) *
       this->nb_nodes_per_element);
 
   AKANTU_DEBUG_INFO("Receiving connectivities from proc " << root);
   comm.receive(
       local_connectivity, this->root,
       Tag::genTag(this->root, this->message_count, Tag::_CONNECTIVITY));
 
   auto & old_nodes = this->getNodesGlobalIds();
   AKANTU_DEBUG_INFO("Renumbering local connectivities");
   MeshUtils::renumberMeshNodes(this->mesh, local_connectivity,
                                this->nb_local_element, this->nb_ghost_element,
                                this->type, old_nodes);
 }
 
 /* -------------------------------------------------------------------------- */
 void SlaveElementInfoPerProc::synchronizePartitions() {
   Array<UInt> local_partitions(this->nb_element_to_receive +
                                this->nb_ghost_element * 2);
   AKANTU_DEBUG_INFO("Receiving partition informations from proc " << root);
   this->comm.receive(local_partitions, this->root,
                      Tag::genTag(root, this->message_count, Tag::_PARTITIONS));
 
   if (Mesh::getSpatialDimension(this->type) ==
       this->mesh.getSpatialDimension()) {
     AKANTU_DEBUG_INFO("Creating communications scheme");
     this->fillCommunicationScheme(local_partitions);
   }
 }
 
 /* -------------------------------------------------------------------------- */
 void SlaveElementInfoPerProc::synchronizeTags() {
   AKANTU_DEBUG_IN();
 
   if (this->nb_tags == 0) {
     AKANTU_DEBUG_OUT();
     return;
   }
 
   /* --------<<<<-TAGS------------------------------------------------- */
   UInt mesh_data_sizes_buffer_length = 0;
   CommunicationBuffer mesh_data_sizes_buffer;
 
   AKANTU_DEBUG_INFO(
       "Receiving the size of the information about the mesh data tags.");
   comm.broadcast(mesh_data_sizes_buffer_length, root);
 
   if (mesh_data_sizes_buffer_length != 0) {
     mesh_data_sizes_buffer.resize(mesh_data_sizes_buffer_length);
     AKANTU_DEBUG_INFO(
         "Receiving the information about the mesh data tags, addr "
         << (void *)mesh_data_sizes_buffer.storage());
     comm.broadcast(mesh_data_sizes_buffer, root);
     AKANTU_DEBUG_INFO("Size of the information about the mesh data: "
                       << mesh_data_sizes_buffer_length);
 
     std::vector<std::string> tag_names;
     std::vector<MeshDataTypeCode> tag_type_codes;
     std::vector<UInt> tag_nb_component;
     tag_names.resize(nb_tags);
     tag_type_codes.resize(nb_tags);
     tag_nb_component.resize(nb_tags);
     CommunicationBuffer mesh_data_buffer;
     UInt type_code_int;
     for (UInt i(0); i < nb_tags; ++i) {
       mesh_data_sizes_buffer >> tag_names[i];
       mesh_data_sizes_buffer >> type_code_int;
       tag_type_codes[i] = static_cast<MeshDataTypeCode>(type_code_int);
       mesh_data_sizes_buffer >> tag_nb_component[i];
     }
 
     std::vector<std::string>::const_iterator names_it = tag_names.begin();
     std::vector<std::string>::const_iterator names_end = tag_names.end();
 
     CommunicationStatus mesh_data_comm_status;
     AKANTU_DEBUG_INFO("Checking size of data to receive for mesh data TAG("
                       << Tag::genTag(root, this->message_count, Tag::_MESH_DATA)
                       << ")");
     comm.probe<char>(root,
                      Tag::genTag(root, this->message_count, Tag::_MESH_DATA),
                      mesh_data_comm_status);
     UInt mesh_data_buffer_size(mesh_data_comm_status.size());
     AKANTU_DEBUG_INFO("Receiving "
                       << mesh_data_buffer_size << " bytes of mesh data TAG("
                       << Tag::genTag(root, this->message_count, Tag::_MESH_DATA)
                       << ")");
     mesh_data_buffer.resize(mesh_data_buffer_size);
     comm.receive(mesh_data_buffer, root,
                  Tag::genTag(root, this->message_count, Tag::_MESH_DATA));
 
     // Loop over each tag for the current type
     UInt k(0);
     for (; names_it != names_end; ++names_it, ++k) {
       this->fillMeshData(mesh_data_buffer, *names_it, tag_type_codes[k],
                          tag_nb_component[k]);
     }
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void SlaveElementInfoPerProc::synchronizeGroups() {
   AKANTU_DEBUG_IN();
 
   const Communicator & comm = mesh.getCommunicator();
   UInt my_rank = comm.whoAmI();
 
   AKANTU_DEBUG_INFO("Receiving element groups from proc "
                     << root << " TAG("
                     << Tag::genTag(root, my_rank, Tag::_ELEMENT_GROUP) << ")");
 
   CommunicationStatus status;
   comm.probe<char>(root, Tag::genTag(root, my_rank, Tag::_ELEMENT_GROUP),
                    status);
 
   CommunicationBuffer buffer(status.size());
   comm.receive(buffer, root, Tag::genTag(root, my_rank, Tag::_ELEMENT_GROUP));
 
   this->fillElementGroupsFromBuffer(buffer);
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 
 } // akantu
diff --git a/src/synchronizer/synchronizer.cc b/src/synchronizer/synchronizer.cc
index cfc86b95c..4917daf4e 100644
--- a/src/synchronizer/synchronizer.cc
+++ b/src/synchronizer/synchronizer.cc
@@ -1,56 +1,55 @@
 /**
  * @file   synchronizer.cc
  *
  * @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Wed Sep 01 2010
- * @date last modification: Tue Dec 09 2014
+ * @date last modification: Wed Nov 15 2017
  *
  * @brief  implementation of the common part
  *
  * @section LICENSE
  *
- * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
- * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
- * Solides)
+ * 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
+ * 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
+ * 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 "synchronizer.hh"
 #include "communicator.hh"
 /* -------------------------------------------------------------------------- */
 #include <functional>
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 Synchronizer::Synchronizer(const Communicator & comm, const ID & id,
                            MemoryID memory_id)
     : Memory(id, memory_id), communicator(comm) {
   int max_tag = comm.getMaxTag();
 
   this->hash_id = std::hash<std::string>()(this->getID());
   if (max_tag != 0)
     this->hash_id = this->hash_id % max_tag;
 
   this->nb_proc = communicator.getNbProc();
   this->rank = communicator.whoAmI();
 }
 
 } // namespace akantu
diff --git a/src/synchronizer/synchronizer.hh b/src/synchronizer/synchronizer.hh
index 8f3501158..1d1e4cbe4 100644
--- a/src/synchronizer/synchronizer.hh
+++ b/src/synchronizer/synchronizer.hh
@@ -1,125 +1,125 @@
 /**
  * @file   synchronizer.hh
  *
  * @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
  * @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Fri Jun 18 2010
- * @date last modification: Thu Dec 10 2015
+ * @date last modification: Tue Feb 20 2018
  *
  * @brief  Common interface for synchronizers
  *
  * @section LICENSE
  *
- * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
- * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
- * Solides)
+ * 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
+ * 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
+ * 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_memory.hh"
 /* -------------------------------------------------------------------------- */
 #include <map>
 /* -------------------------------------------------------------------------- */
 
 #ifndef __AKANTU_SYNCHRONIZER_HH__
 #define __AKANTU_SYNCHRONIZER_HH__
 
 namespace akantu {
 class Communicator;
 }
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 /* Base class for synchronizers                                               */
 /* -------------------------------------------------------------------------- */
 class Synchronizer : protected Memory {
   /* ------------------------------------------------------------------------ */
   /* Constructors/Destructors                                                 */
   /* ------------------------------------------------------------------------ */
 public:
   Synchronizer(const Communicator & comm, const ID & id = "synchronizer",
                MemoryID memory_id = 0);
 
   Synchronizer(const Synchronizer & other) = default;
 
   ~Synchronizer() override = default;
 
   /* ------------------------------------------------------------------------ */
   /* Methods                                                                  */
   /* ------------------------------------------------------------------------ */
 public:
   /// synchronize ghosts without state
   template <class DataAccessor>
   void synchronizeOnce(DataAccessor & data_accessor,
                        const SynchronizationTag & tag) const;
 
   /// synchronize ghosts
   template <class DataAccessor>
   void synchronize(DataAccessor & data_accessor,
                    const SynchronizationTag & tag);
 
   /// asynchronous synchronization of ghosts
   template <class DataAccessor>
   void asynchronousSynchronize(const DataAccessor & data_accessor,
                                const SynchronizationTag & tag);
 
   /// wait end of asynchronous synchronization of ghosts
   template <class DataAccessor>
   void waitEndSynchronize(DataAccessor & data_accessor,
                           const SynchronizationTag & tag);
 
   /// compute buffer size for a given tag and data accessor
   template <class DataAccessor>
   void computeBufferSize(const DataAccessor & data_accessor,
                          const SynchronizationTag & tag);
 
   /* ------------------------------------------------------------------------ */
   /* Accessors                                                                */
   /* ------------------------------------------------------------------------ */
 public:
   AKANTU_GET_MACRO(Communicator, communicator, const Communicator &);
 
   /* ------------------------------------------------------------------------ */
   /* Class Members                                                            */
   /* ------------------------------------------------------------------------ */
 protected:
   /// id of the synchronizer
   ID id;
 
   /// hashed version of the id
   int hash_id;
 
   /// message counter per tag
   std::map<SynchronizationTag, UInt> tag_counter;
 
   /// the static memory instance
   const Communicator & communicator;
 
   /// nb processors in the communicator
   UInt nb_proc;
 
   /// rank in the communicator
   UInt rank;
 };
 
 } // namespace akantu
 
 #include "synchronizer_tmpl.hh"
 
 #endif /* __AKANTU_SYNCHRONIZER_HH__ */
diff --git a/src/synchronizer/synchronizer_impl.hh b/src/synchronizer/synchronizer_impl.hh
index fcfedb3e8..1bb1eaf56 100644
--- a/src/synchronizer/synchronizer_impl.hh
+++ b/src/synchronizer/synchronizer_impl.hh
@@ -1,123 +1,124 @@
 /**
  * @file   synchronizer_impl.hh
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
- * @date   Wed Aug 24 13:26:47 2016
+ * @date creation: Fri Jun 18 2010
+ * @date last modification: Tue Feb 20 2018
  *
  * @brief  Implementation of the generic part of synchronizers
  *
  * @section LICENSE
  *
- * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * 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
+ * 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
+ * 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 "communications.hh"
 #include "synchronizer.hh"
 /* -------------------------------------------------------------------------- */
 
 #ifndef __AKANTU_SYNCHRONIZER_IMPL_HH__
 #define __AKANTU_SYNCHRONIZER_IMPL_HH__
 
 namespace akantu {
 
 template <class Entity> class SynchronizerImpl : public Synchronizer {
   /* ------------------------------------------------------------------------ */
   /* Constructors/Destructors                                                 */
   /* ------------------------------------------------------------------------ */
 public:
   SynchronizerImpl(const Communicator & communicator,
                    const ID & id = "synchronizer", MemoryID memory_id = 0);
 
   SynchronizerImpl(const SynchronizerImpl & other, const ID & id);
 
   ~SynchronizerImpl() override = default;
 
   /* ------------------------------------------------------------------------ */
   /* Methods                                                                  */
   /* ------------------------------------------------------------------------ */
 public:
   /// synchronous synchronization without state
   virtual void synchronizeOnceImpl(DataAccessor<Entity> & data_accessor,
                                    const SynchronizationTag & tag) const;
 
   /// asynchronous synchronization of ghosts
   virtual void
   asynchronousSynchronizeImpl(const DataAccessor<Entity> & data_accessor,
                               const SynchronizationTag & tag);
 
   /// wait end of asynchronous synchronization of ghosts
   virtual void waitEndSynchronizeImpl(DataAccessor<Entity> & data_accessor,
                                       const SynchronizationTag & tag);
 
   /// compute all buffer sizes
   virtual void
   computeAllBufferSizes(const DataAccessor<Entity> & data_accessor);
 
   /// compute buffer size for a given tag and data accessor
   virtual void computeBufferSizeImpl(const DataAccessor<Entity> & data_accessor,
                                      const SynchronizationTag & tag);
 
   /* ------------------------------------------------------------------------ */
   virtual void synchronizeImpl(DataAccessor<Entity> & data_accessor,
                                const SynchronizationTag & tag) {
     this->asynchronousSynchronizeImpl(data_accessor, tag);
     this->waitEndSynchronizeImpl(data_accessor, tag);
   }
 
   /* ------------------------------------------------------------------------ */
   /// extract the elements that have a true predicate from in_synchronizer and
   /// store them in the current synchronizer
   template <typename Pred>
   void split(SynchronizerImpl & in_synchronizer, Pred && pred);
 
   /// update schemes in a synchronizer
   template <typename Updater> void updateSchemes(Updater && scheme_updater);
 
   /* ------------------------------------------------------------------------ */
   virtual UInt sanityCheckDataSize(const Array<Entity> & elements,
                                    const SynchronizationTag & tag) const;
   virtual void
   packSanityCheckData(CommunicationDescriptor<Entity> & comm_desc) const;
   virtual void
   unpackSanityCheckData(CommunicationDescriptor<Entity> & comm_desc) const;
 
 public:
   AKANTU_GET_MACRO(Communications, communications,
                    const Communications<Entity> &);
 
 protected:
   AKANTU_GET_MACRO_NOT_CONST(Communications, communications,
                              Communications<Entity> &);
 
   virtual Int getRank(const Entity & entity) const = 0;
 
   /* ------------------------------------------------------------------------ */
   /* Class Members                                                            */
   /* ------------------------------------------------------------------------ */
 protected:
   /// information on the communications
   Communications<Entity> communications;
 };
 
 } // namespace akantu
 
 #include "synchronizer_impl_tmpl.hh"
 
 #endif /* __AKANTU_SYNCHRONIZER_IMPL_HH__ */
diff --git a/src/synchronizer/synchronizer_impl_tmpl.hh b/src/synchronizer/synchronizer_impl_tmpl.hh
index 7831fbc79..1c919afbd 100644
--- a/src/synchronizer/synchronizer_impl_tmpl.hh
+++ b/src/synchronizer/synchronizer_impl_tmpl.hh
@@ -1,314 +1,315 @@
 /**
  * @file   synchronizer_impl_tmpl.hh
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
- * @date   Wed Aug 24 13:29:47 2016
+ * @date creation: Wed Sep 07 2016
+ * @date last modification: Tue Feb 20 2018
  *
  * @brief  Implementation of the SynchronizerImpl
  *
  * @section LICENSE
  *
- * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * 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
+ * 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
+ * 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 "synchronizer_impl.hh"
 /* -------------------------------------------------------------------------- */
 
 #ifndef __AKANTU_SYNCHRONIZER_IMPL_TMPL_HH__
 #define __AKANTU_SYNCHRONIZER_IMPL_TMPL_HH__
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 template <class Entity>
 SynchronizerImpl<Entity>::SynchronizerImpl(const Communicator & comm,
                                            const ID & id, MemoryID memory_id)
 
     : Synchronizer(comm, id, memory_id), communications(comm) {}
 
 /* -------------------------------------------------------------------------- */
 template <class Entity>
 SynchronizerImpl<Entity>::SynchronizerImpl(const SynchronizerImpl & other,
                                            const ID & id)
     : Synchronizer(other), communications(other.communications) {
   this->id = id;
 }
 
 /* -------------------------------------------------------------------------- */
 template <class Entity>
 void SynchronizerImpl<Entity>::synchronizeOnceImpl(
     DataAccessor<Entity> & data_accessor,
     const SynchronizationTag & tag) const {
   // no need to synchronize
   if (this->nb_proc == 1)
     return;
 
   using CommunicationRequests = std::vector<CommunicationRequest>;
   using CommunicationBuffers = std::map<UInt, CommunicationBuffer>;
 
   CommunicationRequests send_requests, recv_requests;
   CommunicationBuffers send_buffers, recv_buffers;
 
   auto postComm = [&](const CommunicationSendRecv & sr,
                       CommunicationBuffers & buffers,
                       CommunicationRequests & requests) -> void {
     for (auto && pair : communications.iterateSchemes(sr)) {
       auto & proc = pair.first;
       const auto & scheme = pair.second;
 
       auto & buffer = buffers[proc];
       UInt buffer_size = data_accessor.getNbData(scheme, tag);
       buffer.resize(buffer_size);
 
       if (sr == _recv) {
         requests.push_back(communicator.asyncReceive(
             buffer, proc,
             Tag::genTag(this->rank, 0, Tag::_SYNCHRONIZE, this->hash_id)));
       } else {
         data_accessor.packData(buffer, scheme, tag);
         send_requests.push_back(communicator.asyncSend(
             buffer, proc,
             Tag::genTag(proc, 0, Tag::_SYNCHRONIZE, this->hash_id)));
       }
     }
   };
 
   // post the receive requests
   postComm(_recv, recv_buffers, recv_requests);
 
   // post the send data requests
   postComm(_send, send_buffers, send_requests);
 
   // treat the receive requests
   UInt request_ready;
   while ((request_ready = communicator.waitAny(recv_requests)) != UInt(-1)) {
     CommunicationRequest & req = recv_requests[request_ready];
     UInt proc = req.getSource();
 
     CommunicationBuffer & buffer = recv_buffers[proc];
     const auto & scheme = this->communications.getScheme(proc, _recv);
 
     data_accessor.unpackData(buffer, scheme, tag);
 
     req.free();
     recv_requests.erase(recv_requests.begin() + request_ready);
   }
 
   communicator.waitAll(send_requests);
   communicator.freeCommunicationRequest(send_requests);
 }
 
 /* -------------------------------------------------------------------------- */
 template <class Entity>
 void SynchronizerImpl<Entity>::asynchronousSynchronizeImpl(
     const DataAccessor<Entity> & data_accessor,
     const SynchronizationTag & tag) {
   AKANTU_DEBUG_IN();
 
   if (not this->communications.hasCommunicationSize(tag))
     this->computeBufferSize(data_accessor, tag);
 
   this->communications.incrementCounter(tag);
 
   // Posting the receive -------------------------------------------------------
   if (this->communications.hasPendingRecv(tag)) {
     AKANTU_CUSTOM_EXCEPTION_INFO(
         debug::CommunicationException(),
         "There must still be some pending receive communications."
             << " Tag is " << tag << " Cannot start new ones");
   }
 
   for (auto && comm_desc : this->communications.iterateRecv(tag)) {
     comm_desc.postRecv(this->hash_id);
   }
 
   // Posting the sends -------------------------------------------------------
   if (communications.hasPendingSend(tag)) {
     AKANTU_CUSTOM_EXCEPTION_INFO(
         debug::CommunicationException(),
         "There must be some pending sending communications."
             << " Tag is " << tag);
   }
 
   for (auto && comm_desc : this->communications.iterateSend(tag)) {
     comm_desc.resetBuffer();
 
 #ifndef AKANTU_NDEBUG
     this->packSanityCheckData(comm_desc);
 #endif
 
     comm_desc.packData(data_accessor);
     comm_desc.postSend(this->hash_id);
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <class Entity>
 void SynchronizerImpl<Entity>::waitEndSynchronizeImpl(
     DataAccessor<Entity> & data_accessor, const SynchronizationTag & tag) {
   AKANTU_DEBUG_IN();
 
 #ifndef AKANTU_NDEBUG
   if (this->communications.begin(tag, _recv) !=
           this->communications.end(tag, _recv) &&
       !this->communications.hasPendingRecv(tag))
     AKANTU_CUSTOM_EXCEPTION_INFO(debug::CommunicationException(),
                                  "No pending communication with the tag \""
                                      << tag);
 #endif
 
   auto recv_end = this->communications.end(tag, _recv);
   decltype(recv_end) recv_it;
 
   while ((recv_it = this->communications.waitAnyRecv(tag)) != recv_end) {
     auto && comm_desc = *recv_it;
 #ifndef AKANTU_NDEBUG
     this->unpackSanityCheckData(comm_desc);
 #endif
 
     comm_desc.unpackData(data_accessor);
     comm_desc.resetBuffer();
     comm_desc.freeRequest();
   }
 
   this->communications.waitAllSend(tag);
   this->communications.freeSendRequests(tag);
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <class Entity>
 void SynchronizerImpl<Entity>::computeAllBufferSizes(
     const DataAccessor<Entity> & data_accessor) {
   for (auto && tag : this->communications.iterateTags()) {
     this->computeBufferSize(data_accessor, tag);
   }
 }
 
 /* -------------------------------------------------------------------------- */
 template <class Entity>
 void SynchronizerImpl<Entity>::computeBufferSizeImpl(
     const DataAccessor<Entity> & data_accessor,
     const SynchronizationTag & tag) {
   AKANTU_DEBUG_IN();
 
   if (not this->communications.hasCommunication(tag)) {
     this->communications.initializeCommunications(tag);
     AKANTU_DEBUG_ASSERT(communications.hasCommunication(tag) == true,
                         "Communications where not properly initialized");
   }
 
   for (auto sr : iterate_send_recv) {
     for (auto && pair : this->communications.iterateSchemes(sr)) {
       auto proc = pair.first;
       const auto & scheme = pair.second;
       UInt size = 0;
 #ifndef AKANTU_NDEBUG
       size += this->sanityCheckDataSize(scheme, tag);
 #endif
       size += data_accessor.getNbData(scheme, tag);
       AKANTU_DEBUG_INFO("I have "
                         << size << "(" << printMemorySize<char>(size) << " - "
                         << scheme.size() << " element(s)) data to "
                         << std::string(sr == _recv ? "receive from" : "send to")
                         << proc << " for tag " << tag);
 
       this->communications.setCommunicationSize(tag, proc, size, sr);
     }
   }
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <typename Entity>
 template <typename Pred>
 void SynchronizerImpl<Entity>::split(SynchronizerImpl<Entity> & in_synchronizer,
                                      Pred && pred) {
   AKANTU_DEBUG_IN();
 
   auto filter_list = [&](auto & list, auto & new_list) {
     auto copy = list;
     list.resize(0);
     new_list.resize(0);
 
     for (auto && entity : copy) {
       if (std::forward<Pred>(pred)(entity)) {
         new_list.push_back(entity);
       } else {
         list.push_back(entity);
       }
     }
   };
 
   for (auto sr : iterate_send_recv) {
     for (auto & scheme_pair :
          in_synchronizer.communications.iterateSchemes(sr)) {
       auto proc = scheme_pair.first;
       auto & scheme = scheme_pair.second;
       auto & new_scheme = communications.createScheme(proc, sr);
       filter_list(scheme, new_scheme);
     }
   }
 
   in_synchronizer.communications.invalidateSizes();
   communications.invalidateSizes();
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <typename Entity>
 template <typename Updater>
 void SynchronizerImpl<Entity>::updateSchemes(Updater && scheme_updater) {
   for (auto sr : iterate_send_recv) {
     for (auto & scheme_pair : communications.iterateSchemes(sr)) {
       auto proc = scheme_pair.first;
       auto & scheme = scheme_pair.second;
       std::forward<Updater>(scheme_updater)(scheme, proc, sr);
     }
   }
 
   communications.invalidateSizes();
 }
 
 /* -------------------------------------------------------------------------- */
 template <class Entity>
 UInt SynchronizerImpl<Entity>::sanityCheckDataSize(
     const Array<Entity> &, const SynchronizationTag &) const {
   return 0;
 }
 
 /* -------------------------------------------------------------------------- */
 template <class Entity>
 void SynchronizerImpl<Entity>::packSanityCheckData(
     CommunicationDescriptor<Entity> &) const {}
 
 /* -------------------------------------------------------------------------- */
 template <class Entity>
 void SynchronizerImpl<Entity>::unpackSanityCheckData(
     CommunicationDescriptor<Entity> &) const {}
 
 /* -------------------------------------------------------------------------- */
 } // namespace akantu
 
 #endif /* __AKANTU_SYNCHRONIZER_IMPL_TMPL_HH__ */
diff --git a/src/synchronizer/synchronizer_registry.cc b/src/synchronizer/synchronizer_registry.cc
index 3711fa3af..f99fac614 100644
--- a/src/synchronizer/synchronizer_registry.cc
+++ b/src/synchronizer/synchronizer_registry.cc
@@ -1,121 +1,120 @@
 /**
  * @file   synchronizer_registry.cc
  *
  * @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Thu Jun 16 2011
- * @date last modification: Thu Oct 08 2015
+ * @date last modification: Wed Nov 15 2017
  *
  * @brief  Registry of synchronizers
  *
  * @section LICENSE
  *
- * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
- * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
- * Solides)
+ * 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
+ * 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
+ * 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 "synchronizer_registry.hh"
 #include "synchronizer.hh"
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 SynchronizerRegistry::SynchronizerRegistry() {
   AKANTU_DEBUG_IN();
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 SynchronizerRegistry::~SynchronizerRegistry() {
   AKANTU_DEBUG_IN();
 
   synchronizers.clear();
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void SynchronizerRegistry::registerDataAccessor(
     DataAccessorBase & data_accessor) {
   this->data_accessor = &data_accessor;
 }
 
 /* -------------------------------------------------------------------------- */
 void SynchronizerRegistry::synchronize(SynchronizationTag tag) {
   AKANTU_DEBUG_IN();
 
   AKANTU_DEBUG_ASSERT(data_accessor != nullptr, "No data accessor set.");
 
   std::pair<Tag2Sync::iterator, Tag2Sync::iterator> range =
       synchronizers.equal_range(tag);
 
   for (auto it = range.first; it != range.second; ++it) {
     it->second->synchronize(*data_accessor, tag);
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void SynchronizerRegistry::asynchronousSynchronize(SynchronizationTag tag) {
   AKANTU_DEBUG_IN();
 
   AKANTU_DEBUG_ASSERT(data_accessor != nullptr, "No data accessor set.");
 
   std::pair<Tag2Sync::iterator, Tag2Sync::iterator> range =
       synchronizers.equal_range(tag);
 
   for (auto it = range.first; it != range.second; ++it) {
     (*it).second->asynchronousSynchronize(*data_accessor, tag);
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void SynchronizerRegistry::waitEndSynchronize(SynchronizationTag tag) {
   AKANTU_DEBUG_IN();
 
   AKANTU_DEBUG_ASSERT(data_accessor != nullptr, "No data accessor set.");
 
   std::pair<Tag2Sync::iterator, Tag2Sync::iterator> range =
       synchronizers.equal_range(tag);
 
   for (auto it = range.first; it != range.second; ++it) {
     (*it).second->waitEndSynchronize(*data_accessor, tag);
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void SynchronizerRegistry::registerSynchronizer(Synchronizer & synchronizer,
                                                 SynchronizationTag tag) {
   AKANTU_DEBUG_IN();
 
   synchronizers.insert(
       std::pair<SynchronizationTag, Synchronizer *>(tag, &synchronizer));
 
   AKANTU_DEBUG_OUT();
 }
 
 } // akantu
diff --git a/src/synchronizer/synchronizer_registry.hh b/src/synchronizer/synchronizer_registry.hh
index 1edf20b9a..54c2026ee 100644
--- a/src/synchronizer/synchronizer_registry.hh
+++ b/src/synchronizer/synchronizer_registry.hh
@@ -1,91 +1,90 @@
 /**
  * @file   synchronizer_registry.hh
  *
  * @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Fri Jun 18 2010
- * @date last modification: Tue Dec 09 2014
+ * @date last modification: Sun Dec 03 2017
  *
  * @brief  Registry of synchronizers
  *
  * @section LICENSE
  *
- * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
- * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
- * Solides)
+ * 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
+ * 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
+ * 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 <map>
 /* -------------------------------------------------------------------------- */
 
 #ifndef __AKANTU_SYNCHRONIZER_REGISTRY_HH__
 #define __AKANTU_SYNCHRONIZER_REGISTRY_HH__
 
 namespace akantu {
 class DataAccessorBase;
 class Synchronizer;
 }
 
 namespace akantu {
 
 class SynchronizerRegistry {
   /* ------------------------------------------------------------------------ */
   /* Constructors/Destructors                                                 */
   /* ------------------------------------------------------------------------ */
 public:
   SynchronizerRegistry();
   virtual ~SynchronizerRegistry();
 
   /* ------------------------------------------------------------------------ */
   /* Methods                                                                  */
   /* ------------------------------------------------------------------------ */
 public:
   /// synchronize operation
   void synchronize(SynchronizationTag tag);
 
   /// asynchronous synchronization
   void asynchronousSynchronize(SynchronizationTag tag);
 
   /// wait end of asynchronous synchronization
   void waitEndSynchronize(SynchronizationTag tag);
 
   /// register a new synchronization
   void registerSynchronizer(Synchronizer & synchronizer,
                             SynchronizationTag tag);
 
   /// Register a different data accessor.
   void registerDataAccessor(DataAccessorBase & data_accessor);
 
   /* ------------------------------------------------------------------------ */
   /* Class Members                                                            */
   /* ------------------------------------------------------------------------ */
 private:
   using Tag2Sync = std::multimap<SynchronizationTag, Synchronizer *>;
   /// list of registered synchronization
   Tag2Sync synchronizers;
 
   /// data accessor that will permit to do the pack/unpack things
   DataAccessorBase * data_accessor{nullptr};
 };
 
 } // akantu
 
 #endif /* __AKANTU_SYNCHRONIZER_REGISTRY_HH__ */
diff --git a/src/synchronizer/synchronizer_tmpl.hh b/src/synchronizer/synchronizer_tmpl.hh
index c7b76c4c7..763cb9070 100644
--- a/src/synchronizer/synchronizer_tmpl.hh
+++ b/src/synchronizer/synchronizer_tmpl.hh
@@ -1,120 +1,121 @@
 /**
  * @file   synchronizer_tmpl.hh
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
- * @date   Wed Aug  3 13:49:36 2016
+ * @date creation: Wed Sep 07 2016
+ * @date last modification: Thu May 11 2017
  *
  * @brief  Implementation of the helper classes for the synchronizer
  *
  * @section LICENSE
  *
- * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * 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
+ * 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
+ * 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_array.hh"
 #include "data_accessor.hh"
 #include "synchronizer.hh"
 #include "synchronizer_impl.hh"
 /* -------------------------------------------------------------------------- */
 
 #ifndef __AKANTU_SYNCHRONIZER_TMPL_HH__
 #define __AKANTU_SYNCHRONIZER_TMPL_HH__
 
 namespace akantu {
 
 template <class DataAccessorT>
 void Synchronizer::synchronizeOnce(DataAccessorT & data_accessor,
                                    const SynchronizationTag & tag) const {
   if (const auto * synch_el =
           dynamic_cast<const SynchronizerImpl<Element> *>(this)) {
     synch_el->synchronizeOnceImpl(
         dynamic_cast<DataAccessor<Element> &>(data_accessor), tag);
   } else if (const auto * synch_dof =
                  dynamic_cast<const SynchronizerImpl<UInt> *>(this)) {
     synch_dof->synchronizeOnceImpl(
         dynamic_cast<DataAccessor<UInt> &>(data_accessor), tag);
   } else {
     AKANTU_EXCEPTION("You synchronizer is not of a known type");
   }
 }
 
 /// synchronize ghosts
 template <class DataAccessorT>
 void Synchronizer::synchronize(DataAccessorT & data_accessor,
                                const SynchronizationTag & tag) {
   if (auto * synch_el = dynamic_cast<SynchronizerImpl<Element> *>(this)) {
     synch_el->synchronizeImpl(
         dynamic_cast<DataAccessor<Element> &>(data_accessor), tag);
   } else if (auto * synch_dof = dynamic_cast<SynchronizerImpl<UInt> *>(this)) {
     synch_dof->synchronizeImpl(
         dynamic_cast<DataAccessor<UInt> &>(data_accessor), tag);
   } else {
     AKANTU_EXCEPTION("You synchronizer is not of a known type");
   }
 }
 
 /* -------------------------------------------------------------------------- */
 template <class DataAccessorT>
 void Synchronizer::asynchronousSynchronize(const DataAccessorT & data_accessor,
                                            const SynchronizationTag & tag) {
   if (auto * synch_el = dynamic_cast<SynchronizerImpl<Element> *>(this)) {
     synch_el->asynchronousSynchronizeImpl(
         dynamic_cast<const DataAccessor<Element> &>(data_accessor), tag);
   } else if (auto * synch_dof = dynamic_cast<SynchronizerImpl<UInt> *>(this)) {
     synch_dof->asynchronousSynchronizeImpl(
         dynamic_cast<const DataAccessor<UInt> &>(data_accessor), tag);
   } else {
     AKANTU_EXCEPTION("You synchronizer is not of a known type");
   }
 }
 
 /* -------------------------------------------------------------------------- */
 template <class DataAccessorT>
 void Synchronizer::waitEndSynchronize(DataAccessorT & data_accessor,
                                       const SynchronizationTag & tag) {
   if (auto * synch_el = dynamic_cast<SynchronizerImpl<Element> *>(this)) {
     synch_el->waitEndSynchronizeImpl(
         dynamic_cast<DataAccessor<Element> &>(data_accessor), tag);
   } else if (auto * synch_dof = dynamic_cast<SynchronizerImpl<UInt> *>(this)) {
     synch_dof->waitEndSynchronizeImpl(
         dynamic_cast<DataAccessor<UInt> &>(data_accessor), tag);
   } else {
     AKANTU_EXCEPTION("You synchronizer is not of a known type");
   }
 }
 
 /// compute buffer size for a given tag and data accessor
 template <class DataAccessorT>
 void Synchronizer::computeBufferSize(const DataAccessorT & data_accessor,
                                      const SynchronizationTag & tag) {
   if (auto * synch_el = dynamic_cast<SynchronizerImpl<Element> *>(this)) {
     synch_el->computeBufferSizeImpl(
         dynamic_cast<const DataAccessor<Element> &>(data_accessor), tag);
   } else if (auto * synch_dof = dynamic_cast<SynchronizerImpl<UInt> *>(this)) {
     synch_dof->computeBufferSizeImpl(
         dynamic_cast<const DataAccessor<UInt> &>(data_accessor), tag);
   } else {
     AKANTU_EXCEPTION("You synchronizer is not of a known type");
   }
 }
 
 } // akantu
 
 #endif /* __AKANTU_SYNCHRONIZER_TMPL_HH__ */