diff --git a/cmake/AkantuCleaning.cmake b/cmake/AkantuCleaning.cmake
index f41eb399e..39202265c 100644
--- a/cmake/AkantuCleaning.cmake
+++ b/cmake/AkantuCleaning.cmake
@@ -1,77 +1,85 @@
 #===============================================================================
 # @file   AkantuCleaning.cmake
 #
 # @author Nicolas Richart <nicolas.richart@epfl.ch>
 #
 # @date creation: Thu Jun 1, 2017
 #
 # @brief  set of tools to clean the code
 #
 # @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)
 #
 # Akantu is free  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/>.
 #===============================================================================
 
 # Adding clang-format target if executable is found
 find_program(CLANG_FORMAT "clang-format")
 mark_as_advanced(CLANG_FORMAT)
 macro(register_code_to_format)
   if(CLANG_FORMAT)
     add_custom_target(
       clang-format-all
       COMMAND ${CLANG_FORMAT}
       -i
       -style=file
       ${ARGN}
       )
   endif()
 endmacro()
 
 # Adding clang-tidy target if executable is found
 find_program(CLANG_TIDY "clang-tidy")
 mark_as_advanced(CLANG_TIDY)
 macro(register_target_to_tidy target)
   if(CLANG_TIDY)
+    option(AKANTU_CLANG_TIDY_AUTOFIX OFF)
+    mark_as_advanced(AKANTU_CLANG_TIDY_AUTOFIX)
+
+    set(_autofix_option)
+    if(AKANTU_CLANG_TIDY_AUTOFIX)
+      set(_autofix_option -fix)
+    endif()
     get_target_property(_sources ${target} SOURCES)
 
     set(CMAKE_EXPORT_COMPILE_COMMANDS ON CACHE BOOL
       "Enable/Disable output of compile commands during generation" FORCE)
 
     file(MAKE_DIRECTORY ${PROJECT_BINARY_DIR}/clang-tidy)
 
     set(_depends)
 
     foreach(_src ${_sources})
       get_filename_component(_src_dir ${_src} DIRECTORY)
       file(MAKE_DIRECTORY ${PROJECT_BINARY_DIR}/clang-tidy/${_src_dir})
 
       add_custom_command(
         OUTPUT ${PROJECT_BINARY_DIR}/clang-tidy/${_src}.yaml
         COMMAND ${CLANG_TIDY}
          -p=${PROJECT_BINARY_DIR}
          -export-fixes=${PROJECT_BINARY_DIR}/clang-tidy/${_src}.yaml
+         ${_autofix_option}
         ${_src}
         COMMENT "Tidying ${_src}"
         WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
         )
 
       list(APPEND _depends ${PROJECT_BINARY_DIR}/clang-tidy/${_src}.yaml)
     endforeach()
     add_custom_target(clang-tidy DEPENDS ${_depends})
   endif()
 endmacro()
diff --git a/python/swig/aka_array.i b/python/swig/aka_array.i
index cf4838547..117f261fb 100644
--- a/python/swig/aka_array.i
+++ b/python/swig/aka_array.i
@@ -1,250 +1,248 @@
 /**
  * @file   aka_array.i
  *
  * @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Fri Dec 12 2014
  * @date last modification: Wed Nov 11 2015
  *
  * @brief  wrapper for arrays
  *
  * @section LICENSE
  *
  * Copyright (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne) Laboratory
  * (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free  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/>.
  *
  */
 
 %{
 #define SWIG_FILE_WITH_INIT
 #include "aka_array.hh"
 #include "aka_types.hh"
 %}
 
 %include "typemaps.i"
 
 namespace akantu {
   %ignore Array::operator=;
   %ignore Array::operator[];
   %ignore Array::operator();
   %ignore Array::set;
   %ignore Array::begin;
   %ignore Array::end;
   %ignore Array::begin_reinterpret;
   %ignore Array::end_reinterpret;
 };
 
 %include "aka_array.hh"
 
 namespace akantu {
-
   %ignore TensorProxy::operator=;
   %ignore TensorProxy::operator[];
   %ignore TensorProxy::operator();
   %ignore Tensor3Proxy::operator=;
   %ignore Tensor3Proxy::operator[];
   %ignore Tensor3Proxy::operator();
   %ignore TensorStorage::operator=;
   %ignore TensorStorage::operator[];
   %ignore TensorStorage::operator();
   %ignore VectorProxy::operator=;
   %ignore VectorProxy::operator[];
   %ignore VectorProxy::operator();
   %ignore MatrixProxy::operator=;
   %ignore MatrixProxy::operator[];
   %ignore MatrixProxy::operator();
   %ignore Matrix::operator=;
   %ignore Matrix::operator[];
   %ignore Matrix::operator();
   %ignore Tensor3::operator=;
   %ignore Tensor3::operator[];
   %ignore Tensor3::operator();
   %ignore Vector::operator=;
   %ignore Vector::operator[];
   %ignore Vector::operator();
   %ignore Vector::solve;
 };
 
 %include "aka_types.hh"
 
 namespace akantu {
   %template(RArray) Array<akantu::Real, true>;
   %template(UArray) Array<akantu::UInt, true>;
   %template(BArray) Array<bool, true>;
-
   %template(RVector) Vector<akantu::Real>;
 };
 
 %include "numpy.i"
 %init %{
   import_array();
 %}
 
 %inline %{
   namespace akantu{
     template <typename T>
       class ArrayForPython : public Array<T>{
 
     public:
     ArrayForPython(T * wrapped_memory,
 		   UInt size = 0,
 		   UInt nb_component = 1,
 		   const ID & id = "")
       : Array<T>(0,nb_component,id){
 	this->values = wrapped_memory;
 	this->size = size;
       };
 
       ~ArrayForPython(){
 	this->values = NULL;
       };
 
       void resize(UInt new_size){
 	AKANTU_DEBUG_ASSERT(this->size == new_size,"cannot resize a temporary vector");
       }
     };
   }
  template <typename T> int getPythonDataTypeCode(){ AKANTU_EXCEPTION("undefined type");}
  template <> int 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 <> int getPythonDataTypeCode<double>(){return NPY_DOUBLE;}
  template <> int getPythonDataTypeCode<long double>(){return NPY_LONGDOUBLE;}
  template <> int getPythonDataTypeCode<float>(){return NPY_FLOAT;}
  template <> int getPythonDataTypeCode<unsigned long>(){
    int data_typecode = NPY_NOTYPE;
    size_t s = sizeof(unsigned long);
    switch(s) {
    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 <> int getPythonDataTypeCode<akantu::UInt>(){
    int data_typecode = NPY_NOTYPE;
    size_t s = sizeof(akantu::UInt);
    switch(s) {
    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 <> int getPythonDataTypeCode<int>(){
    int data_typecode = NPY_NOTYPE;
    size_t s = sizeof(int);
    switch(s) {
    case 2: data_typecode = NPY_INT16; break;
    case 4: data_typecode = NPY_INT32; break;
    case 8: data_typecode = NPY_INT64; break;
    }
    return data_typecode;
  }
 
  int getSizeOfPythonType(int type_num){
    switch (type_num){
    case NPY_INT16 : return 2;break;
    case NPY_UINT16: return 2;break;
    case NPY_INT32 : return 4;break;
    case NPY_UINT32: return 4;break;
    case NPY_INT64 : return 8;break;
    case NPY_UINT64: return 8;break;
    case NPY_FLOAT:  return sizeof(float);break;
    case NPY_DOUBLE:  return sizeof(double);break;
    case NPY_LONGDOUBLE:  return sizeof(long double);break;
    }
    return 0;
  }
 
  std::string getPythonTypeName(int type_num){
    switch (type_num){
    case NPY_INT16 : return "NPY_INT16" ;break;
    case NPY_UINT16: return "NPY_UINT16";break;
    case NPY_INT32 : return "NPY_INT32" ;break;
    case NPY_UINT32: return "NPY_UINT32";break;
    case NPY_INT64 : return "NPY_INT64" ;break;
    case NPY_UINT64: return "NPY_UINT64";break;
    case NPY_FLOAT:  return "NPY_FLOAT" ;break;
    case NPY_DOUBLE: return "NPY_DOUBLE";break;
    case NPY_LONGDOUBLE: return "NPY_LONGDOUBLE";break;
    }
    return 0;
  }
 
  template <typename T> void checkDataType(int type_num){
    AKANTU_DEBUG_ASSERT(type_num == getPythonDataTypeCode<T>(),
 		       "incompatible types between numpy and input function: " <<
 		       type_num << " != " << getPythonDataTypeCode<T>() << std::endl <<
 		       getSizeOfPythonType(type_num) << " != " << sizeof(T) <<
 		       std::endl <<
 		       "The numpy array is of type " << getPythonTypeName(type_num));
  }
 
  %}
 
 
 %define %akantu_array_typemaps(DATA_TYPE)
 
 %typemap(out, fragment="NumPy_Fragments") (akantu::Array< DATA_TYPE > &)
 {
 
   int data_typecode = getPythonDataTypeCode< DATA_TYPE >();
   npy_intp dims[2] = {npy_intp($1->getSize()), npy_intp($1->getNbComponent())};
   PyObject* obj = PyArray_SimpleNewFromData(2, dims, data_typecode, $1->storage());
   PyArrayObject* array = (PyArrayObject*) obj;
   if (!array) SWIG_fail;
   $result = SWIG_Python_AppendOutput($result, obj);
 }
 
 %typemap(in) akantu::Array< DATA_TYPE > &
 {
   if (!PyArray_Check($input)) {
     AKANTU_EXCEPTION("incompatible input which is not a numpy");
   }
   else {
     PyArray_Descr * numpy_type = (PyArray_Descr*)PyArray_DESCR((PyArrayObject*)$input);
     int type_num = numpy_type->type_num;
     checkDataType< DATA_TYPE >(type_num);
     UInt _n = PyArray_NDIM((PyArrayObject*)$input);
     if (_n != 2) AKANTU_EXCEPTION("incompatible numpy dimension " << _n);
     npy_intp * ndims = PyArray_DIMS((PyArrayObject*)$input);
     akantu::UInt sz = ndims[0];
     akantu::UInt nb_components = ndims[1];
     PyArrayIterObject *iter = (PyArrayIterObject *)PyArray_IterNew($input);
     if (iter == NULL) AKANTU_EXCEPTION("Python internal error");
     $1 = new akantu::ArrayForPython< DATA_TYPE >((DATA_TYPE*)(iter->dataptr),sz,nb_components,"tmp_array_for_python");
   }
 }
 %enddef
 
 
 %akantu_array_typemaps(double      )
 %akantu_array_typemaps(float       )
 %akantu_array_typemaps(unsigned int)
 %akantu_array_typemaps(unsigned long)
 %akantu_array_typemaps(int         )
 %akantu_array_typemaps(bool        )
diff --git a/src/common/aka_array.hh b/src/common/aka_array.hh
index 16a0ac321..646801a86 100644
--- a/src/common/aka_array.hh
+++ b/src/common/aka_array.hh
@@ -1,363 +1,365 @@
 /**
  * @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
  *
  * @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)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
  * terms  of the  GNU Lesser  General Public  License as  published by  the Free
  * Software Foundation, either version 3 of the License, or (at your option) any
  * later version.
  *
  * Akantu is  distributed in the  hope that it  will be useful, but  WITHOUT ANY
  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  * A  PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 
 #ifndef __AKANTU_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>{}>
   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[]);
 
   /// append a Vector or a Matrix
   template <template <typename> class C,
             typename = std::enable_if_t<is_tensor<C<T>>{}>>
   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);
 
   /// 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;
 
   /// @see Array::find(const_reference elem) const
   template <template <typename> class C,
             typename = std::enable_if_t<is_tensor<C<T>>{}>>
   inline UInt find(const C<T> & elem);
 
   /// 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); }
 
   /// 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>>{}>>
   inline void set(const C<T> & vm);
 
   /// 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 eb9b21b7e..9a2c7b0bb 100644
--- a/src/common/aka_array_tmpl.hh
+++ b/src/common/aka_array_tmpl.hh
@@ -1,1252 +1,1252 @@
 /**
  * @file   aka_array_tmpl.hh
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Thu Jul 15 2010
  * @date last modification: Fri Jan 22 2016
  *
  * @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)
  *
  * Akantu is free  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/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 /* 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);
 // }
 
 /* -------------------------------------------------------------------------- */
 /**
  * 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);
 }
 
 /* -------------------------------------------------------------------------- */
 /**
  * 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
  */
 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;
 }
 
 /* -------------------------------------------------------------------------- */
 /**
  * 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);
 }
 
 /* -------------------------------------------------------------------------- */
 /**
  * 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);
   }
 }
 
 /* -------------------------------------------------------------------------- */
 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(NULL) {
+    : 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(NULL) {
+    : 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 == NULL) {
+  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 != NULL,
+        tmp_ptr != nullptr,
         "Cannot allocate " << printMemorySize<T>(size_to_alloc * nb_component));
-    if (tmp_ptr == NULL) {
+    if (tmp_ptr == nullptr) {
       AKANTU_DEBUG_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_DEBUG_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; }
 
 /* -------------------------------------------------------------------------- */
 /* 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_DEBUG_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) ->
       typename std::common_type<V...>::type {
     typename std::common_type<V...>::type 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<Arr>::value,
                            typename array_type::template const_iterator<type>,
                            typename array_type::template iterator<type>>;
     if (array.getNbComponent() * array.size() !=
         product_all(std::forward<Ns>(ns)...)) {
       AKANTU_CUSTOM_EXCEPTION_INFO(
           debug::ArrayException(),
           "The iterator on Array "
               << 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::forward<Ns>(ns)...){};
 
     decltype(auto) begin() {
       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) size() {
       return std::get<std::tuple_size<tuple>::value - 1>(sizes);
     }
 
   private:
     Array array;
     tuple sizes;
   };
 } // namespace detail
 
 /* -------------------------------------------------------------------------- */
 template <typename Array, typename... Ns>
 decltype(auto) make_view(Array && array, Ns &&... ns) {
   auto size = std::forward<decltype(array)>(array).size() *
               std::forward<decltype(array)>(array).getNbComponent() /
               detail::product_all(ns...);
 
   return detail::ArrayView<Array, Ns..., decltype(size)>(
       std::forward<Array>(array), std::forward<Ns>(ns)...,
       std::forward<decltype(size)>(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:
   typedef iterator_internal<const R, const_iterator, R> parent;
   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>{}>>
   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>{}>
 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;
 }
 
 } // namespace akantu
 
 #endif /* __AKANTU_AKA_ARRAY_TMPL_HH__ */
diff --git a/src/common/aka_common.cc b/src/common/aka_common.cc
index 7e61edc3b..9f42be2d3 100644
--- a/src/common/aka_common.cc
+++ b/src/common/aka_common.cc
@@ -1,155 +1,155 @@
 /**
  * @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
  *
  * @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)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
  * terms  of the  GNU Lesser  General Public  License as  published by  the Free
  * Software Foundation, either version 3 of the License, or (at your option) any
  * later version.
  *
  * Akantu is  distributed in the  hope that it  will be useful, but  WITHOUT ANY
  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  * A  PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 #include "aka_common.hh"
 #include "aka_static_memory.hh"
 #include "communicator.hh"
 #include "aka_random_generator.hh"
 
 #include "parser.hh"
 #include "cppargparse.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(NULL);
+    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(_st_user).first);
 }
 
 std::unique_ptr<Communicator> Communicator::static_communicator;
 
 } // akantu
diff --git a/src/common/aka_csr.hh b/src/common/aka_csr.hh
index e88f9a02c..2422d5b44 100644
--- a/src/common/aka_csr.hh
+++ b/src/common/aka_csr.hh
@@ -1,259 +1,259 @@
 /**
  * @file   aka_csr.hh
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Wed Apr 20 2011
  * @date last modification: Sun Oct 19 2014
  *
  * @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)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
  * terms  of the  GNU Lesser  General Public  License as  published by  the Free
  * Software Foundation, either version 3 of the License, or (at your option) any
  * later version.
  *
  * Akantu is  distributed in the  hope that it  will be useful, but  WITHOUT ANY
  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  * A  PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 #include "aka_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(){};
 
   /* ------------------------------------------------------------------------ */
   /* 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:
     typedef std::iterator<std::bidirectional_iterator_tag, R> _parent;
     typedef typename _parent::pointer pointer;
     typedef typename _parent::reference reference;
 
-    explicit iterator_internal(pointer x = NULL) : pos(x){};
+    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;
   };
 
   typedef iterator_internal<T> iterator;
   typedef iterator_internal<const T> const_iterator;
 
   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_error.cc b/src/common/aka_error.cc
index cb0346ce0..04209802d 100644
--- a/src/common/aka_error.cc
+++ b/src/common/aka_error.cc
@@ -1,355 +1,355 @@
 /**
  * @file   aka_error.cc
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Mon Sep 06 2010
  * @date last modification: Tue Jan 19 2016
  *
  * @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)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
  * terms  of the  GNU Lesser  General Public  License as  published by  the Free
  * Software Foundation, either version 3 of the License, or (at your option) any
  * later version.
  *
  * Akantu is  distributed in the  hope that it  will be useful, but  WITHOUT ANY
  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  * A  PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 #include "aka_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, NULL, 0, &status)) !=
-        NULL) {
+    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(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) != NULL)
+      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;
     size_t 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)
         location = exec(std::string(BOOST_PP_STRINGIZE(READLINK_COMMAND)) +
                         std::string(" -f ") + location);
 #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)
         std::map<std::string, size_t>::iterator 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;
     }
 
     std::ofstream * 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_random_generator.hh b/src/common/aka_random_generator.hh
index 3fada453f..73fa4952b 100644
--- a/src/common/aka_random_generator.hh
+++ b/src/common/aka_random_generator.hh
@@ -1,265 +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
  *
  * @brief  generic random generator
  *
  * @section LICENSE
  *
  * Copyright  (©)  2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
  * terms  of the  GNU Lesser  General Public  License as  published by  the Free
  * Software Foundation, either version 3 of the License, or (at your option) any
  * later version.
  *
  * Akantu is  distributed in the  hope that it  will be useful, but  WITHOUT ANY
  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  * A  PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 #include "aka_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_static_memory.cc b/src/common/aka_static_memory.cc
index 7d8709f47..d9d258834 100644
--- a/src/common/aka_static_memory.cc
+++ b/src/common/aka_static_memory.cc
@@ -1,156 +1,156 @@
 /**
  * @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
  *
  * @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)
  *
  * Akantu is free  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 <stdexcept>
 #include <sstream>
 
 /* -------------------------------------------------------------------------- */
 #include "aka_static_memory.hh"
 
 /* -------------------------------------------------------------------------- */
 namespace akantu {
 
 bool StaticMemory::is_instantiated = false;
-StaticMemory * StaticMemory::single_static_memory = NULL;
+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 = NULL;
+  StaticMemory::single_static_memory = nullptr;
   AKANTU_DEBUG_OUT();
 }
 /* -------------------------------------------------------------------------- */
 void StaticMemory::sfree(const MemoryID & memory_id,
 			 const ID & name) {
   AKANTU_DEBUG_IN();
 
   try {
     ArrayMap & 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_types.hh b/src/common/aka_types.hh
index bd65ef234..87eed2533 100644
--- a/src/common/aka_types.hh
+++ b/src/common/aka_types.hh
@@ -1,1263 +1,1263 @@
 /**
  * @file   aka_types.hh
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Thu Feb 17 2011
  * @date last modification: Fri Jan 22 2016
  *
  * @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)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
  * terms  of the  GNU Lesser  General Public  License as  published by  the Free
  * Software Foundation, either version 3 of the License, or (at your option) any
  * later version.
  *
  * Akantu is  distributed in the  hope that it  will be useful, but  WITHOUT ANY
  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  * A  PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 #include "aka_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;
 
   TensorProxy(T * data, UInt m, UInt n, UInt p) {
     DimHelper<ndim>::setDims(m, n, p, this->n);
     this->values = data;
   }
 
   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);
   }
 
 public:
   using RetType = _RetType;
 
   //operator RetType() { return RetType(static_cast<RetTypeProxy &>(*this)); }
 
   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; }
 
   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 <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:
   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>> {
   typedef TensorProxy<T, 3, Tensor3<T>> parent;
   using type = Tensor3<T>;
 
 public:
   Tensor3Proxy(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;
   }
 
 protected:
   TensorStorage(const TensorStorage & src) = delete;
 
 public:
   TensorStorage(const TensorStorage & src, bool deep_copy)
       : values(nullptr), wrapped(false) {
     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>> {
   typedef TensorStorage<T, 1, Vector<T>> parent;
 
 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 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 void normalize() {
     Real n = norm();
     operator/=(n);
   }
 
   /* ------------------------------------------------------------------------ */
   /// 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>> {
   typedef TensorStorage<T, 2, Matrix<T>> parent;
 
 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;
     }
   }
 
-  virtual ~Matrix() = default;
+  ~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 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() != NULL)
+    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 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_DEBUG_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>> {
   typedef TensorStorage<T, 3, Tensor3<T>> parent;
 
 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) {}
 
 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/fe_engine/cohesive_element.cc b/src/fe_engine/cohesive_element.cc
index 97c4df49c..9a7073e13 100644
--- a/src/fe_engine/cohesive_element.cc
+++ b/src/fe_engine/cohesive_element.cc
@@ -1,151 +1,176 @@
 /**
  * @file   cohesive_element.cc
  *
  * @author Mauro Corrado <mauro.corrado@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  * @author Marco Vocialta <marco.vocialta@epfl.ch>
  *
  * @date creation: Sun Sep 26 2010
  * @date last modification: Mon Sep 14 2015
  *
  * @brief  CohesiveElement 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)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
  * terms  of the  GNU Lesser  General Public  License as  published by  the Free
  * Software Foundation, either version 3 of the License, or (at your option) any
  * later version.
  *
  * Akantu is  distributed in the  hope that it  will be useful, but  WITHOUT ANY
  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  * A  PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 #include "aka_common.hh"
 #include "element_class.hh"
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
-template<> UInt GeometricalElement<_gt_cohesive_2d_4>::spatial_dimension    = 2;
-template<> UInt GeometricalElement<_gt_cohesive_2d_4>::nb_nodes_per_element = 4;
-template<> UInt GeometricalElement<_gt_cohesive_2d_4>::nb_facet_types       = 1;
-template<> UInt GeometricalElement<_gt_cohesive_2d_4>::nb_facets[]          = { 2 };
-template<> UInt GeometricalElement<_gt_cohesive_2d_4>::nb_nodes_per_facet[] = { 2 };
-template<> UInt GeometricalElement<_gt_cohesive_2d_4>::facet_connectivity_vect[] = {0, 2,
-                                                                                    1, 3};
-template<> UInt * GeometricalElement<_gt_cohesive_2d_4>::facet_connectivity[] = { &facet_connectivity_vect[0] };
-
-template<> ElementType ElementClass<_cohesive_2d_4>::facet_type[] = { _segment_2 };
-template<> ElementType ElementClass<_cohesive_2d_4>::p1_type      = _cohesive_2d_4;
+template <> UInt GeometricalElement<_gt_cohesive_2d_4>::spatial_dimension = 2;
+template <> UInt GeometricalElement<_gt_cohesive_2d_4>::nb_nodes_per_element = 4;
+template <> UInt GeometricalElement<_gt_cohesive_2d_4>::nb_facet_types = 1;
+template <> UInt GeometricalElement<_gt_cohesive_2d_4>::nb_facets[] = {2};
+template <>
+UInt GeometricalElement<_gt_cohesive_2d_4>::nb_nodes_per_facet[] = {2};
+template <>
+UInt GeometricalElement<_gt_cohesive_2d_4>::facet_connectivity_vect[] = {0, 2,
+                                                                         1, 3};
+template <>
+UInt * GeometricalElement<_gt_cohesive_2d_4>::facet_connectivity[] = {
+    &facet_connectivity_vect[0]};
+
+template <>
+ElementType ElementClass<_cohesive_2d_4>::facet_type[] = {_segment_2};
+template <> ElementType ElementClass<_cohesive_2d_4>::p1_type = _cohesive_2d_4;
 
 /* -------------------------------------------------------------------------- */
-template<> UInt GeometricalElement<_gt_cohesive_2d_6>::spatial_dimension    = 2;
-template<> UInt GeometricalElement<_gt_cohesive_2d_6>::nb_nodes_per_element = 6;
-template<> UInt GeometricalElement<_gt_cohesive_2d_6>::nb_facet_types       = 1;
-template<> UInt GeometricalElement<_gt_cohesive_2d_6>::nb_facets[]          = { 2 };
-template<> UInt GeometricalElement<_gt_cohesive_2d_6>::nb_nodes_per_facet[] = { 3 };
-template<> UInt GeometricalElement<_gt_cohesive_2d_6>::facet_connectivity_vect[] = {0, 3,
-                                                                                    1, 4,
-                                                                                    2, 5};
-template<> UInt * GeometricalElement<_gt_cohesive_2d_6>::facet_connectivity[] = { &facet_connectivity_vect[0] };
-
-template<> ElementType ElementClass<_cohesive_2d_6>::facet_type[] = { _segment_3 };
-template<> ElementType ElementClass<_cohesive_2d_6>::p1_type      = _cohesive_2d_4;
+template <> UInt GeometricalElement<_gt_cohesive_2d_6>::spatial_dimension = 2;
+template <>
+UInt GeometricalElement<_gt_cohesive_2d_6>::nb_nodes_per_element = 6;
+template <> UInt GeometricalElement<_gt_cohesive_2d_6>::nb_facet_types = 1;
+template <> UInt GeometricalElement<_gt_cohesive_2d_6>::nb_facets[] = {2};
+template <>
+UInt GeometricalElement<_gt_cohesive_2d_6>::nb_nodes_per_facet[] = {3};
+template <>
+UInt GeometricalElement<_gt_cohesive_2d_6>::facet_connectivity_vect[] = {
+    0, 3, 1, 4, 2, 5};
+template <>
+UInt * GeometricalElement<_gt_cohesive_2d_6>::facet_connectivity[] = {
+    &facet_connectivity_vect[0]};
+
+template <>
+ElementType ElementClass<_cohesive_2d_6>::facet_type[] = {_segment_3};
+template <> ElementType ElementClass<_cohesive_2d_6>::p1_type = _cohesive_2d_4;
 
 /* -------------------------------------------------------------------------- */
-template<> UInt GeometricalElement<_gt_cohesive_1d_2>::spatial_dimension    = 1;
-template<> UInt GeometricalElement<_gt_cohesive_1d_2>::nb_nodes_per_element = 2;
-template<> UInt GeometricalElement<_gt_cohesive_1d_2>::nb_facet_types       = 1;
-template<> UInt GeometricalElement<_gt_cohesive_1d_2>::nb_facets[]          = { 2 };
-template<> UInt GeometricalElement<_gt_cohesive_1d_2>::nb_nodes_per_facet[] = { 1 };
-template<> UInt GeometricalElement<_gt_cohesive_1d_2>::facet_connectivity_vect[] = {0,
-                                                                                    1};
-template<> UInt * GeometricalElement<_gt_cohesive_1d_2>::facet_connectivity[] = { &facet_connectivity_vect[0] };
-
-template<> ElementType ElementClass<_cohesive_1d_2>::facet_type[] = { _point_1 };
-template<> ElementType ElementClass<_cohesive_1d_2>::p1_type      = _cohesive_1d_2;
+template <> UInt GeometricalElement<_gt_cohesive_1d_2>::spatial_dimension = 1;
+template <>
+UInt GeometricalElement<_gt_cohesive_1d_2>::nb_nodes_per_element = 2;
+template <> UInt GeometricalElement<_gt_cohesive_1d_2>::nb_facet_types = 1;
+template <> UInt GeometricalElement<_gt_cohesive_1d_2>::nb_facets[] = {2};
+template <>
+UInt GeometricalElement<_gt_cohesive_1d_2>::nb_nodes_per_facet[] = {1};
+template <>
+UInt GeometricalElement<_gt_cohesive_1d_2>::facet_connectivity_vect[] = {0, 1};
+template <>
+UInt * GeometricalElement<_gt_cohesive_1d_2>::facet_connectivity[] = {
+    &facet_connectivity_vect[0]};
+
+template <> ElementType ElementClass<_cohesive_1d_2>::facet_type[] = {_point_1};
+template <> ElementType ElementClass<_cohesive_1d_2>::p1_type = _cohesive_1d_2;
 /* -------------------------------------------------------------------------- */
 
-template<> UInt GeometricalElement<_gt_cohesive_3d_6>::spatial_dimension    = 3;
-template<> UInt GeometricalElement<_gt_cohesive_3d_6>::nb_nodes_per_element = 6;
-template<> UInt GeometricalElement<_gt_cohesive_3d_6>::nb_facet_types       = 1;
-template<> UInt GeometricalElement<_gt_cohesive_3d_6>::nb_facets[]          = { 2 };
-template<> UInt GeometricalElement<_gt_cohesive_3d_6>::nb_nodes_per_facet[] = { 3 };
-template<> UInt GeometricalElement<_gt_cohesive_3d_6>::facet_connectivity_vect[] = {0, 3,
-                                                                                    1, 4,
-                                                                                    2, 5};
-template<> UInt * GeometricalElement<_gt_cohesive_3d_6>::facet_connectivity[] = { &facet_connectivity_vect[0] };
-
-template<> ElementType ElementClass<_cohesive_3d_6>::facet_type[] = { _triangle_3 };
-template<> ElementType ElementClass<_cohesive_3d_6>::p1_type      = _cohesive_3d_6;
+template <> UInt GeometricalElement<_gt_cohesive_3d_6>::spatial_dimension = 3;
+template <>
+UInt GeometricalElement<_gt_cohesive_3d_6>::nb_nodes_per_element = 6;
+template <> UInt GeometricalElement<_gt_cohesive_3d_6>::nb_facet_types = 1;
+template <> UInt GeometricalElement<_gt_cohesive_3d_6>::nb_facets[] = {2};
+template <>
+UInt GeometricalElement<_gt_cohesive_3d_6>::nb_nodes_per_facet[] = {3};
+template <>
+UInt GeometricalElement<_gt_cohesive_3d_6>::facet_connectivity_vect[] = {
+    0, 3, 1, 4, 2, 5};
+template <>
+UInt * GeometricalElement<_gt_cohesive_3d_6>::facet_connectivity[] = {
+    &facet_connectivity_vect[0]};
+
+template <>
+ElementType ElementClass<_cohesive_3d_6>::facet_type[] = {_triangle_3};
+template <> ElementType ElementClass<_cohesive_3d_6>::p1_type = _cohesive_3d_6;
 
 /* -------------------------------------------------------------------------- */
 
-template<> UInt GeometricalElement<_gt_cohesive_3d_12>::spatial_dimension    = 3;
-template<> UInt GeometricalElement<_gt_cohesive_3d_12>::nb_nodes_per_element = 12;
-template<> UInt GeometricalElement<_gt_cohesive_3d_12>::nb_facet_types       = 1;
-template<> UInt GeometricalElement<_gt_cohesive_3d_12>::nb_facets[]          = { 2 };
-template<> UInt GeometricalElement<_gt_cohesive_3d_12>::nb_nodes_per_facet[] = { 6 };
-template<> UInt GeometricalElement<_gt_cohesive_3d_12>::facet_connectivity_vect[] = {0, 6,
-                                                                                     1, 7,
-                                                                                     2, 8,
-                                                                                     3, 9,
-                                                                                     4, 10,
-                                                                                     5, 11};
-template<> UInt * GeometricalElement<_gt_cohesive_3d_12>::facet_connectivity[] = { &facet_connectivity_vect[0] };
-
-template<> ElementType ElementClass<_cohesive_3d_12>::facet_type[] = { _triangle_6 };
-template<> ElementType ElementClass<_cohesive_3d_12>::p1_type      = _cohesive_3d_6;
+template <> UInt GeometricalElement<_gt_cohesive_3d_12>::spatial_dimension = 3;
+template <>
+UInt GeometricalElement<_gt_cohesive_3d_12>::nb_nodes_per_element = 12;
+template <> UInt GeometricalElement<_gt_cohesive_3d_12>::nb_facet_types = 1;
+template <> UInt GeometricalElement<_gt_cohesive_3d_12>::nb_facets[] = {2};
+template <>
+UInt GeometricalElement<_gt_cohesive_3d_12>::nb_nodes_per_facet[] = {6};
+template <>
+UInt GeometricalElement<_gt_cohesive_3d_12>::facet_connectivity_vect[] = {
+    0, 6, 1, 7, 2, 8, 3, 9, 4, 10, 5, 11};
+template <>
+UInt * GeometricalElement<_gt_cohesive_3d_12>::facet_connectivity[] = {
+    &facet_connectivity_vect[0]};
+
+template <>
+ElementType ElementClass<_cohesive_3d_12>::facet_type[] = {_triangle_6};
+template <> ElementType ElementClass<_cohesive_3d_12>::p1_type = _cohesive_3d_6;
 
 /* -------------------------------------------------------------------------- */
 
-template<> UInt GeometricalElement<_gt_cohesive_3d_8>::spatial_dimension    = 3;
-template<> UInt GeometricalElement<_gt_cohesive_3d_8>::nb_nodes_per_element = 8;
-template<> UInt GeometricalElement<_gt_cohesive_3d_8>::nb_facet_types       = 1;
-template<> UInt GeometricalElement<_gt_cohesive_3d_8>::nb_facets[]          = { 2 };
-template<> UInt GeometricalElement<_gt_cohesive_3d_8>::nb_nodes_per_facet[] = { 4 };
-template<> UInt GeometricalElement<_gt_cohesive_3d_8>::facet_connectivity_vect[] = {0, 4,
-                                                                                    1, 5,
-                                                                                    2, 6,
-                                                                                    3, 7};
-template<> UInt * GeometricalElement<_gt_cohesive_3d_8>::facet_connectivity[] = { &facet_connectivity_vect[0] };
-
-template<> ElementType ElementClass<_cohesive_3d_8>::facet_type[] = { _quadrangle_4 };
-template<> ElementType ElementClass<_cohesive_3d_8>::p1_type      = _cohesive_3d_8;
+template <> UInt GeometricalElement<_gt_cohesive_3d_8>::spatial_dimension = 3;
+template <>
+UInt GeometricalElement<_gt_cohesive_3d_8>::nb_nodes_per_element = 8;
+template <> UInt GeometricalElement<_gt_cohesive_3d_8>::nb_facet_types = 1;
+template <> UInt GeometricalElement<_gt_cohesive_3d_8>::nb_facets[] = {2};
+template <>
+UInt GeometricalElement<_gt_cohesive_3d_8>::nb_nodes_per_facet[] = {4};
+template <>
+UInt GeometricalElement<_gt_cohesive_3d_8>::facet_connectivity_vect[] = {
+    0, 4, 1, 5, 2, 6, 3, 7};
+template <>
+UInt * GeometricalElement<_gt_cohesive_3d_8>::facet_connectivity[] = {
+    &facet_connectivity_vect[0]};
+
+template <>
+ElementType ElementClass<_cohesive_3d_8>::facet_type[] = {_quadrangle_4};
+template <> ElementType ElementClass<_cohesive_3d_8>::p1_type = _cohesive_3d_8;
 
 /* -------------------------------------------------------------------------- */
 
-template<> UInt GeometricalElement<_gt_cohesive_3d_16>::spatial_dimension    = 3;
-template<> UInt GeometricalElement<_gt_cohesive_3d_16>::nb_nodes_per_element = 16;
-template<> UInt GeometricalElement<_gt_cohesive_3d_16>::nb_facet_types       = 1;
-template<> UInt GeometricalElement<_gt_cohesive_3d_16>::nb_facets[]          = { 2 };
-template<> UInt GeometricalElement<_gt_cohesive_3d_16>::nb_nodes_per_facet[] = { 8 };
-template<> UInt GeometricalElement<_gt_cohesive_3d_16>::facet_connectivity_vect[] = {0, 8,
-                                                                                     1, 9,
-                                                                                     2, 10,
-                                                                                     3, 11,
-                                                                                     4, 12,
-                                                                                     5, 13,
-                                                                                     6, 14,
-                                                                                     7, 15};
-template<> UInt * GeometricalElement<_gt_cohesive_3d_16>::facet_connectivity[] = { &facet_connectivity_vect[0] };
-
-template<> ElementType ElementClass<_cohesive_3d_16>::facet_type[] = { _quadrangle_8 };
-template<> ElementType ElementClass<_cohesive_3d_16>::p1_type      = _cohesive_3d_8;
+template <> UInt GeometricalElement<_gt_cohesive_3d_16>::spatial_dimension = 3;
+template <>
+UInt GeometricalElement<_gt_cohesive_3d_16>::nb_nodes_per_element = 16;
+template <> UInt GeometricalElement<_gt_cohesive_3d_16>::nb_facet_types = 1;
+template <> UInt GeometricalElement<_gt_cohesive_3d_16>::nb_facets[] = {2};
+template <>
+UInt GeometricalElement<_gt_cohesive_3d_16>::nb_nodes_per_facet[] = {8};
+template <>
+UInt GeometricalElement<_gt_cohesive_3d_16>::facet_connectivity_vect[] = {
+    0, 8, 1, 9, 2, 10, 3, 11, 4, 12, 5, 13, 6, 14, 7, 15};
+template <>
+UInt * GeometricalElement<_gt_cohesive_3d_16>::facet_connectivity[] = {
+    &facet_connectivity_vect[0]};
+
+template <>
+ElementType ElementClass<_cohesive_3d_16>::facet_type[] = {_quadrangle_8};
+template <> ElementType ElementClass<_cohesive_3d_16>::p1_type = _cohesive_3d_8;
 
 /* -------------------------------------------------------------------------- */
 
-} // akantu
+} // namespace akantu
diff --git a/src/fe_engine/element_class.hh b/src/fe_engine/element_class.hh
index 188115a3d..6cb694cda 100644
--- a/src/fe_engine/element_class.hh
+++ b/src/fe_engine/element_class.hh
@@ -1,410 +1,408 @@
 /**
  * @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
  *
  * @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)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
  * terms  of the  GNU Lesser  General Public  License as  published by  the Free
  * Software Foundation, either version 3 of the License, or (at your option) any
  * later version.
  *
  * Akantu is  distributed in the  hope that it  will be useful, but  WITHOUT ANY
  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  * A  PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 #include "aka_common.hh"
 #include "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};                      \
+    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);
 
 /* -------------------------------------------------------------------------- */
 /// Templated GeometricalElement with function getInradius
 template <GeometricalType geometrical_type,
           GeometricalShapeType shape =
               GeometricalShape<geometrical_type>::shape>
 class GeometricalElement {
 public:
   /// compute the in-radius
   static inline Real getInradius(__attribute__((unused))
                                  const Matrix<Real> & coord) {
     AKANTU_DEBUG_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, spatial_dimension, UInt);
   static AKANTU_GET_MACRO_NOT_CONST(NbNodesPerElement, nb_nodes_per_element,
                                     UInt);
   static AKANTU_GET_MACRO_NOT_CONST(NbFacetTypes, nb_facet_types, UInt);
   static inline UInt getNbFacetsPerElement(UInt t);
   static inline UInt getNbFacetsPerElement();
   static inline const MatrixProxy<UInt>
   getFacetLocalConnectivityPerElement(UInt t = 0);
 
 protected:
   /// Number of nodes per element
   static UInt nb_nodes_per_element;
   /// spatial dimension of the element
   static UInt spatial_dimension;
   /// number of different facet types
   static UInt nb_facet_types;
   /// number of facets for element
   static UInt nb_facets[];
+  /// Nb nodes per facets types
+  static UInt nb_nodes_per_facet[];
   /// storage of the facet local connectivity
   static UInt facet_connectivity_vect[];
   /// local connectivity of facets
   static UInt * facet_connectivity[];
-
-private:
-  /// Type of the facet elements
-  static UInt nb_nodes_per_facet[];
 };
 
 /* -------------------------------------------------------------------------- */
 /* Interpolation                                                              */
 /* -------------------------------------------------------------------------- */
 /// default InterpolationProperty structure
 template <InterpolationType interpolation_type> struct InterpolationProperty {
   static const InterpolationKind kind{_itk_not_defined};
   static const UInt nb_nodes_per_element{0};
   static const UInt natural_space_dimension{0};
 };
 
 /// 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 const InterpolationKind kind{itp_kind};                             \
     static const UInt nb_nodes_per_element{nb_nodes};                          \
     static const 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:
   typedef InterpolationProperty<interpolation_type> interpolation_property;
 
   /// 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_DEBUG_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_DEBUG_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_DEBUG_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:
   typedef GeometricalElement<
       ElementClassProperty<element_type>::geometrical_type>
       geometrical_element;
   typedef InterpolationElement<
       ElementClassProperty<element_type>::interpolation_type>
       interpolation_element;
 
   typedef ElementClassProperty<element_type> element_property;
   typedef typename interpolation_element::interpolation_property
       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 AKANTU_GET_MACRO_NOT_CONST(
       SpatialDimension, ElementClassProperty<element_type>::spatial_dimension,
       UInt);
   static AKANTU_GET_MACRO_NOT_CONST(P1ElementType, p1_type,
                                     const ElementType &);
   static const ElementType & getFacetType(UInt t = 0) { return facet_type[t]; }
   static ElementType * getFacetTypeInternal() { return facet_type; }
 
 protected:
   /// Type of the facet elements
   static ElementType facet_type[];
   /// type of element P1 associated
   static ElementType p1_type;
 };
 
 /* -------------------------------------------------------------------------- */
 } // namespace akantu
 
 /* -------------------------------------------------------------------------- */
 #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/fe_engine.hh b/src/fe_engine/fe_engine.hh
index 2c6fffa42..9ca9a0343 100644
--- a/src/fe_engine/fe_engine.hh
+++ b/src/fe_engine/fe_engine.hh
@@ -1,384 +1,384 @@
 /**
  * @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
  *
  * @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)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
  * terms  of the  GNU Lesser  General Public  License as  published by  the Free
  * Software Foundation, either version 3 of the License, or (at your option) any
  * later version.
  *
  * Akantu is  distributed in the  hope that it  will be useful, but  WITHOUT ANY
  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  * A  PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 
 #ifndef __AKANTU_FE_ENGINE_HH__
 #define __AKANTU_FE_ENGINE_HH__
 
 /* -------------------------------------------------------------------------- */
 #include "aka_memory.hh"
 #include "element_type_map.hh"
 #include "mesh_events.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, ID id = "fem",
            MemoryID memory_id = 0);
 
-  virtual ~FEEngine();
+  ~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 = NULL) const = 0;
+      const ElementTypeMapArray<UInt> * filter_elements = nullptr) 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 = NULL) const = 0;
+      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_DEBUG_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_DEBUG_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_DEBUG_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_DEBUG_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_template.hh b/src/fe_engine/fe_engine_template.hh
index 026963159..5b8c0e502 100644
--- a/src/fe_engine/fe_engine_template.hh
+++ b/src/fe_engine/fe_engine_template.hh
@@ -1,393 +1,395 @@
 /**
  * @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
  *
  * @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)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
  * terms  of the  GNU Lesser  General Public  License as  published by  the Free
  * Software Foundation, either version 3 of the License, or (at your option) any
  * later version.
  *
  * Akantu is  distributed in the  hope that it  will be useful, but  WITHOUT ANY
  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  * A  PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 /* -------------------------------------------------------------------------- */
 
 #ifndef __AKANTU_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:
   typedef I<kind, IntegrationOrderFunctor> Integ;
   typedef S<kind> Shape;
 
   FEEngineTemplate(Mesh & mesh, UInt spatial_dimension = _all_dimensions,
                    ID id = "fem", MemoryID memory_id = 0);
 
-  virtual ~FEEngineTemplate();
+  ~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"
-  virtual Real
-  integrate(const Vector<Real> & f, const ElementType & type, UInt index,
-            const GhostType & ghost_type = _not_ghost) const override;
+  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 = NULL) const override;
+      const ElementTypeMapArray<UInt> * filter_elements =
+          nullptr) 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 = NULL) const override;
+      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 = NULL) const override;
+      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;
 #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_tmpl.hh b/src/fe_engine/fe_engine_template_tmpl.hh
index 48637bec3..83e0f168e 100644
--- a/src/fe_engine/fe_engine_template_tmpl.hh
+++ b/src/fe_engine/fe_engine_template_tmpl.hh
@@ -1,1301 +1,1301 @@
 /**
  * @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
  *
  * @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)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
  * terms  of the  GNU Lesser  General Public  License as  published by  the Free
  * Software Foundation, either version 3 of the License, or (at your option) any
  * later version.
  *
  * Akantu is  distributed in the  hope that it  will be useful, but  WITHOUT ANY
  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  * A  PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 #include "aka_common.hh"
 #include "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() {}
 
 /* -------------------------------------------------------------------------- */
 /**
  * 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_DEBUG_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_DEBUG_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 = NULL;
+  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();
 }
 
 /* -------------------------------------------------------------------------- */
 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_DEBUG_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_DEBUG_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) {
+  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_DEBUG_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_DEBUG_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_DEBUG_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_DEBUG_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_DEBUG_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/integration_point.hh b/src/fe_engine/integration_point.hh
index b03973307..2e6314ce7 100644
--- a/src/fe_engine/integration_point.hh
+++ b/src/fe_engine/integration_point.hh
@@ -1,167 +1,168 @@
 /**
  * @file   integration_point.hh
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Wed Jun 17 2015
  * @date last modification: Sun Nov 15 2015
  *
  * @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)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
  * terms  of the  GNU Lesser  General Public  License as  published by  the Free
  * Software Foundation, either version 3 of the License, or (at your option) any
  * later version.
  *
  * Akantu is  distributed in the  hope that it  will be useful, but  WITHOUT ANY
  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  * A  PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 /* -------------------------------------------------------------------------- */
 #include "aka_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:
   typedef Vector<Real> position_type;
 
   /* ------------------------------------------------------------------------ */
   /* 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), global_num(0),
         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;
   // 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 8374f1415..5df11d185 100644
--- a/src/fe_engine/integrator.hh
+++ b/src/fe_engine/integrator.hh
@@ -1,137 +1,137 @@
 /**
  * @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
  *
  * @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)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
  * terms  of the  GNU Lesser  General Public  License as  published by  the Free
  * Software Foundation, either version 3 of the License, or (at your option) any
  * later version.
  *
  * Akantu is  distributed in the  hope that it  will be useful, but  WITHOUT ANY
  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  * A  PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 #ifndef __AKANTU_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();
   };
 
-  virtual ~Integrator(){};
+  ~Integrator() override{};
 
   /* ------------------------------------------------------------------------ */
   /* Methods                                                                  */
   /* ------------------------------------------------------------------------ */
 public:
   /// empty method
   template <ElementType type>
   inline void precomputeJacobiansOnQuadraturePoints(__attribute__((unused))
                                                     GhostType ghost_type) {}
 
   /// empty method
   void integrateOnElement(__attribute__((unused)) const Array<Real> & f,
                           __attribute__((unused)) Real * intf,
                           __attribute__((unused)) UInt nb_degree_of_freedom,
                           __attribute__((unused)) const Element & elem,
                           __attribute__((unused))
                           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 d35db8ed3..b6f09fa1e 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
  *
  * @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)
  *
  * Akantu is free  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 "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);
 
-  virtual ~IntegratorGauss(){};
+  ~IntegratorGauss() override{};
 
   /* ------------------------------------------------------------------------ */
   /* 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/shape_cohesive.hh b/src/fe_engine/shape_cohesive.hh
index 38e512944..d214f7035 100644
--- a/src/fe_engine/shape_cohesive.hh
+++ b/src/fe_engine/shape_cohesive.hh
@@ -1,169 +1,169 @@
 /**
  * @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
  *
  * @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)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
  * terms  of the  GNU Lesser  General Public  License as  published by  the Free
  * Software Foundation, either version 3 of the License, or (at your option) any
  * later version.
  *
  * Akantu is  distributed in the  hope that it  will be useful, but  WITHOUT ANY
  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  * A  PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 #include "aka_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);
 
-  virtual ~ShapeLagrange() = default;
+  ~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);
   }
 
   /// 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_DEBUG_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_functions.hh b/src/fe_engine/shape_functions.hh
index ccdac5dce..f7d130af6 100644
--- a/src/fe_engine/shape_functions.hh
+++ b/src/fe_engine/shape_functions.hh
@@ -1,214 +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
  *
  * @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)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
  * terms  of the  GNU Lesser  General Public  License as  published by  the Free
  * Software Foundation, either version 3 of the License, or (at your option) any
  * later version.
  *
  * Akantu is  distributed in the  hope that it  will be useful, but  WITHOUT ANY
  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  * A  PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 
 #include "aka_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);
-  virtual ~ShapeFunctions() = default;
+  ~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);
     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_DEBUG_TO_IMPLEMENT();
   }
   virtual void onElementsRemoved(const Array<Element> &,
                                  const ElementTypeMapArray<UInt> &) {
     AKANTU_DEBUG_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_lagrange.hh b/src/fe_engine/shape_lagrange.hh
index 3973aeeb9..565a00f74 100644
--- a/src/fe_engine/shape_lagrange.hh
+++ b/src/fe_engine/shape_lagrange.hh
@@ -1,162 +1,162 @@
 /**
  * @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
  *
  * @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)
  *
  * Akantu is free  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 "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);
-  virtual ~ShapeLagrange() = default;
+  ~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;
 
   /// 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.hh b/src/fe_engine/shape_lagrange_base.hh
index 2d3a0ab8c..08d915f7d 100644
--- a/src/fe_engine/shape_lagrange_base.hh
+++ b/src/fe_engine/shape_lagrange_base.hh
@@ -1,91 +1,91 @@
 
 /**
  * @file   shape_lagrange_base.hh
  *
  * @author Nicolas Richart
  *
  * @date creation  Thu Jul 27 2017
  *
  * @brief Base class for the shape lagrange
  *
  * @section LICENSE
  *
  * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free  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 "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);
-  virtual ~ShapeLagrangeBase();
+  ~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/io/dumper/dumper_compute.hh b/src/io/dumper/dumper_compute.hh
index a55f37291..2f7931dd7 100644
--- a/src/io/dumper/dumper_compute.hh
+++ b/src/io/dumper/dumper_compute.hh
@@ -1,272 +1,272 @@
 /**
  * @file   dumper_compute.hh
  *
  * @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
  *
  * @date creation: Tue Sep 02 2014
  * @date last modification: Tue Jan 19 2016
  *
  * @brief  Field that map a function to another field
  *
  * @section LICENSE
  *
  * Copyright  (©)  2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
  * terms  of the  GNU Lesser  General Public  License as  published by  the Free
  * Software Foundation, either version 3 of the License, or (at your option) any
  * later version.
  *
  * Akantu is  distributed in the  hope that it  will be useful, but  WITHOUT ANY
  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  * A  PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 #ifndef __AKANTU_DUMPER_COMPUTE_HH__
 #define __AKANTU_DUMPER_COMPUTE_HH__
 /* -------------------------------------------------------------------------- */
 #include "aka_common.hh"
 #include "dumper_iohelper.hh"
 #include "dumper_type_traits.hh"
 #include "dumper_field.hh"
 #include <io_helper.hh>
 
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 __BEGIN_AKANTU_DUMPER__
 
 class ComputeFunctorInterface {
 public:
   virtual ~ComputeFunctorInterface(){};
 
   virtual UInt getDim() = 0;
   virtual UInt getNbComponent(UInt old_nb_comp) = 0;
 };
 
 /* -------------------------------------------------------------------------- */
 
 template <typename return_type>
 class ComputeFunctorOutput : public ComputeFunctorInterface {
 public:
   ComputeFunctorOutput(){};
-  virtual ~ComputeFunctorOutput(){};
+  ~ComputeFunctorOutput() override{};
 };
 
 /* -------------------------------------------------------------------------- */
 template <typename input_type, typename return_type>
 class ComputeFunctor : public ComputeFunctorOutput<return_type> {
 public:
   ComputeFunctor(){};
-  virtual ~ComputeFunctor(){};
+  ~ComputeFunctor() override{};
 
   virtual return_type func(const input_type & d, Element global_index) = 0;
 };
 
 /* -------------------------------------------------------------------------- */
 template <typename SubFieldCompute, typename _return_type>
 class FieldCompute : public Field {
   /* ------------------------------------------------------------------------ */
   /* Typedefs                                                                 */
   /* ------------------------------------------------------------------------ */
 public:
   typedef typename SubFieldCompute::iterator sub_iterator;
   typedef typename SubFieldCompute::types sub_types;
   typedef typename sub_types::return_type sub_return_type;
   typedef _return_type return_type;
   typedef typename sub_types::data_type data_type;
 
   typedef TypeTraits<data_type, return_type, ElementTypeMapArray<data_type> >
       types;
 
   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() {
+  ~FieldCompute() override {
     delete &(this->sub_field);
     delete &(this->func);
   }
 
-  virtual void registerToDumper(const std::string & id,
-                                iohelper::Dumper & dumper) {
+  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;
   }
 
-  virtual void checkHomogeneity() { this->homogeneous = true; };
+  void checkHomogeneity() override { this->homogeneous = true; };
 
   iohelper::DataType getDataType() {
     return iohelper::getDataType<data_type>();
   }
 
   /// get the number of components of the hosted field
-  virtual ElementTypeMap<UInt>
+  ElementTypeMap<UInt>
   getNbComponents(UInt dim = _all_dimensions, GhostType ghost_type = _not_ghost,
-                  ElementKind kind = _ek_not_defined) {
+                  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 virtual Field * connect(FieldComputeProxy & proxy);
+  inline Field * connect(FieldComputeProxy & proxy) override;
 
   /// for connection to a FieldCompute
-  virtual ComputeFunctorInterface * connect(HomogenizerProxy & proxy);
+  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) {
     FieldCompute<T, output> * 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 NULL;
+    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 NULL;
+    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_partition.hh b/src/io/dumper/dumper_element_partition.hh
index ff8aa2654..79c8b9ced 100644
--- a/src/io/dumper/dumper_element_partition.hh
+++ b/src/io/dumper/dumper_element_partition.hh
@@ -1,124 +1,124 @@
 /**
  * @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
  *
  * @brief  ElementPartition field
  *
  * @section LICENSE
  *
  * Copyright  (©)  2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free  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/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 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:
   typedef element_iterator<types, dumper::element_partition_field_iterator> parent;
   typedef typename types::return_type return_type;
   typedef typename types::array_iterator array_iterator;
   typedef typename types::field_type 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                                                                 */
   /* ------------------------------------------------------------------------ */
 
   typedef SingleType<UInt,Vector,filtered> types;
   typedef element_partition_field_iterator<types> iterator;
   typedef GenericElementalField<types,element_partition_field_iterator> parent;
   typedef typename types::field_type 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() { return 1; }
+  UInt getDim() override { return 1; }
 };
 
 /* -------------------------------------------------------------------------- */
 
 __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 383b8b575..ab5ee3886 100644
--- a/src/io/dumper/dumper_generic_elemental_field.hh
+++ b/src/io/dumper/dumper_generic_elemental_field.hh
@@ -1,224 +1,224 @@
 /**
  * @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
  *
  * @brief  Generic interface for elemental fields
  *
  * @section LICENSE
  *
  * Copyright  (©)  2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
  * terms  of the  GNU Lesser  General Public  License as  published by  the Free
  * Software Foundation, either version 3 of the License, or (at your option) any
  * later version.
  *
  * Akantu is  distributed in the  hope that it  will be useful, but  WITHOUT ANY
  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  * A  PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 #ifndef __AKANTU_DUMPER_GENERIC_ELEMENTAL_FIELD_HH__
 #define __AKANTU_DUMPER_GENERIC_ELEMENTAL_FIELD_HH__
 /* -------------------------------------------------------------------------- */
 #include "dumper_field.hh"
 #include "element_type_map_filter.hh"
 #include "dumper_element_iterator.hh"
 #include "dumper_homogenizing_field.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
   typedef _types types;
   typedef typename types::data_type data_type;
   typedef typename types::it_type it_type;
   typedef typename types::field_type field_type;
   typedef typename types::array_type array_type;
   typedef typename types::array_iterator array_iterator;
   typedef typename field_type::type_iterator field_type_iterator;
   typedef iterator_type<types> iterator;
 
   /* ------------------------------------------------------------------------ */
   /* 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
-  virtual ElementTypeMap<UInt>
+  ElementTypeMap<UInt>
   getNbComponents(UInt dim = _all_dimensions, GhostType ghost_type = _not_ghost,
-                  ElementKind kind = _ek_not_defined) {
+                  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
-  virtual void checkHomogeneity();
+  void checkHomogeneity() override;
 
 public:
-  virtual void registerToDumper(const std::string & id,
-                                iohelper::Dumper & dumper) {
+  void registerToDumper(const std::string & id,
+                        iohelper::Dumper & dumper) override {
     dumper.addElemDataField(id, *this);
   };
 
   /// for connection to a FieldCompute
-  inline virtual Field * connect(FieldComputeProxy & proxy) {
+  inline Field * connect(FieldComputeProxy & proxy) override {
     return proxy.connectToField(this);
   }
 
   /// for connection to a Homogenizer
-  inline virtual ComputeFunctorInterface * connect(HomogenizerProxy & proxy) {
+  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) {
+  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_homogenizing_field.hh b/src/io/dumper/dumper_homogenizing_field.hh
index ad50139dd..443468e72 100644
--- a/src/io/dumper/dumper_homogenizing_field.hh
+++ b/src/io/dumper/dumper_homogenizing_field.hh
@@ -1,217 +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
  *
  * @brief  description of field homogenizing field
  *
  * @section LICENSE
  *
  * Copyright  (©)  2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
  * terms  of the  GNU Lesser  General Public  License as  published by  the Free
  * Software Foundation, either version 3 of the License, or (at your option) any
  * later version.
  *
  * Akantu is  distributed in the  hope that it  will be useful, but  WITHOUT ANY
  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  * A  PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 #ifndef __AKANTU_DUMPER_HOMOGENIZING_FIELD_HH__
 #define __AKANTU_DUMPER_HOMOGENIZING_FIELD_HH__
 /* -------------------------------------------------------------------------- */
 #include "dumper_compute.hh"
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 __BEGIN_AKANTU_DUMPER__
 
 /* -------------------------------------------------------------------------- */
 
 template <typename type>
 inline type typeConverter(const type & input,
-                          __attribute__((unused)) Vector<typename type::value_type> & res,
+                          __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) {
+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                                                                 */
   /* ------------------------------------------------------------------------ */
 
   typedef typename type::value_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                                                                  */
   /* ------------------------------------------------------------------------ */
 
-  virtual type func(const type & d,
-                    __attribute__((unused)) Element global_index) {
-
+  type func(const type & d, Element /*global_index*/) {
     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() { return nb_data; };
-  UInt getNbComponent(__attribute__((unused)) UInt old_nb_comp) { throw; };
+  UInt getDim() override { return nb_data; };
+  UInt getNbComponent(UInt /*old_nb_comp*/) { 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(){};
 
 public:
   inline static ComputeFunctorInterface * createHomogenizer(Field & field);
 
   template <typename T>
   inline ComputeFunctorInterface * connectToField(T * field) {
     ElementTypeMap<UInt> nb_components = field->getNbComponents();
 
     typedef typename T::types::return_type ret_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) {
 
   typedef dumper::AvgHomogenizingFunctor<ret_type> Homogenizer;
   Homogenizer * foo = new Homogenizer(nb_components);
   return foo;
 }
 
 template <>
 inline ComputeFunctorInterface *
-HomogenizerProxy::instantiateHomogenizer<Vector<iohelper::ElemType> >(
+HomogenizerProxy::instantiateHomogenizer<Vector<iohelper::ElemType>>(
     __attribute__((unused)) ElementTypeMap<UInt> & nb_components) {
   throw;
-  return NULL;
+  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__
-} // akantu
+} // namespace akantu
 
 #endif /* __AKANTU_DUMPER_HOMOGENIZING_FIELD_HH__ */
diff --git a/src/io/dumper/dumper_material_padders.hh b/src/io/dumper/dumper_material_padders.hh
index b19377c25..c5a0d1700 100644
--- a/src/io/dumper/dumper_material_padders.hh
+++ b/src/io/dumper/dumper_material_padders.hh
@@ -1,297 +1,298 @@
 /**
  * @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
  *
  * @brief  Material padders for plane stress/ plane strain
  *
  * @section LICENSE
  *
  * Copyright  (©)  2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
  * terms  of the  GNU Lesser  General Public  License as  published by  the Free
  * Software Foundation, either version 3 of the License, or (at your option) any
  * later version.
  *
  * Akantu is  distributed in the  hope that it  will be useful, but  WITHOUT ANY
  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  * A  PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 #ifndef __AKANTU_DUMPER_MATERIAL_PADDERS_HH__
 #define __AKANTU_DUMPER_MATERIAL_PADDERS_HH__
 /* -------------------------------------------------------------------------- */
 #include "dumper_padding_helper.hh"
 /* -------------------------------------------------------------------------- */
 namespace akantu {
 __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) {
+  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() { return 9; };
+  UInt getDim() override { return 9; };
 
-  UInt getNbComponent(__attribute__((unused)) UInt old_nb_comp) {
+  UInt getNbComponent(UInt /*old_nb_comp*/) {
     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) {
+  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() { return 9; };
+  UInt getDim() override { return 9; };
 
-  UInt getNbComponent(__attribute__((unused)) UInt old_nb_comp) {
+  UInt getNbComponent(UInt /*old_nb_comp*/) {
     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,
-                           __attribute__((unused)) Element global_element_id) {
+  inline Matrix<Real> func(const Vector<Real> & in, Element /*global_element_id*/) {
     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() { return spatial_dimension * spatial_dimension; };
+  UInt getDim() override { return spatial_dimension * spatial_dimension; };
 
-  UInt getNbComponent(__attribute__((unused)) UInt old_nb_comp) {
+  UInt getNbComponent(UInt /*old_nb_comp*/) {
     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,
-                           __attribute__((unused)) Element global_element_id) {
+                           Element /*global_element_id*/) {
     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() { return spatial_dimension; };
+  UInt getDim() override { return spatial_dimension; };
 
-  UInt getNbComponent(__attribute__((unused)) UInt old_nb_comp) {
+  UInt getNbComponent(UInt /*old_nb_comp*/) {
     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,
-                           __attribute__((unused)) Element global_element_id) {
+                           Element /*global_element_id*/) {
     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() { return 1; };
+  UInt getDim() override { return 1; };
 
-  UInt getNbComponent(__attribute__((unused)) UInt old_nb_comp) {
+  UInt getNbComponent(UInt /*old_nb_comp*/) {
     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 c462adc14..e01599dcf 100644
--- a/src/io/dumper/dumper_nodal_field.hh
+++ b/src/io/dumper/dumper_nodal_field.hh
@@ -1,240 +1,249 @@
 /**
  * @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
  *
  * @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)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
  * terms  of the  GNU Lesser  General Public  License as  published by  the Free
  * Software Foundation, either version 3 of the License, or (at your option) any
  * later version.
  *
  * Akantu is  distributed in the  hope that it  will be useful, but  WITHOUT ANY
  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  * A  PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 #ifndef __AKANTU_DUMPER_NODAL_FIELD_HH__
 #define __AKANTU_DUMPER_NODAL_FIELD_HH__
 
 #include "dumper_field.hh"
 #include <io_helper.hh>
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 __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 = NULL) :
+             __attribute__((unused)) const UInt * filter = nullptr)
+        :
 
-      internal_it(vect), offset(offset), n(n), stride(stride) {}
+          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);
+    };
 
-    bool operator!=(const iterator & it) const { return internal_it != it.internal_it; }
-    iterator & operator++() { internal_it += offset; return *this; };
-    Vector<T> operator* (){ 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 = NULL) :
 
     field(field), n(n), stride(stride), padding(0) {
-    AKANTU_DEBUG_ASSERT(filter == NULL, "Filter passed to unfiltered NodalField!");
+    AKANTU_DEBUG_ASSERT(filter == nullptr,
+                        "Filter passed to unfiltered NodalField!");
     if(n == 0) { this->n = field.getNbComponent() - stride; }
   }
 
   /* ------------------------------------------------------------------------ */
   /* Methods                                                                  */
   /* ------------------------------------------------------------------------ */
-  
-  virtual void registerToDumper(const std::string & id,
-				iohelper::Dumper & dumper) {
+
+  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() { return true; }
-  void checkHomogeneity() { this->homogeneous = true; }
+  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 {
+    bool operator!=(const iterator & it) const override {
       return filter != it.filter;
     }
 
-    iterator & operator++() {
+    iterator & operator++() override {
       ++filter;
       return *this;
     }
 
-    Vector<T> operator* () {
+    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 != NULL, 
-			"No filter passed to filtered NodalField!");
+    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                                                                  */
   /* ------------------------------------------------------------------------ */
-  
-  virtual void registerToDumper(const std::string & id, iohelper::Dumper & dumper) {
+
+  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() {
-    return true;
-  }
-  void checkHomogeneity() { this->homogeneous = true; }
+  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_paraview.hh b/src/io/dumper/dumper_paraview.hh
index 448fd2ee3..eabc41a88 100644
--- a/src/io/dumper/dumper_paraview.hh
+++ b/src/io/dumper/dumper_paraview.hh
@@ -1,74 +1,74 @@
 /**
  * @file   dumper_paraview.hh
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Fri Jun 18 2010
  * @date last modification: Sun Oct 19 2014
  *
  * @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)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
  * terms  of the  GNU Lesser  General Public  License as  published by  the Free
  * Software Foundation, either version 3 of the License, or (at your option) any
  * later version.
  *
  * Akantu is  distributed in the  hope that it  will be useful, but  WITHOUT ANY
  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  * A  PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 
 #ifndef __AKANTU_DUMPER_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);
-  virtual ~DumperParaview();
+  ~DumperParaview() override;
 
   /* ------------------------------------------------------------------------ */
   /* Methods                                                                  */
   /* ------------------------------------------------------------------------ */
 public:
   // void dump();
 
   /* ------------------------------------------------------------------------ */
   /* Accessors                                                                */
   /* ------------------------------------------------------------------------ */
 public:
-  void setBaseName(const std::string & basename);
+  void setBaseName(const std::string & basename) override;
 
   /* ------------------------------------------------------------------------ */
   /* Class Members                                                            */
   /* ------------------------------------------------------------------------ */
 private:
 
 };
 
 
 } // akantu
 
 #endif /* __AKANTU_DUMPER_PARAVIEW_HH__ */
diff --git a/src/io/mesh_io/mesh_io_abaqus.hh b/src/io/mesh_io/mesh_io_abaqus.hh
index 877d87efc..0f6beec0a 100644
--- a/src/io/mesh_io/mesh_io_abaqus.hh
+++ b/src/io/mesh_io/mesh_io_abaqus.hh
@@ -1,60 +1,60 @@
 /**
  * @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
  *
  * @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)
  *
  * Akantu is free  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 "mesh_io.hh"
 #include "mesh_accessor.hh"
 
 #ifndef __AKANTU_MESH_IO_ABAQUS_HH__
 #define __AKANTU_MESH_IO_ABAQUS_HH__
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 class MeshIOAbaqus : public MeshIO {
 public:
   MeshIOAbaqus();
-  virtual ~MeshIOAbaqus();
+  ~MeshIOAbaqus() override;
 
   /// read a mesh from the file
-  virtual void read(const std::string & filename, Mesh & mesh);
+  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 bd32eed14..d2037f66c 100644
--- a/src/io/mesh_io/mesh_io_diana.cc
+++ b/src/io/mesh_io/mesh_io_diana.cc
@@ -1,604 +1,604 @@
 /**
  * @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
  *
  * @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)
  *
  * Akantu is free  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 <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);
 
     UInt * 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() {}
 
 /* -------------------------------------------------------------------------- */
 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_DEBUG_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_DEBUG_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);
     }
 
     std::stringstream * str = new std::stringstream(line);
 
     UInt id;
     std::string name;
     char c;
     *str >> id >> name >> c;
 
     Array<UInt> * 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);
         std::set<UInt>::iterator 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 = NULL;
+  Array<UInt> * connectivity = nullptr;
   UInt node_per_element = 0;
   Element elem;
-  UInt * read_order = NULL;
+  UInt * read_order = nullptr;
 
   while (1) {
     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];
     strcpy(tutu, line.c_str());
 
     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;
 
   typedef std::map<std::string, Real> MatProp;
   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 (MatProp::iterator 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 (MatProp::iterator 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 7ddcbed5c..65004a5cc 100644
--- a/src/io/mesh_io/mesh_io_diana.hh
+++ b/src/io/mesh_io/mesh_io_diana.hh
@@ -1,107 +1,107 @@
 /**
  * @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
  *
  * @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)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
  * terms  of the  GNU Lesser  General Public  License as  published by  the Free
  * Software Foundation, either version 3 of the License, or (at your option) any
  * later version.
  *
  * Akantu is  distributed in the  hope that it  will be useful, but  WITHOUT ANY
  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  * A  PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 
 #ifndef __AKANTU_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();
-  virtual ~MeshIODiana();
+  ~MeshIODiana() override;
 
   /* ------------------------------------------------------------------------ */
   /* Methods                                                                  */
   /* ------------------------------------------------------------------------ */
 public:
   /// read a mesh from the file
-  virtual void read(const std::string & filename, Mesh & mesh);
+  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);
+  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 4fb0f54bc..c2b7287bf 100644
--- a/src/io/mesh_io/mesh_io_msh.cc
+++ b/src/io/mesh_io/mesh_io_msh.cc
@@ -1,971 +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
  *
  * @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)
  *
  * Akantu is free  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/>.
  *
  */
 
 /* -----------------------------------------------------------------------------
    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[_kirchhoff_shell] = _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() {}
 
 /* -------------------------------------------------------------------------- */
 /* 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_DEBUG_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_DEBUG_ERROR("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_DEBUG_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 = NULL;
+      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 143bd095e..7c905705b 100644
--- a/src/io/mesh_io/mesh_io_msh.hh
+++ b/src/io/mesh_io/mesh_io_msh.hh
@@ -1,115 +1,115 @@
 /**
  * @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
  *
  * @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)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
  * terms  of the  GNU Lesser  General Public  License as  published by  the Free
  * Software Foundation, either version 3 of the License, or (at your option) any
  * later version.
  *
  * Akantu is  distributed in the  hope that it  will be useful, but  WITHOUT ANY
  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  * A  PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 
 #ifndef __AKANTU_MESH_IO_MSH_HH__
 #define __AKANTU_MESH_IO_MSH_HH__
 
 /* -------------------------------------------------------------------------- */
 #include "mesh_io.hh"
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 
 class MeshIOMSH : public MeshIO {
   /* ------------------------------------------------------------------------ */
   /* Constructors/Destructors                                                 */
   /* ------------------------------------------------------------------------ */
 public:
 
   MeshIOMSH();
 
-  virtual ~MeshIOMSH();
+  ~MeshIOMSH() override;
 
   /* ------------------------------------------------------------------------ */
   /* Methods                                                                  */
   /* ------------------------------------------------------------------------ */
 public:
 
   /// read a mesh from the file
-  virtual void read(const std::string & filename, Mesh & mesh);
+  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);
+  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/parser/cppargparse/cppargparse.cc b/src/io/parser/cppargparse/cppargparse.cc
index f4a82dc00..acdc871a8 100644
--- a/src/io/parser/cppargparse/cppargparse.cc
+++ b/src/io/parser/cppargparse/cppargparse.cc
@@ -1,528 +1,531 @@
 /**
  * @file   cppargparse.cc
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Thu Apr 03 2014
  * @date last modification: Wed Nov 11 2015
  *
  * @brief  implementation of the ArgumentParser
  *
  * @section LICENSE
  *
  * Copyright  (©)  2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free  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 "cppargparse.hh"
 
 #include <cstdlib>
 #include <cstring>
 #include <libgen.h>
 
 #include <iostream>
 #include <iomanip>
 #include <string>
 #include <queue>
 #include <sstream>
 #include <algorithm>
 
 #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() : external_exit(NULL), prank(0), psize(1) {
+ArgumentParser::ArgumentParser() : external_exit(nullptr), prank(0), psize(1) {
   this->addArgument("-h;--help", "show this help message and exit", 0, _boolean,
                     false, true);
 }
 
 /* -------------------------------------------------------------------------- */
 ArgumentParser::~ArgumentParser() {
   for (_Arguments::iterator 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 {
   Arguments::const_iterator 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 (std::vector<std::string>::iterator 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);
   char *x = (char *)malloc(len+1); /* 1 for the null terminator */
-  if(!x) return NULL; /* malloc could not allocate memory */
+  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;
 
   for (int i = 0; i < argc; ++i) {
     argvs.push_back(std::string(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 (PositionalArgument::iterator 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;
 
     ArgumentKeyMap::iterator key_it = key_args.find(arg);
 
     bool is_positional = false;
-    _Argument * argument_ptr = NULL;
+    _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; // "+"
-      // [[fallthrough]]; un-comment when compiler will get it
+      /* 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 (_Arguments::iterator 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 (Arguments::const_iterator 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 (_Arguments::const_iterator 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 (PositionalArgument::const_iterator 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;
-    // [[fallthrough]]; un-comment when compiler will get it
+    /* 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 (PositionalArgument::const_iterator 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 (_Arguments::const_iterator 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_tmpl.hh b/src/io/parser/cppargparse/cppargparse_tmpl.hh
index 92a662404..d62452a05 100644
--- a/src/io/parser/cppargparse/cppargparse_tmpl.hh
+++ b/src/io/parser/cppargparse/cppargparse_tmpl.hh
@@ -1,245 +1,245 @@
 /**
  * @file   cppargparse_tmpl.hh
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Thu Apr 03 2014
  * @date last modification: Tue Dec 08 2015
  *
  * @brief  Implementation of the templated part of the commandline argument
  * parser
  *
  * @section LICENSE
  *
  * Copyright  (©)  2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free  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 <stdexcept>
 #include <sstream>
 
 #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()), nargs(1), type(_string),
         required(false), parsed(false), has_default(false), has_const(false),
         is_positional(false) {}
-  virtual ~_Argument() {}
+  ~_Argument() override {}
 
   void setValues(std::vector<std::string> & values) {
     for (std::vector<std::string>::iterator 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;
   ArgumentType type;
   bool required;
   bool parsed;
   bool has_default;
   bool has_const;
   std::vector<std::string> keys;
   bool is_positional;
 };
 
 /* -------------------------------------------------------------------------- */
 /// typed storage of the arguments
 template <class T>
 class ArgumentParser::ArgumentStorage : public ArgumentParser::_Argument {
 public:
   ArgumentStorage() : _default(T()), _const(T()), values(std::vector<T>()) {}
 
-  virtual void addValue(std::string & value) {
+  void addValue(std::string & value) override {
     std::stringstream sstr(value);
     T t;
     sstr >> t;
     values.push_back(t);
   }
 
-  virtual void setToDefault() {
+  void setToDefault() override {
     values.clear();
     values.push_back(_default);
   }
 
-  virtual void setToConst() {
+  void setToConst() override {
     values.clear();
     values.push_back(_const);
   }
 
-  void printself(std::ostream & stream) const {
+  void printself(std::ostream & stream) const override {
     stream << this->name << " =";
     stream << std::boolalpha; // for boolean
     for (typename std::vector<T>::const_iterator vit = this->values.begin();
          vit != this->values.end(); ++vit) {
       stream << " " << *vit;
     }
   }
 
-  virtual std::ostream & _printDefault(std::ostream & stream) const {
+  std::ostream & _printDefault(std::ostream & stream) const override {
     stream << _default;
     return stream;
   }
 
-  virtual std::ostream & _printConst(std::ostream & stream) const {
+  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 ArgumentParser::ArgumentStorage<T> & _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 ArgumentParser::ArgumentStorage<T> & _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/parameter_registry.hh b/src/io/parser/parameter_registry.hh
index 913b81f80..5db930cb4 100644
--- a/src/io/parser/parameter_registry.hh
+++ b/src/io/parser/parameter_registry.hh
@@ -1,217 +1,217 @@
 /**
  * @file   parameter_registry.hh
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Thu Aug 09 2012
  * @date last modification: Thu Dec 17 2015
  *
  * @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)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
  * terms  of the  GNU Lesser  General Public  License as  published by  the Free
  * Software Foundation, either version 3 of the License, or (at your option) any
  * later version.
  *
  * Akantu is  distributed in the  hope that it  will be useful, but  WITHOUT ANY
  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  * A  PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 #include "aka_common.hh"
 #include "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) {
   ParameterAccessType 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;
 };
 
 /* -------------------------------------------------------------------------- */
 /* 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);
+  void setAuto(const ParserParameter & param) override;
   T & getTyped();
   const T & getTyped() const;
 
-  virtual void printself(std::ostream & stream) const;
+  void printself(std::ostream & stream) const override;
 
-  inline operator Real() const;
+  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
   typedef std::map<std::string, Parameter *> Parameters;
   Parameters params;
 
   /// list of sub-registries
   typedef std::map<std::string, ParameterRegistry *> SubRegisteries;
   SubRegisteries sub_registries;
 
   /// should accessor check in sub registries
   bool consisder_sub;
 };
 
 } // akantu
 
 #include "parameter_registry_tmpl.hh"
 
 #endif /* __AKANTU_PARAMETER_REGISTRY_HH__ */
diff --git a/src/io/parser/parsable.hh b/src/io/parser/parsable.hh
index 16dfab955..8911bddd2 100644
--- a/src/io/parser/parsable.hh
+++ b/src/io/parser/parsable.hh
@@ -1,76 +1,76 @@
 /**
  * @file   parameter_registry.hh
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Thu Aug 09 2012
  * @date last modification: Thu Dec 17 2015
  *
  * @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)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
  * terms  of the  GNU Lesser  General Public  License as  published by  the Free
  * Software Foundation, either version 3 of the License, or (at your option) any
  * later version.
  *
  * Akantu is  distributed in the  hope that it  will be useful, but  WITHOUT ANY
  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  * A  PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 #include "aka_common.hh"
 #include "parser.hh"
 #include "parameter_registry.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 SectionType & section_type, const ID & id = std::string());
-  virtual ~Parsable();
+  ~Parsable() override;
 
   /// Add subsection to the sub_sections map
   void registerSubSection(const SectionType & 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:
   SectionType section_type;
   /// ID of parsable object
   ID pid;
   typedef std::pair<SectionType, std::string> SubSectionKey;
   typedef std::map<SubSectionKey, Parsable *> SubSections;
   /// Subsections map
   SubSections sub_sections;
 };
 
 } // akantu
 
 #include "parsable_tmpl.hh"
 
 #endif /* __AKANTU_PARSABLE_HH__ */
diff --git a/src/io/parser/parser.hh b/src/io/parser/parser.hh
index 93f74edf7..ffe397dcc 100644
--- a/src/io/parser/parser.hh
+++ b/src/io/parser/parser.hh
@@ -1,515 +1,515 @@
 /**
  * @file   parser.hh
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Wed Nov 13 2013
  * @date last modification: Wed Jan 13 2016
  *
  * @brief  File parser interface
  *
  * @section LICENSE
  *
  * Copyright  (©)  2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
  * terms  of the  GNU Lesser  General Public  License as  published by  the Free
  * Software Foundation, either version 3 of the License, or (at your option) any
  * later version.
  *
  * Akantu is  distributed in the  hope that it  will be useful, but  WITHOUT ANY
  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  * A  PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 #include "aka_common.hh"
 #include "aka_random_generator.hh"
 /* -------------------------------------------------------------------------- */
 #include <map>
 /* -------------------------------------------------------------------------- */
 
 #ifndef __AKANTU_PARSER_HH__
 #define __AKANTU_PARSER_HH__
 
 namespace akantu {
 
 // clang-format off
 #define AKANTU_SECTION_TYPES                                            \
   (global)                                                              \
   (material)                                                            \
   (model)                                                               \
   (mesh)                                                                \
   (heat)                                                                \
   (contact)                                                             \
   (friction)                                                            \
   (embedded_interface)                                                  \
   (rules)                                                               \
   (non_local)                                                           \
   (user)                                                                \
   (solver)                                                              \
   (neighborhoods)                                                       \
   (neighborhood)                                                        \
   (time_step_solver)                                                    \
   (non_linear_solver)                                                   \
   (model_solver)                                                        \
   (integration_scheme)                                                  \
   (weight_function)                                                     \
   (not_defined)
 // clang-format on
 
 #define AKANTU_SECTION_TYPES_PREFIX(elem) BOOST_PP_CAT(_st_, elem)
 
 #define AKANTU_SECT_PREFIX(s, data, elem) AKANTU_SECTION_TYPES_PREFIX(elem)
 /// Defines the possible section types
 enum SectionType {
   BOOST_PP_SEQ_ENUM(
       BOOST_PP_SEQ_TRANSFORM(AKANTU_SECT_PREFIX, _, AKANTU_SECTION_TYPES))
 };
 #undef AKANTU_SECT_PREFIX
 
 #define AKANTU_SECTION_TYPE_PRINT_CASE(r, data, elem)                          \
   case AKANTU_SECTION_TYPES_PREFIX(elem): {                                    \
     stream << BOOST_PP_STRINGIZE(AKANTU_SECTION_TYPES_PREFIX(elem));           \
     break;                                                                     \
   }
 
 inline std::ostream & operator<<(std::ostream & stream, SectionType type) {
   switch (type) {
     BOOST_PP_SEQ_FOR_EACH(AKANTU_SECTION_TYPE_PRINT_CASE, _,
                           AKANTU_SECTION_TYPES)
   default:
     stream << "not a SectionType";
     break;
   }
   return stream;
 }
 
 #undef AKANTU_SECTION_TYPE_PRINT_CASE
 /// 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()
-      : parent_section(NULL), name(std::string()), value(std::string()),
+      : parent_section(nullptr), 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)
       : parent_section(param.parent_section), name(param.name),
         value(param.value), dbg_filename(param.dbg_filename),
         dbg_line(param.dbg_line), dbg_column(param.dbg_column) {}
 
   virtual ~ParserParameter() {}
 
   /// 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;
   /// 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:
   typedef std::multimap<SectionType, ParserSection> SubSections;
   typedef std::map<std::string, ParserParameter> Parameters;
 
 private:
   typedef SubSections::const_iterator const_section_iterator_;
 
 public:
   /* ------------------------------------------------------------------------ */
   /* SubSection iterator                                                      */
   /* ------------------------------------------------------------------------ */
   /// Iterator on sections
   class const_section_iterator {
   public:
     const_section_iterator() {}
     const_section_iterator(const const_section_iterator & other)
         : it(other.it) {}
     const_section_iterator(const const_section_iterator_ & it) : it(it) {}
 
     const_section_iterator & operator=(const const_section_iterator & other) {
       if (this != &other) {
         it = other.it;
       }
       return *this;
     }
     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)
         : it(other.it) {}
     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()
-      : parent_section(NULL), name(std::string()), type(_st_not_defined) {}
+      : parent_section(nullptr), name(std::string()), type(_st_not_defined) {}
 
   ParserSection(const std::string & name, SectionType type)
-      : parent_section(NULL), name(name), type(type) {}
+      : parent_section(nullptr), name(name), type(type) {}
 
   ParserSection(const std::string & name, SectionType 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() {
     Parameters::iterator pit = this->parameters.begin();
     for (; pit != this->parameters.end(); ++pit)
       pit->second.setParent(*this);
 
     SubSections::iterator sit = this->sub_sections_by_type.begin();
     for (; sit != this->sub_sections_by_type.end(); ++sit)
       sit->second.setParent(*this);
   }
 
   /* ---------------------------------------------------------------------- */
   /* Accessors                                                              */
   /* ---------------------------------------------------------------------- */
 public:
   /// Get begin and end iterators on subsections of certain type
   std::pair<const_section_iterator, const_section_iterator>
   getSubSections(SectionType type = _st_not_defined) const {
     if (type != _st_not_defined) {
       std::pair<const_section_iterator_, const_section_iterator_> range =
           sub_sections_by_type.equal_range(type);
       return std::pair<const_section_iterator, const_section_iterator>(
           range.first, range.second);
     } else {
       return std::pair<const_section_iterator, const_section_iterator>(
           sub_sections_by_type.begin(), sub_sections_by_type.end());
     }
   }
 
   /// Get number of subsections of certain type
   UInt getNbSubSections(SectionType type = _st_not_defined) const {
     if (type != _st_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
   std::pair<const_parameter_iterator, const_parameter_iterator>
   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
   SectionType 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;
   /// Name of section
   std::string name;
   /// Type of section, see AKANTU_SECTION_TYPES
   SectionType type;
   /// 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", _st_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
 
 #include "parser_tmpl.hh"
 
 #endif /* __AKANTU_PARSER_HH__ */
diff --git a/src/mesh/element_type_map.hh b/src/mesh/element_type_map.hh
index 50ead8453..3a93260ad 100644
--- a/src/mesh/element_type_map.hh
+++ b/src/mesh/element_type_map.hh
@@ -1,437 +1,437 @@
 /**
  * @file   element_type_map.hh
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Wed Aug 31 2011
  * @date last modification: Fri Oct 02 2015
  *
  * @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)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
  * terms  of the  GNU Lesser  General Public  License as  published by  the Free
  * Software Foundation, either version 3 of the License, or (at your option) any
  * later version.
  *
  * Akantu is  distributed in the  hope that it  will be useful, but  WITHOUT ANY
  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  * A  PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 #include "aka_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(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();
+  ~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. */
   inline Stored & operator()(const Stored & insert, const SupportType & type,
                              const GhostType & ghost_type = _not_ghost);
 
   /// 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. */
   typedef std::map<SupportType, Stored> DataMap;
   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() {}
 
     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;
 
   template <typename... pack>
   using named_argument_test =
       aka::conjunction<aka::bool_constant<(sizeof...(pack) > 0)>,
                        is_named_argument<pack>...>;
 
 public:
   template <typename... pack>
   std::enable_if_t<named_argument_test<pack...>{}, ElementTypesIteratorHelper>
   elementTypes(pack &&... _pack) const {
     return elementTypesImpl(use_named_args,
                             std::forward<decltype(_pack)>(_pack)...);
   }
 
   template <typename... pack>
   std::enable_if_t<not named_argument_test<pack...>{},
                    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;
 
   /*! 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) const;
 
   /// access the data of an element, this combine the map and array accessor
   inline T & operator()(const Element & element);
 
   /* 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();
 
   /*! 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
-  virtual void printself(std::ostream & stream, int indent = 0) const;
+  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/group_manager.cc b/src/mesh/group_manager.cc
index 11ff31129..9899e747d 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
  *
  * @brief  Stores information about ElementGroup and NodeGroup
  *
  * @section LICENSE
  *
  * Copyright  (©)  2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free  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 "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>
 /* -------------------------------------------------------------------------- */
 
 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_DEBUG_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();
 
   NodeGroups::iterator nit = node_groups.find(group_name);
   NodeGroups::iterator 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 = NULL;
+  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_DEBUG_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(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);
 
       std::set<UInt>::iterator it = global_clusters[c].begin();
       std::set<UInt>::iterator 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 {
+                        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 {
+                       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) {
+                         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, 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, 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,
                                   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);
   typedef typename ElementTypeMapArray<T>::type_iterator 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);
 
         std::map<std::string, UInt>::iterator 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));
         }
       }
     }
   }
 
   std::set<std::string>::iterator git = group_names.begin();
   std::set<std::string>::iterator 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 (const_element_group_iterator it(element_group_begin());
        it != element_group_end(); ++it) {
     it->second->printself(stream, indent + 1);
     node_group_seen.insert(it->second->getNodeGroup().getName());
   }
 
   for (const_node_group_iterator 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();
 
   ElementGroups::const_iterator it = element_groups.begin();
   ElementGroups::const_iterator 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");
 
   NodeGroups::const_iterator nnames_it = node_groups.begin();
   NodeGroups::const_iterator 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");
   ElementGroups::const_iterator gnames_it = this->element_groups.begin();
   ElementGroups::const_iterator 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 {
   const_element_group_iterator 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) {
   element_group_iterator 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 {
   const_node_group_iterator 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) {
   node_group_iterator 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_inline_impl.cc b/src/mesh/group_manager_inline_impl.cc
index d6ebfbbf2..72f4946ff 100644
--- a/src/mesh/group_manager_inline_impl.cc
+++ b/src/mesh/group_manager_inline_impl.cc
@@ -1,207 +1,207 @@
 /**
  * @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
  *
  * @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)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free  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 "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 == NULL)
-    return NULL;
+  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 == NULL)
-    return NULL;
+  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 == NULL)
-    return NULL;
+  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,
     ElementTypeMap<UInt> nb_data_per_elem) {
   const field_type * field_ptr = &field;
-  if (field_ptr == NULL)
-    return NULL;
+  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 == NULL)
-    return NULL;
+  if (field_ptr == nullptr)
+    return nullptr;
   if (group_name == "all")
     throw;
 
   typedef typename field_type::type T;
   ElementGroup & group = this->getElementGroup(group_name);
   UInt dim = group.getDimension();
   if (dim != spatial_dimension)
     throw;
   const ElementTypeMapArray<UInt> & elemental_filter = group.getElements();
 
   ElementTypeMapArrayFilter<T> * 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 == NULL)
-    return NULL;
+  if (field == nullptr)
+    return nullptr;
   if (group_name == "all") {
     typedef typename dumper::NodalField<type, false> DumpType;
-    DumpType * dumper = new DumpType(*field, 0, 0, NULL);
+    DumpType * 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());
     typedef typename dumper::NodalField<type, true> DumpType;
     DumpType * dumper = new DumpType(*field, 0, 0, nodal_filter);
     dumper->setPadding(padding_size);
     return dumper;
   }
-  return NULL;
+  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 NULL;
+    return nullptr;
   if (group_name == "all") {
     typedef typename dumper::NodalField<type, false> DumpType;
     DumpType * 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());
     typedef typename dumper::NodalField<type, true> DumpType;
     DumpType * dumper = new DumpType(*field, size, stride, nodal_filter);
     dumper->setPadding(padding_size);
     return dumper;
   }
-  return NULL;
+  return nullptr;
 }
 
 /* -------------------------------------------------------------------------- */
 
 } // akantu
 
 #endif
diff --git a/src/mesh/mesh.cc b/src/mesh/mesh.cc
index a75f9b14a..a1c460a24 100644
--- a/src/mesh/mesh.cc
+++ b/src/mesh/mesh.cc
@@ -1,472 +1,476 @@
 /**
  * @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
  *
  * @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)
  *
  * Akantu is free  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 <sstream>
-
 #include "aka_config.hh"
-
 /* -------------------------------------------------------------------------- */
 #include "element_class.hh"
 #include "group_manager_inline_impl.cc"
 #include "mesh.hh"
 #include "mesh_io.hh"
+#include "mesh_utils.hh"
 /* -------------------------------------------------------------------------- */
 #include "element_synchronizer.hh"
 #include "facet_synchronizer.hh"
 #include "mesh_utils_distribution.hh"
 #include "node_synchronizer.hh"
 #include "communicator.hh"
 /* -------------------------------------------------------------------------- */
 #ifdef AKANTU_USE_IOHELPER
 #include "dumper_field.hh"
 #include "dumper_internal_material_field.hh"
 #endif
 /* -------------------------------------------------------------------------- */
+#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, 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();
 }
 
 /* -------------------------------------------------------------------------- */
 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());
     }
   }
 
   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(_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_DEBUG_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 ffaa08a3b..a22dea521 100644
--- a/src/mesh/mesh.hh
+++ b/src/mesh/mesh.hh
@@ -1,602 +1,602 @@
 /**
  * @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
  *
  * @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)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
  * terms  of the  GNU Lesser  General Public  License as  published by  the Free
  * Software Foundation, either version 3 of the License, or (at your option) any
  * later version.
  *
  * Akantu is  distributed in the  hope that it  will be useful, but  WITHOUT ANY
  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  * A  PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 #ifndef __AKANTU_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}
  Mesh::type_iterator it = mesh.firstType(dim, ghost_type);
  Mesh::type_iterator end = mesh.lastType(dim, ghost_type);
  for(; it != end; ++it) {
    UInt nb_element  = mesh.getNbElement(*it);
    const Array<UInt> & conn = mesh.getConnectivity(*it);
    for(UInt e = 0; e < nb_element; ++e) {
      ...
    }
  }
  @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, std::shared_ptr<Array<Real>> nodes,
        const ID & id = "mesh", const MemoryID & memory_id = 0);
 
-  virtual ~Mesh();
+  ~Mesh() override;
 
   /// @typedef ConnectivityTypeList list of the types present in a Mesh
   typedef std::set<ElementType> ConnectivityTypeList;
 
   /// 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
-  virtual void printself(std::ostream & stream, int indent = 0) const;
+  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);
 
   /// convert a element to a linearized element
   inline UInt elementToLinearized(const Element & elem) const;
 
   /// convert a linearized element to an element
   inline Element linearizedToElement(UInt linearized_element) const;
 
   /// update the types offsets array for the conversions
   // inline void updateTypesOffsets(const GhostType & ghost_type);
 
   /// 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
   inline void getBarycenter(UInt element, const ElementType & type,
                             Real * barycenter,
                             GhostType ghost_type = _not_ghost) const;
   inline void getBarycenter(const Element & element,
                             Vector<Real> & barycenter) const;
 
   /// get the element connected to a subelement
   const Array<std::vector<Element>> &
   getElementToSubelement(const ElementType & el_type,
                          const GhostType & ghost_type = _not_ghost) const;
   /// get the element connected to a subelement
   Array<std::vector<Element>> &
   getElementToSubelement(const ElementType & el_type,
                          const GhostType & ghost_type = _not_ghost);
 
   /// get the subelement connected to an element
   const Array<Element> &
   getSubelementToElement(const ElementType & el_type,
                          const GhostType & ghost_type = _not_ghost) const;
   /// get the subelement connected to an element
   Array<Element> &
   getSubelementToElement(const ElementType & el_type,
                          const GhostType & ghost_type = _not_ghost);
 
   /// 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);
 
   /// 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);
 
   /// get local connectivity of a facet for a given facet type
   static inline MatrixProxy<UInt>
   getFacetLocalConnectivity(const ElementType & type, UInt t = 0);
 
   /// get connectivity of facets for a given element
   inline Matrix<UInt> getFacetConnectivity(const Element & element,
                                            UInt t = 0) const;
 
   /// 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);
 
   /// get the type of the surface element associated to a given element
   static inline ElementType getFacetType(const ElementType & type, UInt t = 0);
 
   /// get all the type of the surface element associated to a given element
   static inline VectorProxy<ElementType>
   getAllFacetTypes(const ElementType & type);
 
   /// 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
   // &);
   AKANTU_GET_MACRO(Communicator, *communicator, const auto &);
   /* ------------------------------------------------------------------------ */
   /* Private methods for friends                                              */
   /* ------------------------------------------------------------------------ */
 private:
   friend class MeshAccessor;
 
   //#if defined(AKANTU_COHESIVE_ELEMENT)
   //  friend class CohesiveElementInserter;
   //#endif
 
   //#if defined(AKANTU_IGFEM)
   //  template <UInt dim> friend class MeshIgfemSphericalGrowingGel;
   //#endif
 
   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
   const 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_data.hh b/src/mesh/mesh_data.hh
index 92f634eb6..41f2e445c 100644
--- a/src/mesh/mesh_data.hh
+++ b/src/mesh/mesh_data.hh
@@ -1,150 +1,150 @@
 /**
  * @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
  *
  * @brief  Stores generic data loaded from the mesh file
  *
  * @section LICENSE
  *
  * Copyright  (©)  2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
  * terms  of the  GNU Lesser  General Public  License as  published by  the Free
  * Software Foundation, either version 3 of the License, or (at your option) any
  * later version.
  *
  * Akantu is  distributed in the  hope that it  will be useful, but  WITHOUT ANY
  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  * A  PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 
 #ifndef __AKANTU_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:
   typedef MeshDataTypeCode TypeCode;
   typedef std::map<std::string, ElementTypeMapBase *> ElementalDataMap;
   typedef std::vector<std::string> StringVector;
   typedef std::map<std::string, TypeCode> TypeCodeMap;
 
   /* ------------------------------------------------------------------------ */
   /* Constructors/Destructors                                                 */
   /* ------------------------------------------------------------------------ */
 public:
   MeshData(const ID & id = "mesh_data", const ID & parent_id = "",
            const MemoryID & memory_id = 0);
-  ~MeshData();
+  ~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);
 
   /// Get an existing elemental data array
   template <typename T>
   bool hasDataArray(const ID & data_name, const ElementType & el_type,
                     const GhostType & ghost_type = _not_ghost) 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_events.hh b/src/mesh/mesh_events.hh
index bb0cb2539..77dc78da3 100644
--- a/src/mesh/mesh_events.hh
+++ b/src/mesh/mesh_events.hh
@@ -1,187 +1,187 @@
 /**
  * @file   mesh_events.hh
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Fri Feb 20 2015
  * @date last modification: Mon Dec 07 2015
  *
  * @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)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
  * terms  of the  GNU Lesser  General Public  License as  published by  the Free
  * Software Foundation, either version 3 of the License, or (at your option) any
  * later version.
  *
  * Akantu is  distributed in the  hope that it  will be useful, but  WITHOUT ANY
  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  * A  PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 #include "aka_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() {}
   /// 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:
-  virtual ~NewNodesEvent(){};
+  ~NewNodesEvent() override{};
 };
 
 /// akantu::MeshEvent related to nodes removed from the mesh
 class RemovedNodesEvent : public MeshEvent<UInt> {
 public:
-  virtual ~RemovedNodesEvent(){};
+  ~RemovedNodesEvent() override{};
   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:
-  virtual ~NewElementsEvent(){};
+  ~NewElementsEvent() override{};
 };
 
 /// akantu::MeshEvent related to elements removed from the mesh
 class RemovedElementsEvent : public MeshEvent<Element> {
 public:
-  virtual ~RemovedElementsEvent(){};
+  ~RemovedElementsEvent() override{};
   inline RemovedElementsEvent(const Mesh & mesh,
                               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:
-  virtual ~ChangedElementsEvent(){};
+  ~ChangedElementsEvent() override{};
   inline ChangedElementsEvent(
       const Mesh & mesh, ID new_numbering_id = "changed_event:new_numbering")
       : RemovedElementsEvent(mesh, 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(){};
   /* ------------------------------------------------------------------------ */
   /* 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) = 0;
   /// function to implement to react on  akantu::RemovedNodesEvent
   virtual void onNodesRemoved(const Array<UInt> & nodes_list,
                               const Array<UInt> & new_numbering,
                               const RemovedNodesEvent & event) = 0;
   /// function to implement to react on  akantu::NewElementsEvent
   virtual void onElementsAdded(const Array<Element> & elements_list,
                                const NewElementsEvent & event) = 0;
   /// function to implement to react on  akantu::RemovedElementsEvent
   virtual void
   onElementsRemoved(const Array<Element> & elements_list,
                     const ElementTypeMapArray<UInt> & new_numbering,
                     const RemovedElementsEvent & event) = 0;
   /// 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) = 0;
 };
 
 } // akantu
 
 #endif /* __AKANTU_MESH_EVENTS_HH__ */
diff --git a/src/mesh/mesh_inline_impl.cc b/src/mesh/mesh_inline_impl.cc
index a506bee50..df8fe3c66 100644
--- a/src/mesh/mesh_inline_impl.cc
+++ b/src/mesh/mesh_inline_impl.cc
@@ -1,635 +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
  *
  * @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)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
  * terms  of the  GNU Lesser  General Public  License as  published by  the Free
  * Software Foundation, either version 3 of the License, or (at your option) any
  * later version.
  *
  * Akantu is  distributed in the  hope that it  will be useful, but  WITHOUT ANY
  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  * A  PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 #include "aka_iterators.hh"
 #include "mesh.hh"
 /* -------------------------------------------------------------------------- */
 #if defined(AKANTU_COHESIVE_ELEMENT)
 #include "cohesive_element.hh"
 #endif
 /* -------------------------------------------------------------------------- */
 
 #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,
                                                   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 Array<std::vector<Element>> &
 Mesh::getElementToSubelement(const ElementType & type,
                              const GhostType & ghost_type) const {
   return getData<std::vector<Element>>("element_to_subelement", type,
                                        ghost_type);
 }
 
 /* -------------------------------------------------------------------------- */
 inline Array<std::vector<Element>> &
 Mesh::getElementToSubelement(const ElementType & type,
                              const GhostType & ghost_type) {
   return getData<std::vector<Element>>("element_to_subelement", type,
                                        ghost_type);
 }
 
 /* -------------------------------------------------------------------------- */
 inline const Array<Element> &
 Mesh::getSubelementToElement(const ElementType & type,
                              const GhostType & ghost_type) const {
   return getData<Element>("subelement_to_element", type, ghost_type);
 }
 
 /* -------------------------------------------------------------------------- */
 inline Array<Element> &
 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);
 }
 
 /* -------------------------------------------------------------------------- */
 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);
 
   Real * 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 ElementType Mesh::getFacetType(const ElementType & type, UInt t) {
   ElementType surface_type = _not_defined;
 #define GET_FACET_TYPE(type) surface_type = ElementClass<type>::getFacetType(t)
   AKANTU_BOOST_ALL_ELEMENT_SWITCH(GET_FACET_TYPE);
 #undef GET_FACET_TYPE
 
   return surface_type;
 }
 
 /* -------------------------------------------------------------------------- */
 inline VectorProxy<ElementType>
 Mesh::getAllFacetTypes(const ElementType & type) {
 #define GET_FACET_TYPE(type)                                                   \
   UInt nb = ElementClass<type>::getNbFacetTypes();                             \
   ElementType * elt_ptr =                                                      \
       const_cast<ElementType *>(ElementClass<type>::getFacetTypeInternal());   \
   return VectorProxy<ElementType>(elt_ptr, nb);
 
   AKANTU_BOOST_ALL_ELEMENT_SWITCH(GET_FACET_TYPE);
 #undef GET_FACET_TYPE
 }
 
 /* -------------------------------------------------------------------------- */
 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 MatrixProxy<UInt>
 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 MatrixProxy<UInt>(
       nullptr, 0, 0); // This avoid a compilation warning but will certainly
   // also cause a segfault if reached
 }
 
 /* -------------------------------------------------------------------------- */
 inline Matrix<UInt> Mesh::getFacetConnectivity(const Element & element,
                                                UInt t) const {
   AKANTU_DEBUG_IN();
 
   Matrix<UInt> local_facets(getFacetLocalConnectivity(element.type, t), false);
   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 != NULL, "The global ids are note set.");
+  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_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_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_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/node_group.hh b/src/mesh/node_group.hh
index 1003698b6..b8362db4f 100644
--- a/src/mesh/node_group.hh
+++ b/src/mesh/node_group.hh
@@ -1,141 +1,141 @@
 /**
  * @file   node_group.hh
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Fri Jun 18 2010
  * @date last modification: Tue Dec 08 2015
  *
  * @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)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
  * terms  of the  GNU Lesser  General Public  License as  published by  the Free
  * Software Foundation, either version 3 of the License, or (at your option) any
  * later version.
  *
  * Akantu is  distributed in the  hope that it  will be useful, but  WITHOUT ANY
  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  * A  PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 #include "aka_common.hh"
 #include "aka_array.hh"
 #include "aka_memory.hh"
 #include "mesh_filter.hh"
 #include "dumpable.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);
-  virtual ~NodeGroup();
+  ~NodeGroup() override;
 
   /* ------------------------------------------------------------------------ */
   /* Methods                                                                  */
   /* ------------------------------------------------------------------------ */
 public:
   typedef Array<UInt>::const_iterator<UInt> const_node_iterator;
 
   /// 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);
 
   inline decltype(auto) find(UInt node) const {
     return node_group.find(node);
   }
   
   /// 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_utils/cohesive_element_inserter.cc b/src/mesh_utils/cohesive_element_inserter.cc
index 65ef1d158..e328de401 100644
--- a/src/mesh_utils/cohesive_element_inserter.cc
+++ b/src/mesh_utils/cohesive_element_inserter.cc
@@ -1,451 +1,449 @@
 /**
  * @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
  *
  * @brief  Cohesive element inserter functions
  *
  * @section LICENSE
  *
  * Copyright  (©)  2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free  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 "element_group.hh"
 //#include "facet_synchronizer.hh"
 #include "global_ids_updater.hh"
 /* -------------------------------------------------------------------------- */
 #include <algorithm>
 #include <limits>
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 
 CohesiveElementInserter::CohesiveElementInserter(Mesh & mesh, bool is_extrinsic,
                                                  const ID & id)
     : id(id), mesh(mesh), mesh_facets(mesh.initMeshFacets()),
       insertion_facets("insertion_facets", id),
       insertion_limits(mesh.getSpatialDimension(), 2),
       check_facets("check_facets", id) {
-
-  MeshUtils::buildAllFacets(mesh, mesh_facets, 0);
   init(is_extrinsic);
 }
 
 /* -------------------------------------------------------------------------- */
 CohesiveElementInserter::~CohesiveElementInserter() {
 #if defined(AKANTU_PARALLEL_COHESIVE_ELEMENT)
   delete global_ids_updater;
 #endif
 }
 
 /* -------------------------------------------------------------------------- */
 void CohesiveElementInserter::init(bool is_extrinsic) {
   AKANTU_DEBUG_IN();
 
   UInt spatial_dimension = mesh.getSpatialDimension();
 
   MeshUtils::resetFacetToDouble(mesh_facets);
 
   /// initialize facet insertion array
   insertion_facets.initialize(mesh_facets,
                               _spatial_dimension = (spatial_dimension - 1),
                               _with_nb_element = true);
   // mesh_facets.initElementTypeMapArray(
   //     insertion_facets, 1, spatial_dimension - 1, false, _ek_regular, true);
 
   /// init insertion limits
   for (UInt dim = 0; dim < spatial_dimension; ++dim) {
     insertion_limits(dim, 0) = std::numeric_limits<Real>::max() * (-1.);
     insertion_limits(dim, 1) = std::numeric_limits<Real>::max();
   }
 
   if (is_extrinsic) {
     check_facets.initialize(mesh_facets,
                             _spatial_dimension = spatial_dimension - 1);
     // mesh_facets.initElementTypeMapArray(check_facets, 1, spatial_dimension -
     // 1);
     initFacetsCheck();
   }
 
 #if defined(AKANTU_PARALLEL_COHESIVE_ELEMENT)
   facet_synchronizer = NULL;
   global_ids_updater = NULL;
 #endif
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void CohesiveElementInserter::initFacetsCheck() {
   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 facet_gt = *gt;
     Mesh::type_iterator it =
         mesh_facets.firstType(spatial_dimension - 1, facet_gt);
     Mesh::type_iterator last =
         mesh_facets.lastType(spatial_dimension - 1, facet_gt);
 
     for (; it != last; ++it) {
       ElementType facet_type = *it;
 
       Array<bool> & f_check = check_facets(facet_type, facet_gt);
 
       const Array<std::vector<Element>> & element_to_facet =
           mesh_facets.getElementToSubelement(facet_type, facet_gt);
 
       UInt nb_facet = element_to_facet.size();
       f_check.resize(nb_facet);
 
       for (UInt f = 0; f < nb_facet; ++f) {
         if (element_to_facet(f)[1] == ElementNull ||
             (element_to_facet(f)[0].ghost_type == _ghost &&
              element_to_facet(f)[1].ghost_type == _ghost)) {
           f_check(f) = false;
         } else
           f_check(f) = true;
       }
     }
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void CohesiveElementInserter::limitCheckFacets() {
   AKANTU_DEBUG_IN();
 
   UInt spatial_dimension = mesh.getSpatialDimension();
   Vector<Real> bary_facet(spatial_dimension);
 
   for (ghost_type_t::iterator gt = ghost_type_t::begin();
        gt != ghost_type_t::end(); ++gt) {
     GhostType ghost_type = *gt;
 
     Mesh::type_iterator it =
         mesh_facets.firstType(spatial_dimension - 1, ghost_type);
     Mesh::type_iterator end =
         mesh_facets.lastType(spatial_dimension - 1, ghost_type);
     for (; it != end; ++it) {
       ElementType type = *it;
       Array<bool> & f_check = check_facets(type, ghost_type);
       UInt nb_facet = mesh_facets.getNbElement(type, ghost_type);
 
       for (UInt f = 0; f < nb_facet; ++f) {
         if (f_check(f)) {
 
           mesh_facets.getBarycenter(f, type, bary_facet.storage(), ghost_type);
 
           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)
             f_check(f) = false;
         }
       }
     }
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 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() {
   AKANTU_DEBUG_IN();
 
   UInt spatial_dimension = mesh.getSpatialDimension();
 
   Vector<Real> bary_facet(spatial_dimension);
 
   for (auto && ghost_type : ghost_types) {
     for (const auto & type_facet :
          mesh_facets.elementTypes(spatial_dimension - 1, ghost_type)) {
       auto & f_insertion = insertion_facets(type_facet, ghost_type);
       auto & element_to_facet =
           mesh_facets.getElementToSubelement(type_facet, ghost_type);
 
       UInt nb_facet = mesh_facets.getNbElement(type_facet, ghost_type);
       for (UInt f = 0; f < nb_facet; ++f) {
 
         if (element_to_facet(f)[1] == ElementNull)
           continue;
 
         mesh_facets.getBarycenter(f, type_facet, bary_facet.storage(),
                                   ghost_type);
 
         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)
           f_insertion(f) = true;
       }
     }
   }
 
   AKANTU_DEBUG_OUT();
 
   return insertElements();
 }
 
 /* -------------------------------------------------------------------------- */
 void CohesiveElementInserter::insertIntrinsicElements(std::string physname,
                                                       UInt material_index) {
   AKANTU_DEBUG_IN();
 
   UInt spatial_dimension = mesh.getSpatialDimension();
   ElementTypeMapArray<UInt> * phys_data;
   try {
     phys_data = &(mesh_facets.getData<UInt>("physical_names"));
   } catch (...) {
     phys_data = &(mesh_facets.registerData<UInt>("physical_names"));
     phys_data->initialize(mesh_facets,
                           _spatial_dimension = spatial_dimension - 1,
                           _with_nb_element = true);
     // mesh_facets.initElementTypeMapArray(*phys_data, 1, spatial_dimension - 1,
     //                                     false, _ek_regular, true);
   }
   Vector<Real> bary_facet(spatial_dimension);
   mesh_facets.createElementGroup(physname);
 
   GhostType ghost_type = _not_ghost;
 
   Mesh::type_iterator it =
       mesh_facets.firstType(spatial_dimension - 1, ghost_type);
   Mesh::type_iterator end =
       mesh_facets.lastType(spatial_dimension - 1, ghost_type);
 
   for (; it != end; ++it) {
     const ElementType type_facet = *it;
     Array<bool> & f_insertion = insertion_facets(type_facet, ghost_type);
     Array<std::vector<Element>> & element_to_facet =
         mesh_facets.getElementToSubelement(type_facet, ghost_type);
 
     UInt nb_facet = mesh_facets.getNbElement(type_facet, ghost_type);
     UInt coord_in_limit = 0;
 
     ElementGroup & group = mesh.getElementGroup(physname);
     ElementGroup & group_facet = mesh_facets.getElementGroup(physname);
 
     Vector<Real> bary_physgroup(spatial_dimension);
     Real norm_bary;
     for (ElementGroup::const_element_iterator el_it(
              group.begin(type_facet, ghost_type));
          el_it != group.end(type_facet, ghost_type); ++el_it) {
 
       UInt e = *el_it;
       mesh.getBarycenter(e, type_facet, bary_physgroup.storage(), ghost_type);
 #ifndef AKANTU_NDEBUG
       bool find_a_partner = false;
 #endif
       norm_bary = bary_physgroup.norm();
       Array<UInt> & material_id = (*phys_data)(type_facet, ghost_type);
 
       for (UInt f = 0; f < nb_facet; ++f) {
 
         if (element_to_facet(f)[1] == ElementNull)
           continue;
 
         mesh_facets.getBarycenter(f, type_facet, bary_facet.storage(),
                                   ghost_type);
 
         coord_in_limit = 0;
 
         while (coord_in_limit < spatial_dimension &&
                (std::abs(bary_facet(coord_in_limit) -
                          bary_physgroup(coord_in_limit)) /
                     norm_bary <
                 Math::getTolerance()))
           ++coord_in_limit;
 
         if (coord_in_limit == spatial_dimension) {
           f_insertion(f) = true;
 #ifndef AKANTU_NDEBUG
           find_a_partner = true;
 #endif
           group_facet.add(type_facet, f, ghost_type, false);
           material_id(f) = material_index;
           break;
         }
       }
       AKANTU_DEBUG_ASSERT(find_a_partner,
                           "The element nO "
                               << e << " of physical group " << physname
                               << " did not find its associated facet!"
                               << " Try to decrease math tolerance. "
                               << std::endl);
     }
   }
   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 defined(AKANTU_PARALLEL_COHESIVE_ELEMENT)
   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, _so_sum);
   }
 #endif
 
   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 defined(AKANTU_PARALLEL_COHESIVE_ELEMENT)
   if (mesh.isDistributed()) {
     /// update global ids
     this->synchronizeGlobalIDs(node_event);
   }
 #endif
 
   return nb_new_elements;
 }
 
 /* -------------------------------------------------------------------------- */
 void CohesiveElementInserter::updateInsertionFacets() {
   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 facet_gt = *gt;
     Mesh::type_iterator it =
         mesh_facets.firstType(spatial_dimension - 1, facet_gt);
     Mesh::type_iterator last =
         mesh_facets.lastType(spatial_dimension - 1, facet_gt);
 
     for (; it != last; ++it) {
       ElementType facet_type = *it;
 
       Array<bool> & ins_facets = insertion_facets(facet_type, facet_gt);
 
       // this is the extrinsic case
       if (check_facets.exists(facet_type, facet_gt)) {
         Array<bool> & f_check = check_facets(facet_type, facet_gt);
 
         UInt nb_facets = f_check.size();
 
         for (UInt f = 0; f < ins_facets.size(); ++f) {
           if (ins_facets(f)) {
             ++nb_facets;
             ins_facets(f) = false;
             f_check(f) = false;
           }
         }
 
         f_check.resize(nb_facets);
       }
       // and this the intrinsic one
       else {
         ins_facets.resize(mesh_facets.getNbElement(facet_type, facet_gt));
         ins_facets.set(false);
       }
     }
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void CohesiveElementInserter::printself(std::ostream & stream,
                                         int indent) const {
   std::string space;
   for (Int i = 0; i < indent; i++, space += AKANTU_INDENT)
     ;
 
   stream << space << "CohesiveElementInserter [" << std::endl;
 
   stream << space << " + mesh [" << std::endl;
   mesh.printself(stream, indent + 2);
   stream << space << AKANTU_INDENT << "]" << std::endl;
 
   stream << space << " + mesh_facets [" << std::endl;
   mesh_facets.printself(stream, indent + 2);
   stream << space << AKANTU_INDENT << "]" << std::endl;
 
   stream << space << "]" << std::endl;
 }
 
 } // namespace akantu
diff --git a/src/mesh_utils/cohesive_element_inserter.hh b/src/mesh_utils/cohesive_element_inserter.hh
index decc1fc45..f220d71f9 100644
--- a/src/mesh_utils/cohesive_element_inserter.hh
+++ b/src/mesh_utils/cohesive_element_inserter.hh
@@ -1,204 +1,204 @@
 /**
  * @file   cohesive_element_inserter.hh
  *
  * @author Fabian Barras <fabian.barras@epfl.ch>
  * @author Marco Vocialta <marco.vocialta@epfl.ch>
  *
  * @date creation: Wed Dec 04 2013
  * @date last modification: Fri Oct 02 2015
  *
  * @brief  Cohesive element inserter
  *
  * @section LICENSE
  *
  * Copyright  (©)  2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
  * terms  of the  GNU Lesser  General Public  License as  published by  the Free
  * Software Foundation, either version 3 of the License, or (at your option) any
  * later version.
  *
  * Akantu is  distributed in the  hope that it  will be useful, but  WITHOUT ANY
  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  * A  PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 /* -------------------------------------------------------------------------- */
 #include "data_accessor.hh"
 #include "mesh_utils.hh"
 /* -------------------------------------------------------------------------- */
 #include <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> {
   /* ------------------------------------------------------------------------ */
   /* Constructors/Destructors                                                 */
   /* ------------------------------------------------------------------------ */
 public:
   CohesiveElementInserter(Mesh & mesh, bool is_extrinsic = false,
                           const ID & id = "cohesive_element_inserter");
 
-  virtual ~CohesiveElementInserter();
+  ~CohesiveElementInserter() override;
 
   /* ------------------------------------------------------------------------ */
   /* Methods                                                                  */
   /* ------------------------------------------------------------------------ */
 public:
   /// init function
   void init(bool is_extrinsic);
 
   /// 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();
 
   /// preset insertion of intrinsic cohesive elements along
   /// a predefined group of facet and assign them a defined material index.
   /// insertElement() method has to be called to finalize insertion.
   void insertIntrinsicElements(std::string physname, UInt material_index);
 
   /// insert extrinsic cohesive elements (returns the number of new
   /// cohesive elements)
   UInt insertElements(bool only_double_facets = false);
 
   /// function to print the contain of the class
   virtual void printself(std::ostream & stream, int indent = 0) const;
 
   /// limit check facets to match given insertion limits
   void limitCheckFacets();
 
 #if defined(AKANTU_PARALLEL_COHESIVE_ELEMENT)
   /// init parallel variables
   void initParallel(FacetSynchronizer * facet_synchronizer,
                     ElementSynchronizer * element_synchronizer);
 #endif
 
 protected:
   /// init facets check
   void initFacetsCheck();
 
   /// 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_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 &);
 
   /* ------------------------------------------------------------------------ */
   /* 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
   Array<Real> insertion_limits;
 
   /// vector containing facets in which extrinsic cohesive elements can be
   /// inserted
   ElementTypeMapArray<bool> check_facets;
 
   // /// facet synchronizer
   // FacetSynchronizer & facet_synchronizer;
 
   /// global connectivity ids updater
   std::unique_ptr<GlobalIdsUpdater> global_ids_updater;
 };
 
 /* -------------------------------------------------------------------------- */
 /* inline functions                                                           */
 /* -------------------------------------------------------------------------- */
 
 /// standard output stream operator
 inline std::ostream & operator<<(std::ostream & stream,
                                  const CohesiveElementInserter & _this) {
   _this.printself(stream);
   return stream;
 }
 
 class CohesiveNewNodesEvent : public NewNodesEvent{
 public:
   CohesiveNewNodesEvent() = default;
-  virtual ~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 350049797..0837a19ec 100644
--- a/src/mesh_utils/cohesive_element_inserter_inline_impl.cc
+++ b/src/mesh_utils/cohesive_element_inserter_inline_impl.cc
@@ -1,106 +1,106 @@
 /**
  * @file   cohesive_element_inserter_inline_impl.cc
  *
  * @author Marco Vocialta <marco.vocialta@epfl.ch>
  *
  *
  * @brief  Cohesive element inserter inline functions
  *
  * @section LICENSE
  *
  * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  */
 /* -------------------------------------------------------------------------- */
 #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();
 
   ElementType current_element_type = _not_defined;
   GhostType current_ghost_type = _casper;
   ElementTypeMapArray<UInt> & physical_names =
       mesh_facets.registerData<UInt>("physical_names");
 
-  Array<bool> * vect = NULL;
-  Array<unsigned int> * vect2 = NULL;
+  Array<bool> * vect = nullptr;
+  Array<unsigned int> * vect2 = nullptr;
 
   Array<Element>::const_iterator<Element> it = elements.begin();
   Array<Element>::const_iterator<Element> 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;
       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/global_ids_updater.hh b/src/mesh_utils/global_ids_updater.hh
index 6cbe5e79e..eadc66eb0 100644
--- a/src/mesh_utils/global_ids_updater.hh
+++ b/src/mesh_utils/global_ids_updater.hh
@@ -1,100 +1,100 @@
 /**
  * @file   global_ids_updater.hh
  *
  * @author Marco Vocialta <marco.vocialta@epfl.ch>
  *
  * @date creation: Fri Oct 02 2015
  *
  * @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)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
  * terms  of the  GNU Lesser  General Public  License as  published by  the Free
  * Software Foundation, either version 3 of the License, or (at your option) any
  * later version.
  *
  * Akantu is  distributed in the  hope that it  will be useful, but  WITHOUT ANY
  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  * A  PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 #ifndef __AKANTU_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 virtual UInt getNbData(const Array<Element> & elements,
-                                const SynchronizationTag & tag) const;
+  inline UInt getNbData(const Array<Element> & elements,
+                        const SynchronizationTag & tag) const override;
 
-  inline virtual void packData(CommunicationBuffer & buffer,
-                               const Array<Element> & elements,
-                               const SynchronizationTag & tag) const;
+  inline void packData(CommunicationBuffer & buffer,
+                       const Array<Element> & elements,
+                       const SynchronizationTag & tag) const override;
 
-  inline virtual void unpackData(CommunicationBuffer & buffer,
-                                 const Array<Element> & elements,
-                                 const SynchronizationTag & tag);
+  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/mesh_partition.hh b/src/mesh_utils/mesh_partition.hh
index 7f834ce03..cb2caacb3 100644
--- a/src/mesh_utils/mesh_partition.hh
+++ b/src/mesh_utils/mesh_partition.hh
@@ -1,151 +1,151 @@
 /**
  * @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
  *
  * @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)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
  * terms  of the  GNU Lesser  General Public  License as  published by  the Free
  * Software Foundation, either version 3 of the License, or (at your option) any
  * later version.
  *
  * Akantu is  distributed in the  hope that it  will be useful, but  WITHOUT ANY
  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  * A  PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 
 #ifndef __AKANTU_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);
 
-  virtual ~MeshPartition();
+  ~MeshPartition() override;
 
   class EdgeLoadFunctor {
   public:
     virtual Int operator()(const Element & el1, const Element & el2) const
         noexcept = 0;
   };
 
   class ConstEdgeLoadFunctor : public EdgeLoadFunctor {
   public:
-    virtual inline Int operator()(const Element &, const Element &) const
-        noexcept {
+    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);
 
   /* ------------------------------------------------------------------------ */
   /* 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;
 
   Array<Element> lin_to_element;
 };
 
 } // 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.hh b/src/mesh_utils/mesh_partition/mesh_partition_mesh_data.hh
index bfb340547..a8f44b91a 100644
--- a/src/mesh_utils/mesh_partition/mesh_partition_mesh_data.hh
+++ b/src/mesh_utils/mesh_partition/mesh_partition_mesh_data.hh
@@ -1,98 +1,98 @@
 /**
  * @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
  *
  * @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)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
  * terms  of the  GNU Lesser  General Public  License as  published by  the Free
  * Software Foundation, either version 3 of the License, or (at your option) any
  * later version.
  *
  * Akantu is  distributed in the  hope that it  will be useful, but  WITHOUT ANY
  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  * A  PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 
 #ifndef __AKANTU_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;
 
-  virtual void partitionate(UInt nb_part,
-                            const EdgeLoadFunctor & edge_load_func = ConstEdgeLoadFunctor(),
-                            const Array<UInt> & pairs = Array<UInt>());
-
-  virtual void reorder();
+  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.hh b/src/mesh_utils/mesh_partition/mesh_partition_scotch.hh
index 81eb819b3..e96865878 100644
--- a/src/mesh_utils/mesh_partition/mesh_partition_scotch.hh
+++ b/src/mesh_utils/mesh_partition/mesh_partition_scotch.hh
@@ -1,81 +1,81 @@
 /**
  * @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
  *
  * @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)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
  * terms  of the  GNU Lesser  General Public  License as  published by  the Free
  * Software Foundation, either version 3 of the License, or (at your option) any
  * later version.
  *
  * Akantu is  distributed in the  hope that it  will be useful, but  WITHOUT ANY
  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  * A  PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 
 #ifndef __AKANTU_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;
 
-  virtual void partitionate(UInt nb_part,
-			    const EdgeLoadFunctor & edge_load_func = ConstEdgeLoadFunctor(),
-			    const Array<UInt> & pairs = Array<UInt>());
-
-  virtual void reorder();
+  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 7ee541f65..d4378f2b7 100644
--- a/src/mesh_utils/mesh_utils.cc
+++ b/src/mesh_utils/mesh_utils.cc
@@ -1,2172 +1,2172 @@
 /**
  * @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
  *
  * @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)
  *
  * Akantu is free  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 "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 (ghost_type_t::iterator gt = ghost_type_t::begin();
        gt != ghost_type_t::end(); ++gt) {
     Mesh::type_iterator first =
         mesh.firstType(spatial_dimension, *gt, _ek_not_defined);
     Mesh::type_iterator last =
         mesh.lastType(spatial_dimension, *gt, _ek_not_defined);
 
     for (; first != last; ++first) {
       ElementType type = *first;
       UInt nb_element = mesh.getNbElement(type, *gt);
       Array<UInt>::const_iterator<Vector<UInt>> conn_it =
           mesh.getConnectivity(type, *gt).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 (ghost_type_t::iterator gt = ghost_type_t::begin();
        gt != ghost_type_t::end(); ++gt) {
     Mesh::type_iterator first =
         mesh.firstType(spatial_dimension, *gt, _ek_not_defined);
     Mesh::type_iterator last =
         mesh.lastType(spatial_dimension, *gt, _ek_not_defined);
     e.ghost_type = *gt;
     for (; first != last; ++first) {
       ElementType type = *first;
       e.type = type;
       UInt nb_element = mesh.getNbElement(type, *gt);
       Array<UInt>::const_iterator<Vector<UInt>> conn_it =
           mesh.getConnectivity(type, *gt).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();
 }
 
 /* -------------------------------------------------------------------------- */
 /**
  * This function should disappear in the future (used in mesh partitioning)
  */
 // void MeshUtils::buildNode2Elements(const Mesh & mesh, CSR<UInt> &
 // node_to_elem,
 //                                    UInt spatial_dimension) {
 //   AKANTU_DEBUG_IN();
 //   if (spatial_dimension == _all_dimensions)
 //     spatial_dimension = mesh.getSpatialDimension();
 //   UInt nb_nodes = mesh.getNbNodes();
 
 //   const Mesh::ConnectivityTypeList & type_list =
 //   mesh.getConnectivityTypeList(); Mesh::ConnectivityTypeList::const_iterator
 //   it;
 
 //   UInt nb_types = type_list.size();
 //   UInt nb_good_types = 0;
 
 //   Vector<UInt> nb_nodes_per_element(nb_types);
 //   UInt ** conn_val = new UInt *[nb_types];
 //   Vector<UInt> nb_element(nb_types);
 
 //   for (it = type_list.begin(); it != type_list.end(); ++it) {
 //     ElementType type = *it;
 //     if (Mesh::getSpatialDimension(type) != spatial_dimension)
 //       continue;
 
 //     nb_nodes_per_element[nb_good_types] = Mesh::getNbNodesPerElement(type);
 //     conn_val[nb_good_types] = mesh.getConnectivity(type,
 //     _not_ghost).storage(); nb_element[nb_good_types] =
 //         mesh.getConnectivity(type, _not_ghost).size();
 //     nb_good_types++;
 //   }
 
 //   AKANTU_DEBUG_ASSERT(
 //       nb_good_types != 0,
 //       "Some elements must be found in right dimension to compute facets!");
 
 //   /// 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 t = 0; t < nb_good_types; ++t) {
 //     for (UInt el = 0; el < nb_element[t]; ++el) {
 //       UInt el_offset = el * nb_nodes_per_element[t];
 //       for (UInt n = 0; n < nb_nodes_per_element[t]; ++n) {
 //         ++node_to_elem.rowOffset(conn_val[t][el_offset + n]);
 //       }
 //     }
 //   }
 
 //   node_to_elem.countToCSR();
 //   node_to_elem.resizeCols();
 //   node_to_elem.beginInsertions();
 
 //   /// rearrange element to get the node-element list
 //   for (UInt t = 0, linearized_el = 0; t < nb_good_types; ++t)
 //     for (UInt el = 0; el < nb_element[t]; ++el, ++linearized_el) {
 //       UInt el_offset = el * nb_nodes_per_element[t];
 //       for (UInt n = 0; n < nb_nodes_per_element[t]; ++n)
 //         node_to_elem.insertInRow(conn_val[t][el_offset + n], linearized_el);
 //     }
 
 //   node_to_elem.endInsertions();
 //   delete[] conn_val;
 //   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 Array<Real>::const_vector_iterator 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);
 
       Vector<ElementType> facet_types = mesh.getAllFacetTypes(type);
 
       for (auto && ft : arange(facet_types.size())) {
         ElementType 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);
         const Matrix<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;
     std::map<UInt, UInt>::iterator 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) {
     GhostType 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));
 
   std::map<UInt, UInt>::iterator it = renumbering_map.begin();
   std::map<UInt, UInt>::iterator 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 = NULL;
+      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 = NULL;
+      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) {
     GhostType 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 = NULL;
-      Array<UInt> * sf_to_double = NULL;
-      Array<std::vector<Element>> * sf_to_subfacet_double = NULL;
-      Array<std::vector<Element>> * f_to_subfacet_double = NULL;
-      Array<std::vector<Element>> * el_to_subfacet_double = NULL;
+      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 = NULL;
+      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 = NULL;
+      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 = NULL;
-  Array<std::vector<Element>> * f_to_subfacet_double = NULL;
+  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 = NULL;
+  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 = NULL;
+  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 = NULL;
+  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 = NULL;
+      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,
       _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);
 
     UInt * conn_tmp_pointer = new UInt[nb_nodes_per_facet];
     Vector<UInt> conn_tmp(conn_tmp_pointer, nb_nodes_per_facet);
 
     Element el_tmp;
     Element * 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 = NULL;
-  const Array<UInt> * sf_connectivity = NULL;
-  const Array<Element> * facet_to_element = NULL;
-  const Array<Element> * subfacet_to_facet = NULL;
+  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 = NULL;
+  const Array<std::vector<Element>> * element_to_facet = nullptr;
 
-  const Element * opposing_el = NULL;
+  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 = NULL;
+  Array<UInt> * conn_elem = nullptr;
 #if defined(AKANTU_COHESIVE_ELEMENT)
-  const Array<Element> * cohesive_facets = NULL;
+  const Array<Element> * cohesive_facets = nullptr;
 #endif
   UInt nb_nodes_per_element = 0;
-  UInt * n_update = NULL;
+  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 != NULL,
+          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 b7ed40928..4d9ff8267 100644
--- a/src/mesh_utils/mesh_utils.hh
+++ b/src/mesh_utils/mesh_utils.hh
@@ -1,244 +1,244 @@
 /**
  * @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
  *
  * @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)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
  * terms  of the  GNU Lesser  General Public  License as  published by  the Free
  * Software Foundation, either version 3 of the License, or (at your option) any
  * later version.
  *
  * Akantu is  distributed in the  hope that it  will be useful, but  WITHOUT ANY
  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  * A  PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 #include "aka_common.hh"
 #include "mesh.hh"
 #include "aka_csr.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<Surface, Surface> & 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 = NULL);
+  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/model/boundary_condition.hh b/src/model/boundary_condition.hh
index ed18419b2..65a09e0a1 100644
--- a/src/model/boundary_condition.hh
+++ b/src/model/boundary_condition.hh
@@ -1,106 +1,108 @@
 /**
  * @file   boundary_condition.hh
  *
  * @author Dana Christen <dana.christen@gmail.com>
  *
  * @date creation: Fri Jun 18 2010
  * @date last modification: Fri Dec 18 2015
  *
  * @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)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
  * terms  of the  GNU Lesser  General Public  License as  published by  the Free
  * Software Foundation, either version 3 of the License, or (at your option) any
  * later version.
  *
  * Akantu is  distributed in the  hope that it  will be useful, but  WITHOUT ANY
  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  * A  PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 
 #ifndef __AKANTU_BOUNDARY_CONDITION_HH__
 #define __AKANTU_BOUNDARY_CONDITION_HH__
 
 #include "aka_common.hh"
 #include "boundary_condition_functor.hh"
 #include "mesh.hh"
 #include "fe_engine.hh"
 /* -------------------------------------------------------------------------- */
 
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 
 template <class ModelType>
 class BoundaryCondition {
 
   /* ------------------------------------------------------------------------ */
   /* Typedefs                                                                 */
   /* ------------------------------------------------------------------------ */
 private:
 
   /* ------------------------------------------------------------------------ */
   /* Constructors / Destructors / Initializers                                */
   /* ------------------------------------------------------------------------ */
 public:
-  BoundaryCondition() : model(NULL), primal(NULL), dual(NULL), primal_increment(NULL) {}
+  BoundaryCondition()
+      : model(nullptr), primal(nullptr), dual(nullptr),
+        primal_increment(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;
   Array<Real> * dual;
   Array<Real> * primal_increment;
 };
 
 } // 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 cbc7358d8..776fa1514 100644
--- a/src/model/boundary_condition_functor.hh
+++ b/src/model/boundary_condition_functor.hh
@@ -1,197 +1,197 @@
 /**
  * @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
  *
  * @brief  Definitions of the functors to apply boundary conditions
  *
  * @section LICENSE
  *
  * Copyright  (©)  2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
  * terms  of the  GNU Lesser  General Public  License as  published by  the Free
  * Software Foundation, either version 3 of the License, or (at your option) any
  * later version.
  *
  * Akantu is  distributed in the  hope that it  will be useful, but  WITHOUT ANY
  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  * A  PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 #include "aka_common.hh"
 #include "fe_engine.hh"
 #include "integration_point.hh"
 /* -------------------------------------------------------------------------- */
 
 #ifndef __AKANTU_BOUNDARY_CONDITION_FUNCTOR_HH__
 #define __AKANTU_BOUNDARY_CONDITION_FUNCTOR_HH__
 
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 namespace BC {
 typedef ::akantu::SpacialDirection Axis;
 
 struct Functor {
   enum Type { _dirichlet, _neumann };
 };
 
 /* ------------------------------------------------------------------------ */
 /* Dirichlet                                                                */
 /* ------------------------------------------------------------------------ */
 namespace Dirichlet {
   /* ---------------------------------------------------------------------- */
   class DirichletFunctor : public Functor {
   protected:
     DirichletFunctor() : axis(_x) {}
     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_DEBUG_TO_IMPLEMENT();
     }
 
   public:
     static const Type type = _dirichlet;
 
   protected:
     Axis axis;
   };
 
   /* ---------------------------------------------------------------------- */
   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;
   };
 } // end namespace Dirichlet
 
 /* ------------------------------------------------------------------------ */
 /* Neumann                                                                  */
 /* ------------------------------------------------------------------------ */
 namespace Neumann {
   /* ---------------------------------------------------------------------- */
   class NeumannFunctor : public Functor {
 
   protected:
     NeumannFunctor() {}
 
   public:
     virtual void operator()(const IntegrationPoint & quad_point,
                             Vector<Real> & dual, const Vector<Real> & coord,
                             const Vector<Real> & normals) const = 0;
 
     virtual ~NeumannFunctor() {}
 
   public:
     static const Type type = _neumann;
   };
 
   /* ---------------------------------------------------------------------- */
   class FromHigherDim : public NeumannFunctor {
   public:
     explicit FromHigherDim(const Matrix<Real> & mat) : bc_data(mat) {}
-    virtual ~FromHigherDim() {}
+    ~FromHigherDim() override {}
 
   public:
     inline void operator()(const IntegrationPoint & quad_point,
                            Vector<Real> & dual, const Vector<Real> & coord,
-                           const Vector<Real> & normals) const;
+                           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) {}
-    virtual ~FromSameDim() {}
+    ~FromSameDim() override {}
 
   public:
     inline void operator()(const IntegrationPoint & quad_point,
                            Vector<Real> & dual, const Vector<Real> & coord,
-                           const Vector<Real> & normals) const;
+                           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;
+                           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/common/neighborhood_base.hh b/src/model/common/neighborhood_base.hh
index 73e5fcb22..b6f365edc 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
  *
  * @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)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
  * terms  of the  GNU Lesser  General Public  License as  published by  the Free
  * Software Foundation, either version 3 of the License, or (at your option) any
  * later version.
  *
  * Akantu is  distributed in the  hope that it  will be useful, but  WITHOUT ANY
  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  * A  PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 #ifndef __AKANTU_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);
-  virtual ~NeighborhoodBase();
+  ~NeighborhoodBase() override;
 
   typedef std::vector<std::pair<IntegrationPoint, IntegrationPoint>> PairList;
 
   /* ------------------------------------------------------------------------ */
   /* 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/neighborhoods_criterion_evaluation/neighborhood_max_criterion.hh b/src/model/common/neighborhoods_criterion_evaluation/neighborhood_max_criterion.hh
index 3ea9e3e94..67b7f51c9 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
  *
  * @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)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
  * terms  of the  GNU Lesser  General Public  License as  published by  the Free
  * Software Foundation, either version 3 of the License, or (at your option) any
  * later version.
  *
  * Akantu is  distributed in the  hope that it  will be useful, but  WITHOUT ANY
  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  * A  PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 #ifndef __AKANTU_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);
-  virtual ~NeighborhoodMaxCriterion();
+  ~NeighborhoodMaxCriterion() override;
 
   /* ------------------------------------------------------------------------ */
   /* Methods                                                                  */
   /* ------------------------------------------------------------------------ */
 
 public:
   /// initialize the neighborhood
-  virtual void initNeighborhood();
+  void initNeighborhood() override;
 
   /// create grid synchronizer and exchange ghost cells
-  virtual void createGridSynchronizer();
+  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/non_local_toolbox/base_weight_function.hh b/src/model/common/non_local_toolbox/base_weight_function.hh
index 47252eec9..59bc32172 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
  *
  * @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)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
  * terms  of the  GNU Lesser  General Public  License as  published by  the Free
  * Software Foundation, either version 3 of the License, or (at your option) any
  * later version.
  *
  * Akantu is  distributed in the  hope that it  will be useful, but  WITHOUT ANY
  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  * A  PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 #include "data_accessor.hh"
 #include "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(_st_weight_function, "weight_function:" + type),
         manager(manager), type(type),
         spatial_dimension(manager.getModel().getMesh().getSpatialDimension()) {
     this->registerParam("update_rate", update_rate, 1U, _pat_parsmod,
                         "Update frequency");
   }
 
-  virtual ~BaseWeightFunction() {}
+  ~BaseWeightFunction() override {}
 
   /* ------------------------------------------------------------------------ */
   /* 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/non_local_manager.hh b/src/model/common/non_local_toolbox/non_local_manager.hh
index 458182e59..f249eac9c 100644
--- a/src/model/common/non_local_toolbox/non_local_manager.hh
+++ b/src/model/common/non_local_toolbox/non_local_manager.hh
@@ -1,288 +1,288 @@
 /**
  * @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
  *
  * @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)
  *
  * Akantu is free  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 "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);
-  virtual ~NonLocalManager();
+  ~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_neighborhood.hh b/src/model/common/non_local_toolbox/non_local_neighborhood.hh
index e8f134948..b92eb3e3c 100644
--- a/src/model/common/non_local_toolbox/non_local_neighborhood.hh
+++ b/src/model/common/non_local_toolbox/non_local_neighborhood.hh
@@ -1,135 +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
  *
  * @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)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
  * terms  of the  GNU Lesser  General Public  License as  published by  the Free
  * Software Foundation, either version 3 of the License, or (at your option) any
  * later version.
  *
  * Akantu is  distributed in the  hope that it  will be useful, but  WITHOUT ANY
  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  * A  PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 #ifndef __AKANTU_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);
-  virtual ~NonLocalNeighborhood();
+  ~NonLocalNeighborhood() override;
 
   /* ------------------------------------------------------------------------ */
   /* Methods                                                                  */
   /* ------------------------------------------------------------------------ */
 public:
   /// compute the weights for non-local averaging
-  void computeWeights();
+  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();
+  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.hh b/src/model/common/non_local_toolbox/non_local_neighborhood_base.hh
index 185a3ae6a..547766016 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,130 +1,130 @@
 /**
  * @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
  *
  * @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)
  *
  * Akantu is free  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 "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);
-  virtual ~NonLocalNeighborhoodBase();
+  ~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_DEBUG_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_tmpl.hh b/src/model/common/non_local_toolbox/non_local_neighborhood_tmpl.hh
index 780c3e002..aa4f9a31d 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,280 +1,280 @@
 /**
  * @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
  *
  * @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)
  *
  * Akantu is free  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 "non_local_manager.hh"
 #include "non_local_neighborhood.hh"
 #include "communicator.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(_st_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
     PairList::const_iterator first_pair = pair_list[ghost_type].begin();
     PairList::const_iterator last_pair = pair_list[ghost_type].end();
     Array<Real>::vector_iterator 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
       Array<Real>::const_vector_iterator 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];
       Array<Real>::const_vector_iterator 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, [this, &quadrature_points_volumes](
+    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) {
     GhostType 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]);
     Array<Real>::const_vector_iterator 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 4a33ef9ea..c7db77db8 100644
--- a/src/model/dof_manager.cc
+++ b/src/model/dof_manager.cc
@@ -1,595 +1,595 @@
 /**
  * @file   dof_manager.cc
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date   Wed Aug 12 09:52:30 2015
  *
  * @brief  Implementation of the common parts of the DOFManagers
  *
  * @section LICENSE
  *
  * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free  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 "dof_manager.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 "communicator.hh"
 #include "time_step_solver.hh"
 /* -------------------------------------------------------------------------- */
 #include <memory>
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 DOFManager::DOFManager(const ID & id, const MemoryID & memory_id)
     : Memory(id, memory_id), mesh(nullptr), local_system_size(0),
       pure_local_system_size(0), system_size(0),
       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_DEBUG_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 = NULL;
+  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 != NULL) {
+    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 != NULL)
+    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();
 }
 
 /* -------------------------------------------------------------------------- */
 DOFManager::DOFData::DOFData(const ID & dof_id)
-    : support_type(_dst_generic), group_support("__mesh__"), dof(NULL),
-      blocked_dofs(NULL), increment(NULL), previous(NULL),
+    : 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() {}
 
 /* -------------------------------------------------------------------------- */
 DOFManager::DOFData & DOFManager::getNewDOFData(const ID & dof_id) {
   DOFStorage::iterator 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 = NULL;
+    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 != NULL) {
+  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 != NULL) {
+  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, NULL);
+    derivatives.resize(order, nullptr);
   } else {
-    if (derivatives[order - 1] != NULL) {
+    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 != NULL) {
+  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() {
   DOFStorage::iterator it = this->dofs.begin();
   DOFStorage::iterator 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;
   SparseMatricesMap::const_iterator 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;
   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);
 }
 
 /* -------------------------------------------------------------------------- */
 bool DOFManager::hasLumpedMatrix(const ID & id) const {
   ID mtx_id = this->id + ":lumped_mtx:" + id;
   LumpedMatricesMap::const_iterator 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;
   NonLinearSolversMap::const_iterator 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;
   TimeStepSolversMap::const_iterator 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 23b76fc4c..fd22976d7 100644
--- a/src/model/dof_manager.hh
+++ b/src/model/dof_manager.hh
@@ -1,465 +1,463 @@
 /**
  * @file   dof_manager.hh
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date   Wed Jul 22 11:43:43 2015
  *
  * @brief  Class handling the different types of dofs
  *
  * @section LICENSE
  *
  * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
  * terms  of the  GNU Lesser  General Public  License as  published by  the Free
  * Software Foundation, either version 3 of the License, or (at your option) any
  * later version.
  *
  * Akantu is  distributed in the  hope that it  will be useful, but  WITHOUT ANY
  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  * A  PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 #include "aka_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);
-  virtual ~DOFManager();
+  ~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 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 &);
 
   /* ------------------------------------------------------------------------ */
   /* 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
-  virtual void onNodesAdded(const Array<UInt> & nodes_list,
-                            const NewNodesEvent & event);
+  void onNodesAdded(const Array<UInt> & nodes_list,
+                    const NewNodesEvent & event) override;
   /// function to implement to react on  akantu::RemovedNodesEvent
-  virtual void onNodesRemoved(const Array<UInt> & nodes_list,
-                              const Array<UInt> & new_numbering,
-                              const RemovedNodesEvent & event);
+  void onNodesRemoved(const Array<UInt> & nodes_list,
+                      const Array<UInt> & new_numbering,
+                      const RemovedNodesEvent & event) override;
   /// function to implement to react on  akantu::NewElementsEvent
-  virtual void onElementsAdded(const Array<Element> & elements_list,
-                               const NewElementsEvent & event);
+  void onElementsAdded(const Array<Element> & elements_list,
+                       const NewElementsEvent & event) override;
   /// function to implement to react on  akantu::RemovedElementsEvent
-  virtual void
-  onElementsRemoved(const Array<Element> & elements_list,
-                    const ElementTypeMapArray<UInt> & new_numbering,
-                    const RemovedElementsEvent & event);
+  void onElementsRemoved(const Array<Element> & elements_list,
+                         const ElementTypeMapArray<UInt> & new_numbering,
+                         const RemovedElementsEvent & event) override;
   /// 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);
+  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;
 
   /// Total number of degrees of freedom (size with the ghosts)
   UInt local_system_size;
 
   /// Number of purely local dofs (size without the ghosts)
   UInt pure_local_system_size;
 
   /// Total number of degrees of freedom
   UInt system_size;
 
   /// Communicator used for this manager, should be the same as in the mesh if a
   /// mesh is registered
   const Communicator & communicator;
 };
 
 } // 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 6944e7da6..8c7d95689 100644
--- a/src/model/dof_manager_default.cc
+++ b/src/model/dof_manager_default.cc
@@ -1,913 +1,912 @@
 /**
  * @file   dof_manager_default.cc
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date   Tue Aug 11 16:21:01 2015
  *
  * @brief  Implementation of the default DOFManager
  *
  * @section LICENSE
  *
  * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free  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 "dof_manager_default.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 "communicator.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")),
       jacobian_release(0),
       global_equation_number(0, 1, "global_equation_number"),
       first_global_dof_id(0), 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, communicator);
 }
 
 /* -------------------------------------------------------------------------- */
 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:
   typedef
       typename std::unordered_map<UInt, std::vector<UInt>>::size_type 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 {
     return dofs_per_node.find(node)->second[nth_dof];
   }
 
-  virtual UInt getNbData(const Array<UInt> & nodes,
-                         const SynchronizationTag & tag) const {
+  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;
   }
 
-  virtual void packData(CommunicationBuffer & buffer, const Array<UInt> & nodes,
-                        const SynchronizationTag & tag) const {
+  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;
       }
     }
   }
 
-  virtual void unpackData(CommunicationBuffer & buffer,
-                          const Array<UInt> & nodes,
-                          const SynchronizationTag & tag) {
+  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() {
   DOFStorage::iterator it = this->dofs.begin();
   DOFStorage::iterator 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);
 
   Array<Real>::const_scalar_iterator A_it = A.begin();
   Array<Real>::const_scalar_iterator A_end = A.end();
   Array<Real>::const_scalar_iterator x_it = data_cache.begin();
   Array<Real>::scalar_iterator 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;
   if (ghost_type == _not_ghost) {
     nb_element = this->mesh->getNbElement(type);
   } else {
     AKANTU_DEBUG_TO_IMPLEMENT();
   }
 
   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 (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,
                                        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;
     }
   }
 }
 
 } // namespace akantu
 
 //  LocalWords:  dof dofs
diff --git a/src/model/dof_manager_default.hh b/src/model/dof_manager_default.hh
index 2cb8a89b8..6a70ac77f 100644
--- a/src/model/dof_manager_default.hh
+++ b/src/model/dof_manager_default.hh
@@ -1,360 +1,360 @@
 /**
  * @file   dof_manager_default.hh
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date   Tue Aug 11 14:06:18 2015
  *
  * @brief  Default implementation of the dof manager
  *
  * @section LICENSE
  *
  * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free  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 "dof_manager.hh"
 /* -------------------------------------------------------------------------- */
 #include <unordered_map>
 #include <functional>
 /* -------------------------------------------------------------------------- */
 
 #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);
-  virtual ~DOFManagerDefault();
+  ~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,
                       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;
 
   /// 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;
 
   /// 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_inline_impl.cc b/src/model/dof_manager_inline_impl.cc
index 0a035af4a..d9dab0b49 100644
--- a/src/model/dof_manager_inline_impl.cc
+++ b/src/model/dof_manager_inline_impl.cc
@@ -1,154 +1,154 @@
 /**
  * @file   dof_manager_inline_impl.cc
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date   Wed Aug 12 11:07:01 2015
  *
  * @brief
  *
  * @section LICENSE
  *
  * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free  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 "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 {
   DOFStorage::const_iterator it = this->dofs.find(dof_id);
   return it != this->dofs.end();
 }
 
 /* -------------------------------------------------------------------------- */
 inline DOFManager::DOFData & DOFManager::getDOFData(const ID & dof_id) {
   DOFStorage::iterator 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 {
   DOFStorage::const_iterator 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 != NULL);
+  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 != NULL);
+  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] == NULL))
+  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] != NULL));
+  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/integration_scheme/integration_scheme.hh b/src/model/integration_scheme/integration_scheme.hh
index a13051f22..024313073 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
  *
  * @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)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
  * terms  of the  GNU Lesser  General Public  License as  published by  the Free
  * Software Foundation, either version 3 of the License, or (at your option) any
  * later version.
  *
  * Akantu is  distributed in the  hope that it  will be useful, but  WITHOUT ANY
  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  * A  PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 #include "aka_common.hh"
 #include "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);
-  virtual ~IntegrationScheme() = default;
+  ~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_2nd_order.hh b/src/model/integration_scheme/integration_scheme_2nd_order.hh
index 220fbe50b..d60ee5777 100644
--- a/src/model/integration_scheme/integration_scheme_2nd_order.hh
+++ b/src/model/integration_scheme/integration_scheme_2nd_order.hh
@@ -1,108 +1,108 @@
 /**
  * @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
  *
  * @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)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
  * terms  of the  GNU Lesser  General Public  License as  published by  the Free
  * Software Foundation, either version 3 of the License, or (at your option) any
  * later version.
  *
  * Akantu is  distributed in the  hope that it  will be useful, but  WITHOUT ANY
  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  * A  PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 #include "aka_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){};
 
-  virtual ~IntegrationScheme2ndOrder() = default;
+  ~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.hh b/src/model/integration_scheme/newmark-beta.hh
index 795e24125..7373c56a9 100644
--- a/src/model/integration_scheme/newmark-beta.hh
+++ b/src/model/integration_scheme/newmark-beta.hh
@@ -1,196 +1,196 @@
 /**
  * @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
  *
  * @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)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
  * terms  of the  GNU Lesser  General Public  License as  published by  the Free
  * Software Foundation, either version 3 of the License, or (at your option) any
  * later version.
  *
  * Akantu is  distributed in the  hope that it  will be useful, but  WITHOUT ANY
  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  * A  PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 
 #ifndef __AKANTU_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() { return {"M", "C"}; }
+  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/model.cc b/src/model/model.cc
index 1a17d7ed9..a9ffb9eb7 100644
--- a/src/model/model.cc
+++ b/src/model/model.cc
@@ -1,350 +1,350 @@
 /**
  * @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
  *
  * @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)
  *
  * Akantu is free  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 "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, UInt dim, const ID & id, const MemoryID & memory_id)
     : Memory(id, memory_id), ModelSolver(mesh, 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::initFull(const ModelOptions & options) {
   AKANTU_DEBUG_IN();
 
   method = options.analysis_method;
   if (!this->hasDefaultSolver()) {
     this->initNewSolver(this->method);
   }
   initModel();
 
   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 (!this->hasSolver(solver_name)) {
     ModelSolverOptions options = this->getDefaultSolverOptions(tss_type);
     this->getNewSolver(solver_name, tss_type, options.non_linear_solver_type);
     this->setIntegrationScheme(solver_name, "displacement",
                                options.integration_scheme_type["displacement"],
                                options.solution_type["displacement"]);
   }
 
   this->method = method;
   this->setDefaultSolver(solver_name);
 }
 
 /* -------------------------------------------------------------------------- */
 void Model::initPBC() {
   std::map<UInt, UInt>::iterator it = pbc_pair.begin();
   std::map<UInt, UInt>::iterator end = pbc_pair.end();
 
   is_pbc_slave_node.resize(mesh.getNbNodes());
 #ifndef AKANTU_NDEBUG
   Array<Real>::const_vector_iterator 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::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() {
   GroupManager::element_group_iterator bit = mesh.element_group_begin();
   GroupManager::element_group_iterator bend = mesh.element_group_end();
   for (; bit != bend; ++bit) {
     bit->second->dump();
   }
 }
 
 /* -------------------------------------------------------------------------- */
 void Model::setGroupDirectory(const std::string & directory) {
   GroupManager::element_group_iterator bit = mesh.element_group_begin();
   GroupManager::element_group_iterator 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, 3);
 }
 
 /* -------------------------------------------------------------------------- */
 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 = NULL;
+  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);
 
   if (!field)
     AKANTU_DEBUG_WARNING("No field could be found based on name: " << field_id);
   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 8036a5bef..35a359e98 100644
--- a/src/model/model.hh
+++ b/src/model/model.hh
@@ -1,349 +1,349 @@
 /**
  * @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
  *
  * @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)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
  * terms  of the  GNU Lesser  General Public  License as  published by  the Free
  * Software Foundation, either version 3 of the License, or (at your option) any
  * later version.
  *
  * Akantu is  distributed in the  hope that it  will be useful, but  WITHOUT ANY
  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  * A  PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 /* -------------------------------------------------------------------------- */
 #include "aka_common.hh"
 #include "aka_memory.hh"
 #include "fe_engine.hh"
 #include "mesh.hh"
 #include "model_solver.hh"
 #include "aka_named_argument.hh"
 /* -------------------------------------------------------------------------- */
 
 #ifndef __AKANTU_MODEL_HH__
 #define __AKANTU_MODEL_HH__
 
 namespace akantu {
 class SynchronizerRegistry;
 class Parser;
 } // namespace akantu
 
 /* -------------------------------------------------------------------------- */
 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;
 };
 
 class DumperIOHelper;
 
 class Model : public Memory, public ModelSolver, public MeshEventHandler {
   /* ------------------------------------------------------------------------ */
   /* Constructors/Destructors                                                 */
   /* ------------------------------------------------------------------------ */
 public:
   Model(Mesh & mesh, UInt spatial_dimension = _all_dimensions,
         const ID & id = "model", const MemoryID & memory_id = 0);
 
-  virtual ~Model();
+  ~Model() override;
 
   typedef std::map<std::string, std::unique_ptr<FEEngine>> FEEngineMap;
 
   /* ------------------------------------------------------------------------ */
   /* Methods                                                                  */
   /* ------------------------------------------------------------------------ */
 public:
   virtual void initFull(const ModelOptions & options);
 
   template <typename P, typename T, typename... pack>
   void initFull(named_argument::param_t<P, T &&> && first, pack &&... _pack) {
     this->initFull(ModelOptions{use_named_args, first, _pack...});
   }
 
   /// 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;
 
   // /// 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
-  virtual void printself(std::ostream &, int = 0) const {};
+  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_DEBUG_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 NULL;
+    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 NULL;
+    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 NULL;
+    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 NULL;
+    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 9d5568242..ef491704e 100644
--- a/src/model/model_inline_impl.cc
+++ b/src/model/model_inline_impl.cc
@@ -1,215 +1,215 @@
 /**
  * @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
  *
  * @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)
  *
  * Akantu is free  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 "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;
 
   FEEngineMap::const_iterator 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) {
 
   FEEngineMap::iterator 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
   FEEngineMap::iterator 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;
 
   FEEngineMap::const_iterator 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 != NULL, "The FEEngine boundary "
-                                              << tmp_name
-                                              << " was not created");
+  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_solver.cc b/src/model/model_solver.cc
index 678ae42cb..1225ea251 100644
--- a/src/model/model_solver.cc
+++ b/src/model/model_solver.cc
@@ -1,359 +1,359 @@
 /**
  * @file   model_solver.cc
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date   Wed Aug 12 13:31:56 2015
  *
  * @brief  Implementation of ModelSolver
  *
  * @section LICENSE
  *
  * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free  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 "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 {
 
 /* -------------------------------------------------------------------------- */
 ModelSolver::ModelSolver(Mesh & mesh, const ID & id, UInt memory_id)
     : Parsable(_st_model_solver, id), SolverCallback(), parent_id(id),
-      parent_memory_id(memory_id), mesh(mesh), dof_manager(NULL),
+      parent_memory_id(memory_id), mesh(mesh), dof_manager(nullptr),
       default_solver_id("") {}
 
 /* -------------------------------------------------------------------------- */
 ModelSolver::~ModelSolver() { delete this->dof_manager; }
 
 /* -------------------------------------------------------------------------- */
 void ModelSolver::initDOFManager() {
   std::pair<Parser::const_section_iterator, Parser::const_section_iterator>
       sub_sect = getStaticParser().getSubSections(_st_model_solver);
 
   // default without external solver activated at compilation same as mumps that
   // is the historical solver but with only the lumped solver
   ID solver_type = "explicit";
 
 #if defined(AKANTU_USE_MUMPS)
   solver_type = "mumps";
 #elif defined(AKANTU_USE_PETSC)
   solver_type = "petsc";
 #endif
 
-  const ParserSection * section = NULL;
+  const ParserSection * section = nullptr;
   Parser::const_section_iterator it;
-  for (it = sub_sect.first; it != sub_sect.second && section == NULL; ++it) {
+  for (it = sub_sect.first; it != sub_sect.second && section == nullptr; ++it) {
     if (it->getName() == this->parent_id) {
       section = &(*it);
       solver_type = section->getOption(solver_type);
     }
   }
 
   if (section) {
     this->initDOFManager(*section, solver_type);
   } else {
     this->initDOFManager(solver_type);
   }
 }
 
 /* -------------------------------------------------------------------------- */
 void ModelSolver::initDOFManager(const ID & solver_type) {
   if (solver_type == "explicit") {
     ID id = this->parent_id + ":dof_manager_default";
     this->dof_manager = new DOFManagerDefault(mesh, id, this->parent_memory_id);
   } else if (solver_type == "petsc") {
 #if defined(AKANTU_USE_PETSC)
     ID id = this->parent_id + ":dof_manager_petsc";
     this->dof_manager = new DOFManagerPETSc(mesh, id, this->parent_memory_id);
 #else
     AKANTU_EXCEPTION(
         "To use PETSc you have to activate it in the compilations options");
 #endif
   } else if (solver_type == "mumps") {
 #if defined(AKANTU_USE_MUMPS)
     ID id = this->parent_id + ":dof_manager_default";
     this->dof_manager = new DOFManagerDefault(mesh, id, this->parent_memory_id);
 #else
     AKANTU_EXCEPTION(
         "To use MUMPS you have to activate it in the compilations options");
 #endif
   } else {
     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);
 }
 
 /* -------------------------------------------------------------------------- */
 template <typename T> static T getOptionToType(const std::string & opt_str) {
   std::stringstream sstr(opt_str);
   T opt;
   sstr >> opt;
 
   return opt;
 }
 
 /* -------------------------------------------------------------------------- */
 void ModelSolver::initDOFManager(const ParserSection & section,
                                  const ID & solver_type) {
   this->initDOFManager(solver_type);
   std::pair<Parser::const_section_iterator, Parser::const_section_iterator>
       sub_sect = section.getSubSections(_st_time_step_solver);
 
   Parser::const_section_iterator it;
   for (it = sub_sect.first; it != sub_sect.second; ++it) {
     ID solver_id = it->getName();
 
     // std::string str = it->getOption();
     TimeStepSolverType tss_type =
         it->getParameter("type", this->getDefaultSolverType());
     ModelSolverOptions tss_options = this->getDefaultSolverOptions(tss_type);
 
     std::pair<Parser::const_section_iterator, Parser::const_section_iterator>
         sub_solvers_sect = it->getSubSections(_st_non_linear_solver);
     Parser::const_section_iterator sub_it;
     UInt nb_non_linear_solver_section =
         it->getNbSubSections(_st_non_linear_solver);
 
     NonLinearSolverType nls_type = tss_options.non_linear_solver_type;
 
     if (nb_non_linear_solver_section == 1) {
       const ParserSection & 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 ParserSection & nls_section = *(sub_solvers_sect.first);
       this->dof_manager->getNonLinearSolver(solver_id).parseSection(
           nls_section);
     }
 
     std::pair<Parser::const_section_iterator, Parser::const_section_iterator>
         sub_integrator_sect = it->getSubSections(_st_integration_scheme);
 
     for (sub_it = sub_integrator_sect.first;
          sub_it != sub_integrator_sect.second; ++sub_it) {
       const ParserSection & is_section = *sub_it;
       const ID & dof_id = is_section.getName();
 
       IntegrationSchemeType it_type = is_section.getParameter(
           "type", tss_options.integration_scheme_type[dof_id]);
 
       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);
     }
 
     std::map<ID, IntegrationSchemeType>::const_iterator it =
         tss_options.integration_scheme_type.begin();
     std::map<ID, IntegrationSchemeType>::const_iterator end =
         tss_options.integration_scheme_type.end();
     for (; it != end; ++it) {
       if (!this->hasIntegrationScheme(solver_id, it->first)) {
         this->setIntegrationScheme(solver_id, it->first, it->second,
                                    tss_options.solution_type[it->first]);
       }
     }
   }
 
   if (section.hasParameter("default_solver")) {
     ID default_solver = section.getParameter("default_solver");
     this->setDefaultSolver(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;
 
   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 e6f0aef79..fe6ae060b 100644
--- a/src/model/model_solver.hh
+++ b/src/model/model_solver.hh
@@ -1,185 +1,185 @@
 /**
  * @file   model_solver.hh
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date   Wed Jul 22 10:53:10 2015
  *
  * @brief  Class regrouping the common solve interface to the different models
  *
  * @section LICENSE
  *
  * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
  * terms  of the  GNU Lesser  General Public  License as  published by  the Free
  * Software Foundation, either version 3 of the License, or (at your option) any
  * later version.
  *
  * Akantu is  distributed in the  hope that it  will be useful, but  WITHOUT ANY
  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  * A  PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 #include "aka_common.hh"
 #include "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 ID & id, UInt memory_id);
-  virtual ~ModelSolver();
+  ~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(__attribute__((unused)) TimeStepSolverType time_step_solver_type,
                           __attribute__((unused)) NonLinearSolverType non_linear_solver_type) {
   }
   /* ------------------------------------------------------------------------ */
   /* 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                                                            */
   /* ------------------------------------------------------------------------ */
 private:
   ID parent_id;
   UInt parent_memory_id;
 
   /// Underlying mesh
   Mesh & mesh;
 
   /// Underlying dof_manager (the brain...)
   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.hh b/src/model/non_linear_solver.hh
index 750e0536d..f476b5f02 100644
--- a/src/model/non_linear_solver.hh
+++ b/src/model/non_linear_solver.hh
@@ -1,96 +1,96 @@
 /**
  * @file   non_linear_solver.hh
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date   Mon Aug 24 23:48:41 2015
  *
  * @brief  Non linear solver interface
  *
  * @section LICENSE
  *
  * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
  * terms  of the  GNU Lesser  General Public  License as  published by  the Free
  * Software Foundation, either version 3 of the License, or (at your option) any
  * later version.
  *
  * Akantu is  distributed in the  hope that it  will be useful, but  WITHOUT ANY
  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  * A  PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 #include "aka_common.hh"
 #include "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 : 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);
-  virtual ~NonLinearSolver();
+  ~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();
 
   /* ------------------------------------------------------------------------ */
   /* 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_linear.hh b/src/model/non_linear_solver_linear.hh
index c52b5a693..289fff390 100644
--- a/src/model/non_linear_solver_linear.hh
+++ b/src/model/non_linear_solver_linear.hh
@@ -1,78 +1,78 @@
 /**
  * @file   non_linear_solver_linear.hh
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date   Tue Aug 25 00:48:07 2015
  *
  * @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)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free  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 "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);
-  virtual ~NonLinearSolverLinear();
+  ~NonLinearSolverLinear() override;
 
   /* ------------------------------------------------------------------------ */
   /* Methods                                                                  */
   /* ------------------------------------------------------------------------ */
 public:
   /// Function that solve the non linear system described by the dof manager and
   /// the solver callback functions
-  virtual void solve(SolverCallback & solver_callback);
+  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.hh b/src/model/non_linear_solver_lumped.hh
index 834791c3c..9916dcb93 100644
--- a/src/model/non_linear_solver_lumped.hh
+++ b/src/model/non_linear_solver_lumped.hh
@@ -1,82 +1,82 @@
 /**
  * @file   non_linear_solver_lumped.hh
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date   Tue Aug 25 00:48:07 2015
  *
  * @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)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free  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 "non_linear_solver.hh"
 #include "sparse_solver_mumps.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);
-  virtual ~NonLinearSolverLumped();
+  ~NonLinearSolverLumped() override;
 
   /* ------------------------------------------------------------------------ */
   /* Methods                                                                  */
   /* ------------------------------------------------------------------------ */
 public:
   /// Function that solve the non linear system described by the dof manager and
   /// the solver callback functions
-  virtual void solve(SolverCallback & solver_callback);
+  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.hh b/src/model/non_linear_solver_newton_raphson.hh
index 1b07a299d..e1e6539de 100644
--- a/src/model/non_linear_solver_newton_raphson.hh
+++ b/src/model/non_linear_solver_newton_raphson.hh
@@ -1,104 +1,104 @@
 /**
  * @file   non_linear_solver_newton_raphson.hh
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date   Tue Aug 25 00:48:07 2015
  *
  * @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)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free  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 "non_linear_solver.hh"
 #include "sparse_solver_mumps.hh"
 /* -------------------------------------------------------------------------- */
 
 #ifndef __AKANTU_NON_LINEAR_SOLVER_NEWTON_RAPHSON_HH__
 #define __AKANTU_NON_LINEAR_SOLVER_NEWTON_RAPHSON_HH__
 
 namespace akantu {
   class DOFManagerDefault;
 }
 
 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);
-  virtual ~NonLinearSolverNewtonRaphson();
+  ~NonLinearSolverNewtonRaphson() override;
 
   /* ------------------------------------------------------------------------ */
   /* Methods                                                                  */
   /* ------------------------------------------------------------------------ */
 public:
   /// Function that solve the non linear system described by the dof manager and
   /// the solver callback functions
-  virtual void solve(SolverCallback & solver_callback);
+  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
   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;
 
   /// Convergence error at last solve call
   Real error;
 
   /// Did the last call to solve reached convergence
   bool converged;
 
   /// Force a re-computation of the jacobian matrix
   bool force_linear_recompute;
 };
 
 } // 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 66fff0841..dd99cdfa8 100644
--- a/src/model/solid_mechanics/material.cc
+++ b/src/model/solid_mechanics/material.cc
@@ -1,1606 +1,1606 @@
 /**
  * @file   material.cc
  *
  * @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
  *
  * @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)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
  * terms  of the  GNU Lesser  General Public  License as  published by  the Free
  * Software Foundation, either version 3 of the License, or (at your option) any
  * later version.
  *
  * Akantu is  distributed in the  hope that it  will be useful, but  WITHOUT ANY
  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  * A  PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 #include "material.hh"
 #include "solid_mechanics_model.hh"
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 Material::Material(SolidMechanicsModel & model, const ID & id)
     : Memory(id, model.getMemoryID()), Parsable(_st_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(_st_material, id),
       is_init(false), fem(model.getFEEngine()), 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("poila_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 (std::map<ID, InternalField<Real> *>::iterator it =
            internal_vectors_real.begin();
        it != internal_vectors_real.end(); ++it)
     it->second->resize();
 
   for (std::map<ID, InternalField<UInt> *>::iterator it =
            internal_vectors_uint.begin();
        it != internal_vectors_uint.end(); ++it)
     it->second->resize();
 
   for (std::map<ID, InternalField<bool> *>::iterator it =
            internal_vectors_bool.begin();
        it != internal_vectors_bool.end(); ++it)
     it->second->resize();
 
   is_init = true;
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void Material::savePreviousState() {
   AKANTU_DEBUG_IN();
 
   for (std::map<ID, InternalField<Real> *>::iterator 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) {
 
     Array<Real> & internal_force =
         const_cast<Array<Real> &>(model.getInternalForce());
 
     Mesh & mesh = fem.getMesh();
     Mesh::type_iterator it =
         element_filter.firstType(spatial_dimension, ghost_type);
     Mesh::type_iterator last_type =
         element_filter.lastType(spatial_dimension, ghost_type);
     for (; it != last_type; ++it) {
       Array<UInt> & elem_filter = element_filter(*it, ghost_type);
       UInt nb_element = elem_filter.size();
       if (nb_element) {
         const Array<Real> & shapes_derivatives =
             fem.getShapesDerivatives(*it, ghost_type);
 
         UInt size_of_shapes_derivatives = shapes_derivatives.getNbComponent();
         UInt nb_nodes_per_element = Mesh::getNbNodesPerElement(*it);
         UInt nb_quadrature_points = fem.getNbIntegrationPoints(*it, ghost_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");
 
         Array<Real> * shapesd_filtered =
             new Array<Real>(0, size_of_shapes_derivatives, "filtered shapesd");
 
         FEEngine::filterElementalData(mesh, shapes_derivatives,
                                       *shapesd_filtered, *it, ghost_type,
                                       elem_filter);
 
         Array<Real> & stress_vect = this->stress(*it, ghost_type);
 
         Array<Real>::matrix_iterator sigma =
             stress_vect.begin(spatial_dimension, spatial_dimension);
         Array<Real>::matrix_iterator B =
             shapesd_filtered->begin(spatial_dimension, nb_nodes_per_element);
         Array<Real>::matrix_iterator Bt_sigma_it =
             sigma_dphi_dx->begin(spatial_dimension, nb_nodes_per_element);
 
         for (UInt q = 0; q < nb_element * nb_quadrature_points;
              ++q, ++sigma, ++B, ++Bt_sigma_it)
           Bt_sigma_it->mul<false, false>(*sigma, *B);
 
         delete shapesd_filtered;
 
         /**
          * 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, *it, ghost_type, elem_filter);
         delete sigma_dphi_dx;
 
         /// assemble
         model.getDOFManager().assembleElementalArrayLocalArray(
             *int_sigma_dphi_dx, internal_force, *it, 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()) {
 
     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);
 
     Array<Real> * shapesd_filtered = new Array<Real>(
         nb_element, dim * nb_nodes_per_element, "filtered shapesd");
 
     FEEngine::filterElementalData(fem.getMesh(), shapes_derivatives,
                                   *shapesd_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> Bt_D(dim * nb_nodes_per_element, tangent_size);
 
     Array<Real>::matrix_iterator shapes_derivatives_filtered_it =
         shapesd_filtered->begin(dim, nb_nodes_per_element);
 
     Array<Real>::matrix_iterator Bt_D_B_it =
         bt_d_b->begin(dim * nb_nodes_per_element, dim * nb_nodes_per_element);
 
     Array<Real>::matrix_iterator D_it =
         tangent_stiffness_matrix->begin(tangent_size, tangent_size);
 
     Array<Real>::matrix_iterator 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) {
       Matrix<Real> & D = *D_it;
       Matrix<Real> & Bt_D_B = *Bt_D_B_it;
 
       VoigtHelper<dim>::transferBMatrixToSymVoigtBMatrix(
           *shapes_derivatives_filtered_it, B, nb_nodes_per_element);
       Bt_D.mul<true, false>(B, D);
       Bt_D_B.mul<false, false>(Bt_D, B);
     }
 
     delete tangent_stiffness_matrix;
     delete shapesd_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::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);
 
   // gradu_vect.resize(nb_quadrature_points * nb_element);
 
   // fem.gradientOnIntegrationPoints(model.getIncrement(), gradu_vect,
   //        dim, type, ghost_type, &elem_filter);
 
   Array<Real> * shapes_derivatives_filtered = new Array<Real>(
       nb_element * nb_quadrature_points, dim * nb_nodes_per_element,
       "shapes derivatives filtered");
 
   Array<Real>::const_matrix_iterator shapes_derivatives_it =
       shapes_derivatives.begin(spatial_dimension, nb_nodes_per_element);
 
   Array<Real>::matrix_iterator shapes_derivatives_filtered_it =
       shapes_derivatives_filtered->begin(spatial_dimension,
                                          nb_nodes_per_element);
   UInt * elem_filter_val = elem_filter.storage();
   for (UInt e = 0; e < nb_element; ++e, ++elem_filter_val)
     for (UInt q = 0; q < nb_quadrature_points;
          ++q, ++shapes_derivatives_filtered_it)
       *shapes_derivatives_filtered_it =
           shapes_derivatives_it[*elem_filter_val * nb_quadrature_points + q];
 
   /// 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);
 
   shapes_derivatives_filtered_it = shapes_derivatives_filtered->begin(
       spatial_dimension, nb_nodes_per_element);
 
   Array<Real>::matrix_iterator Bt_S_B_it =
       bt_s_b->begin(bt_s_b_size, bt_s_b_size);
   Array<Real>::matrix_iterator Bt_S_B_end =
       bt_s_b->end(bt_s_b_size, bt_s_b_size);
 
   Array<Real>::matrix_iterator 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) {
     Matrix<Real> & Bt_S_B = *Bt_S_B_it;
     Matrix<Real> & 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.mul<true, false>(B, S);
     Bt_S_B.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");
 
   Array<Real>::const_matrix_iterator shapes_derivatives_it =
       shapes_derivatives.begin(spatial_dimension, nb_nodes_per_element);
 
   Array<Real>::matrix_iterator shapes_derivatives_filtered_it =
       shapes_derivatives_filtered->begin(spatial_dimension,
                                          nb_nodes_per_element);
   UInt * elem_filter_val = elem_filter.storage();
   for (UInt e = 0; e < nb_element; ++e, ++elem_filter_val)
     for (UInt q = 0; q < nb_quadrature_points;
          ++q, ++shapes_derivatives_filtered_it)
       *shapes_derivatives_filtered_it =
           shapes_derivatives_it[*elem_filter_val * nb_quadrature_points + q];
 
   /// 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);
 
   shapes_derivatives_filtered_it = shapes_derivatives_filtered->begin(
       spatial_dimension, nb_nodes_per_element);
 
   Array<Real>::matrix_iterator Bt_D_B_it =
       bt_d_b->begin(dim * nb_nodes_per_element, dim * nb_nodes_per_element);
 
   Array<Real>::matrix_iterator grad_u_it = gradu_vect.begin(dim, dim);
 
   Array<Real>::matrix_iterator D_it =
       tangent_stiffness_matrix->begin(tangent_size, tangent_size);
   Array<Real>::matrix_iterator 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) {
     Matrix<Real> & grad_u = *grad_u_it;
     Matrix<Real> & D = *D_it;
     Matrix<Real> & 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.mul<true, false>(B, D);
     Bt_D_B.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");
 
     FEEngine::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;
 
     Array<Real> * bt_s =
         new Array<Real>(nb_element * nb_quadrature_points, bt_s_size, "B^t*S");
 
     Array<Real>::matrix_iterator grad_u_it =
         this->gradu(type, ghost_type).begin(dim, dim);
 
     Array<Real>::matrix_iterator grad_u_end =
         this->gradu(type, ghost_type).end(dim, dim);
 
     Array<Real>::matrix_iterator 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) {
       Matrix<Real> & grad_u = *grad_u_it;
       Matrix<Real> & r_it = *bt_s_it;
       Matrix<Real> & 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.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::computeAllStressesFromTangentModuli(GhostType ghost_type) {
   AKANTU_DEBUG_IN();
 
   UInt spatial_dimension = model.getSpatialDimension();
 
   for (auto type : element_filter.elementTypes(spatial_dimension, ghost_type)) {
     switch (spatial_dimension) {
     case 1: {
       computeAllStressesFromTangentModuli<1>(type, ghost_type);
       break;
     }
     case 2: {
       computeAllStressesFromTangentModuli<2>(type, ghost_type);
       break;
     }
     case 3: {
       computeAllStressesFromTangentModuli<3>(type, ghost_type);
       break;
     }
     }
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <UInt dim>
 void Material::computeAllStressesFromTangentModuli(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();
   if (nb_element) {
     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);
 
     Array<Real> & disp = model.getDisplacement();
 
     fem.gradientOnIntegrationPoints(disp, gradu_vect, dim, type, ghost_type,
                                     elem_filter);
 
     UInt tangent_moduli_size = getTangentStiffnessVoigtSize(dim);
 
     Array<Real> * tangent_moduli_tensors = new Array<Real>(
         nb_element * nb_quadrature_points,
         tangent_moduli_size * tangent_moduli_size, "tangent_moduli_tensors");
 
     tangent_moduli_tensors->clear();
     computeTangentModuli(type, *tangent_moduli_tensors, ghost_type);
 
     Array<Real> * shapesd_filtered = new Array<Real>(
         nb_element, dim * nb_nodes_per_element, "filtered shapesd");
 
     FEEngine::filterElementalData(fem.getMesh(), shapes_derivatives,
                                   *shapesd_filtered, type, ghost_type,
                                   elem_filter);
 
     Array<Real> filtered_u(nb_element,
                            nb_nodes_per_element * spatial_dimension);
 
     FEEngine::extractNodalToElementField(fem.getMesh(), disp, filtered_u, type,
                                          ghost_type, elem_filter);
 
     /// compute @f$\mathbf{D} \mathbf{B} \mathbf{u}@f$
     Array<Real>::matrix_iterator shapes_derivatives_filtered_it =
         shapesd_filtered->begin(dim, nb_nodes_per_element);
 
     Array<Real>::matrix_iterator D_it =
         tangent_moduli_tensors->begin(tangent_moduli_size, tangent_moduli_size);
     Array<Real>::matrix_iterator sigma_it =
         stress(type, ghost_type).begin(spatial_dimension, spatial_dimension);
     Array<Real>::vector_iterator u_it =
         filtered_u.begin(spatial_dimension * nb_nodes_per_element);
 
     Matrix<Real> B(tangent_moduli_size,
                    spatial_dimension * nb_nodes_per_element);
     Vector<Real> Bu(tangent_moduli_size);
     Vector<Real> DBu(tangent_moduli_size);
 
     for (UInt e = 0; e < nb_element; ++e, ++u_it) {
       for (UInt q = 0; q < nb_quadrature_points;
            ++q, ++D_it, ++shapes_derivatives_filtered_it, ++sigma_it) {
         Vector<Real> & u = *u_it;
         Matrix<Real> & sigma = *sigma_it;
         Matrix<Real> & D = *D_it;
 
         VoigtHelper<dim>::transferBMatrixToSymVoigtBMatrix(
             *shapes_derivatives_filtered_it, B, nb_nodes_per_element);
 
         Bu.mul<false>(B, u);
         DBu.mul<false>(D, Bu);
 
         // Voigt notation to full symmetric tensor
         for (UInt i = 0; i < dim; ++i)
           sigma(i, i) = DBu(i);
         if (dim == 2) {
           sigma(0, 1) = sigma(1, 0) = DBu(2);
         } else if (dim == 3) {
           sigma(1, 2) = sigma(2, 1) = DBu(3);
           sigma(0, 2) = sigma(2, 0) = DBu(4);
           sigma(0, 1) = sigma(1, 0) = DBu(5);
         }
       }
     }
   }
   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(std::string type) {
   AKANTU_DEBUG_IN();
   if (type == "potential")
     return getPotentialEnergy();
   AKANTU_DEBUG_OUT();
   return 0.;
 }
 
 /* -------------------------------------------------------------------------- */
 Real Material::getEnergy(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 = NULL;
+    const Array<std::vector<Element>> * element_to_facet = nullptr;
     GhostType current_ghost_type = _casper;
-    Array<Real> * result_vec = NULL;
+    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(__attribute__((unused)) const ID & vect_id,
                    __attribute__((unused)) const ElementType & type,
                    __attribute__((unused)) const GhostType & ghost_type) const {
   AKANTU_DEBUG_TO_IMPLEMENT();
   return NULL;
 }
 
 /* -------------------------------------------------------------------------- */
 template <typename T>
 Array<T> & Material::getArray(__attribute__((unused)) const ID & vect_id,
                               __attribute__((unused)) const ElementType & type,
                               __attribute__((unused))
                               const GhostType & ghost_type) {
   AKANTU_DEBUG_TO_IMPLEMENT();
   return NULL;
 }
 
 /* -------------------------------------------------------------------------- */
 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_DEBUG_TO_IMPLEMENT();
   return NULL;
 }
 
 /* -------------------------------------------------------------------------- */
 template <typename T>
 InternalField<T> & Material::getInternal(__attribute__((unused))
                                          const ID & int_id) {
   AKANTU_DEBUG_TO_IMPLEMENT();
   return NULL;
 }
 
 /* -------------------------------------------------------------------------- */
 template <>
 const InternalField<Real> & Material::getInternal(const ID & int_id) const {
   std::map<ID, InternalField<Real> *>::const_iterator 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) {
   std::map<ID, InternalField<Real> *>::iterator 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 {
   std::map<ID, InternalField<UInt> *>::const_iterator 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) {
   std::map<ID, InternalField<UInt> *>::iterator 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 (std::map<ID, InternalField<Real> *>::iterator it =
            internal_vectors_real.begin();
        it != internal_vectors_real.end(); ++it)
     it->second->removeIntegrationPoints(material_local_new_numbering);
 
   for (std::map<ID, InternalField<UInt> *>::iterator it =
            internal_vectors_uint.begin();
        it != internal_vectors_uint.end(); ++it)
     it->second->removeIntegrationPoints(material_local_new_numbering);
 
   for (std::map<ID, InternalField<bool> *>::iterator 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 (std::map<ID, InternalField<Real> *>::iterator it =
            internal_vectors_real.begin();
        it != internal_vectors_real.end(); ++it)
     it->second->resize();
 
   for (std::map<ID, InternalField<UInt> *>::iterator it =
            internal_vectors_uint.begin();
        it != internal_vectors_uint.end(); ++it)
     it->second->resize();
 
   for (std::map<ID, InternalField<bool> *>::iterator 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());
 
   Array<Element>::const_iterator<Element> el_begin = element_list.begin();
   Array<Element>::const_iterator<Element> el_end = element_list.end();
 
   for (ghost_type_t::iterator g = ghost_type_t::begin();
        g != ghost_type_t::end(); ++g) {
     GhostType gt = *g;
 
     ElementTypeMapArray<UInt>::type_iterator it =
         new_numbering.firstType(_all_dimensions, gt, _ek_not_defined);
     ElementTypeMapArray<UInt>::type_iterator end =
         new_numbering.lastType(_all_dimensions, gt, _ek_not_defined);
     for (; it != end; ++it) {
       ElementType type = *it;
       if (element_filter.exists(type, gt) && element_filter(type, gt).size()) {
         Array<UInt> & elem_filter = element_filter(type, gt);
 
         Array<UInt> & mat_indexes = this->model.getMaterialByElement(*it, gt);
         Array<UInt> & mat_loc_num =
             this->model.getMaterialLocalNumbering(*it, gt);
         UInt 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);
 
         Array<UInt> & mat_renumbering = material_local_new_numbering(type, gt);
         const Array<UInt> & 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 (std::map<ID, InternalField<Real> *>::iterator it =
            internal_vectors_real.begin();
        it != internal_vectors_real.end(); ++it)
     it->second->removeIntegrationPoints(material_local_new_numbering);
 
   for (std::map<ID, InternalField<UInt> *>::iterator it =
            internal_vectors_uint.begin();
        it != internal_vectors_uint.end(); ++it)
     it->second->removeIntegrationPoints(material_local_new_numbering);
 
   for (std::map<ID, InternalField<bool> *>::iterator 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 311e68a66..db578d06c 100644
--- a/src/model/solid_mechanics/material.hh
+++ b/src/model/solid_mechanics/material.hh
@@ -1,683 +1,681 @@
 
 /**
  * @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
  *
  * @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)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
  * terms  of the  GNU Lesser  General Public  License as  published by  the Free
  * Software Foundation, either version 3 of the License, or (at your option) any
  * later version.
  *
  * Akantu is  distributed in the  hope that it  will be useful, but  WITHOUT ANY
  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  * A  PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 #include "aka_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
-  virtual ~Material();
+  ~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_DEBUG_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_DEBUG_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_DEBUG_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_DEBUG_TO_IMPLEMENT();
   }
 
   /// compute the s-wave speed in the material
   virtual Real getShearWaveSpeed(__attribute__((unused))
                                  const Element & element) const {
     AKANTU_DEBUG_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_DEBUG_TO_IMPLEMENT();
   }
 
   template <typename T>
   void unregisterInternal(__attribute__((unused)) InternalField<T> & vect) {
     AKANTU_DEBUG_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
-  virtual void printself(std::ostream & stream, int indent = 0) const;
+  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:
-  virtual inline UInt getNbData(const Array<Element> & elements,
-                                const SynchronizationTag & tag) const;
+  inline UInt getNbData(const Array<Element> & elements,
+                        const SynchronizationTag & tag) const override;
 
-  virtual inline void packData(CommunicationBuffer & buffer,
-                               const Array<Element> & elements,
-                               const SynchronizationTag & tag) const;
+  inline void packData(CommunicationBuffer & buffer,
+                       const Array<Element> & elements,
+                       const SynchronizationTag & tag) const override;
 
-  virtual inline void unpackData(CommunicationBuffer & buffer,
-                                 const Array<Element> & elements,
-                                 const SynchronizationTag & tag);
+  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:
   /* ------------------------------------------------------------------------ */
-  virtual void onNodesAdded(const Array<UInt> &, const NewNodesEvent &){};
-  virtual void onNodesRemoved(const Array<UInt> &, const Array<UInt> &,
-                              const RemovedNodesEvent &){};
+  void onNodesAdded(const Array<UInt> &, const NewNodesEvent &) override{};
+  void onNodesRemoved(const Array<UInt> &, const Array<UInt> &,
+                      const RemovedNodesEvent &) override{};
 
-  virtual void onElementsAdded(const Array<Element> & element_list,
-                               const NewElementsEvent & event);
+  void onElementsAdded(const Array<Element> & element_list,
+                       const NewElementsEvent & event) override;
 
-  virtual void
-  onElementsRemoved(const Array<Element> & element_list,
-                    const ElementTypeMapArray<UInt> & new_numbering,
-                    const RemovedElementsEvent & event);
+  void onElementsRemoved(const Array<Element> & element_list,
+                         const ElementTypeMapArray<UInt> & new_numbering,
+                         const RemovedElementsEvent & event) override;
 
-  virtual void onElementsChanged(const Array<Element> &, const Array<Element> &,
-                                 const ElementTypeMapArray<UInt> &,
-                                 const ChangedElementsEvent &){};
+  void onElementsChanged(const Array<Element> &, const Array<Element> &,
+                         const ElementTypeMapArray<UInt> &,
+                         const ChangedElementsEvent &) override{};
 
   /* ------------------------------------------------------------------------ */
   /* SolidMechanicsModelEventHandler inherited members                        */
   /* ------------------------------------------------------------------------ */
 public:
   virtual void beforeSolveStep();
   virtual void afterSolveStep();
 
-
-  virtual void onDamageIteration();
-  virtual void onDamageUpdate();
-  virtual void onDump();
+  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(std::string energy_id);
   /// return the energy (identified by id) for the provided element
   virtual Real getEnergy(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, 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 =                                      \
       MaterialFactory::getInstance().registerAllocator(                        \
           #id, MATERIAL_DEFAULT_PER_DIM_ALLOCATOR(id, mat_name))
 
 #endif /* __AKANTU_MATERIAL_HH__ */
diff --git a/src/model/solid_mechanics/material_selector.hh b/src/model/solid_mechanics/material_selector.hh
index d49b9e4f8..6759d1967 100644
--- a/src/model/solid_mechanics/material_selector.hh
+++ b/src/model/solid_mechanics/material_selector.hh
@@ -1,142 +1,142 @@
 /**
  * @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
  *
  * @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)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
  * terms  of the  GNU Lesser  General Public  License as  published by  the Free
  * Software Foundation, either version 3 of the License, or (at your option) any
  * later version.
  *
  * Akantu is  distributed in the  hope that it  will be useful, but  WITHOUT ANY
  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  * A  PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 #include "aka_common.hh"
 #include "mesh.hh"
 
 /* -------------------------------------------------------------------------- */
 
 #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:
   MaterialSelector() : fallback_value(0) {}
   virtual ~MaterialSelector() {}
   virtual UInt operator()(__attribute__((unused)) const Element & element) {
     return fallback_value;
   }
 
   void setFallback(UInt f) { fallback_value = f; }
 
 protected:
   UInt fallback_value;
 };
 
 /* -------------------------------------------------------------------------- */
 /**
  * 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) {
+  UInt operator()(const Element & element) override {
     if (not material_index.exists(element.type, element.ghost_type))
       return fallback_value;
 
     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 fallback_value;
   }
 
 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) {
+  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/materials/internal_field.hh b/src/model/solid_mechanics/materials/internal_field.hh
index 25cd18f86..96df05f34 100644
--- a/src/model/solid_mechanics/materials/internal_field.hh
+++ b/src/model/solid_mechanics/materials/internal_field.hh
@@ -1,257 +1,257 @@
 /**
  * @file   internal_field.hh
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Fri Jun 18 2010
  * @date last modification: Tue Dec 08 2015
  *
  * @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)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
  * terms  of the  GNU Lesser  General Public  License as  published by  the Free
  * Software Foundation, either version 3 of the License, or (at your option) any
  * later version.
  *
  * Akantu is  distributed in the  hope that it  will be useful, but  WITHOUT ANY
  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  * A  PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 #include "aka_common.hh"
 #include "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);
-  virtual ~InternalField();
+  ~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
-  virtual void printself(std::ostream & stream, int indent = 0) const;
+  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:
   typedef typename ElementTypeMapArray<T>::type_iterator type_iterator;
   typedef typename ElementTypeMapArray<UInt>::type_iterator filter_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 != NULL,
+    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 != NULL,
+    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 != NULL,
+    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 != NULL,
+    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 != NULL); }
+  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 88d2b2539..85147ea95 100644
--- a/src/model/solid_mechanics/materials/internal_field_tmpl.hh
+++ b/src/model/solid_mechanics/materials/internal_field_tmpl.hh
@@ -1,320 +1,320 @@
 /**
  * @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
  *
  * @brief  Material internal properties
  *
  * @section LICENSE
  *
  * Copyright  (©)  2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
  * terms  of the  GNU Lesser  General Public  License as  published by  the Free
  * Software Foundation, either version 3 of the License, or (at your option) any
  * later version.
  *
  * Akantu is  distributed in the  hope that it  will be useful, but  WITHOUT ANY
  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  * A  PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 #include "material.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(NULL) {}
+      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(NULL) {}
+      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(NULL) {}
+      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(NULL) {
+      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 = NULL;
+      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 != NULL,
+  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 (ghost_type_t::iterator gt = ghost_type_t::begin();
        gt != ghost_type_t::end(); ++gt) {
     ElementTypeMapArray<UInt>::type_iterator it =
         new_numbering.firstType(_all_dimensions, *gt, _ek_not_defined);
     ElementTypeMapArray<UInt>::type_iterator end =
         new_numbering.lastType(_all_dimensions, *gt, _ek_not_defined);
     for (; it != end; ++it) {
       ElementType type = *it;
       if (this->exists(type, *gt)) {
         Array<T> & vect = this->operator()(type, *gt);
         if (!vect.size())
           continue;
         const Array<UInt> & renumbering = new_numbering(type, *gt);
 
         UInt nb_quad_per_elem = fem->getNbIntegrationPoints(type, *gt);
         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) 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_elastic.hh b/src/model/solid_mechanics/materials/material_elastic.hh
index f28f92293..791043bf6 100644
--- a/src/model/solid_mechanics/materials/material_elastic.hh
+++ b/src/model/solid_mechanics/materials/material_elastic.hh
@@ -1,158 +1,158 @@
 /**
  * @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
  *
  * @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)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
  * terms  of the  GNU Lesser  General Public  License as  published by  the Free
  * Software Foundation, either version 3 of the License, or (at your option) any
  * later version.
  *
  * Akantu is  distributed in the  hope that it  will be useful, but  WITHOUT ANY
  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  * A  PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 #include "aka_common.hh"
 #include "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:
   typedef PlaneStressToolbox<spatial_dimension,
                              MaterialThermal<spatial_dimension>>
   Parent;
 
 public:
   MaterialElastic(SolidMechanicsModel & model, const ID & id = "");
   MaterialElastic(SolidMechanicsModel & model, UInt dim, const Mesh & mesh,
                   FEEngine & fe_engine, const ID & id = "");
 
-  virtual ~MaterialElastic() {}
+  ~MaterialElastic() override {}
 
 protected:
   void initialize();
 
   /* ------------------------------------------------------------------------ */
   /* Methods                                                                  */
   /* ------------------------------------------------------------------------ */
 public:
-  virtual void initMaterial();
+  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;
 
-  virtual void
+  void
   computePotentialEnergyByElement(ElementType type, UInt index,
-                                  Vector<Real> & epot_on_quad_points);
+                                  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
-  virtual Real getShearWaveSpeed(const Element & element) const;
+  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
-  virtual void updateInternalParameters();
+  void updateInternalParameters() override;
 
   static inline void computePotentialEnergyOnQuad(const Matrix<Real> & grad_u,
                                                   const Matrix<Real> & sigma,
                                                   Real & epot);
 
-  virtual bool hasStiffnessMatrixChanged() {
+  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_thermal.hh b/src/model/solid_mechanics/materials/material_thermal.hh
index 792d6097a..c9aad9194 100644
--- a/src/model/solid_mechanics/materials/material_thermal.hh
+++ b/src/model/solid_mechanics/materials/material_thermal.hh
@@ -1,106 +1,106 @@
 /**
  * @file   material_thermal.hh
  *
  * @author Lucas Frerot <lucas.frerot@epfl.ch>
  *
  * @date creation: Fri Jun 18 2010
  * @date last modification: Tue Aug 18 2015
  *
  * @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)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
  * terms  of the  GNU Lesser  General Public  License as  published by  the Free
  * Software Foundation, either version 3 of the License, or (at your option) any
  * later version.
  *
  * Akantu is  distributed in the  hope that it  will be useful, but  WITHOUT ANY
  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  * A  PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 #include "aka_common.hh"
 #include "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 = "");
 
-  virtual ~MaterialThermal() {};
+  ~MaterialThermal() override{};
 
 protected:
   void initialize();
 
   /* ------------------------------------------------------------------------ */
   /* Methods                                                                  */
   /* ------------------------------------------------------------------------ */
 public:
-  virtual void initMaterial();
+  void initMaterial() override;
 
   /// constitutive law for all element of a type
-  virtual void computeStress(ElementType el_type, GhostType ghost_type);
+  void computeStress(ElementType el_type, GhostType ghost_type) override;
 
   /* ------------------------------------------------------------------------ */
   /* DataAccessor inherited members                                           */
   /* ------------------------------------------------------------------------ */
 public:
 
   /* ------------------------------------------------------------------------ */
   /* Accessors                                                                */
   /* ------------------------------------------------------------------------ */
 public:
 
 
   /* ------------------------------------------------------------------------ */
   /* 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;
 };
 
 } // akantu
 
 #endif /* __AKANTU_MATERIAL_THERMAL_HH__ */
diff --git a/src/model/solid_mechanics/materials/plane_stress_toolbox.hh b/src/model/solid_mechanics/materials/plane_stress_toolbox.hh
index 4a5e0c45b..3eb0ee11b 100644
--- a/src/model/solid_mechanics/materials/plane_stress_toolbox.hh
+++ b/src/model/solid_mechanics/materials/plane_stress_toolbox.hh
@@ -1,106 +1,106 @@
 /**
  * @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
  *
  * @brief  Tools to implement the plane stress behavior in a material
  *
  * @section LICENSE
  *
  * Copyright  (©)  2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
  * terms  of the  GNU Lesser  General Public  License as  published by  the Free
  * Software Foundation, either version 3 of the License, or (at your option) any
  * later version.
  *
  * Akantu is  distributed in the  hope that it  will be useful, but  WITHOUT ANY
  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  * A  PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 
 #ifndef __AKANTU_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) {}
 
-  virtual ~PlaneStressToolbox() {}
+  ~PlaneStressToolbox() override {}
 
 protected:
   void initialize();
 
 public:
-  virtual void computeAllCauchyStresses(GhostType ghost_type = _not_ghost) {
+  void computeAllCauchyStresses(GhostType ghost_type = _not_ghost) override {
     AKANTU_DEBUG_IN();
 
     ParentMaterial::computeAllCauchyStresses(ghost_type);
 
     AKANTU_DEBUG_OUT();
   }
 
   virtual void computeCauchyStressPlaneStress(__attribute__((unused))
                                               ElementType el_type,
                                               __attribute__((unused))
                                               GhostType ghost_type) {
     AKANTU_DEBUG_IN();
 
     AKANTU_DEBUG_ERROR("The function \"computeCauchyStressPlaneStress\" can "
                        "only be used in 2D Plane stress problems, which means "
                        "that you made a mistake somewhere!! ");
 
     AKANTU_DEBUG_OUT();
   }
 
 protected:
   bool initialize_third_axis_deformation;
 };
 
 #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 ecf88c1f4..e31099310 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
  *
  * @brief  2D specialization of the akantu::PlaneStressToolbox class
  *
  * @section LICENSE
  *
  * Copyright  (©)  2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
  * terms  of the  GNU Lesser  General Public  License as  published by  the Free
  * Software Foundation, either version 3 of the License, or (at your option) any
  * later version.
  *
  * Akantu is  distributed in the  hope that it  will be useful, but  WITHOUT ANY
  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  * A  PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 
 #ifndef __AKANTU_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 = "");
 
-  virtual ~PlaneStressToolbox() {}
+  ~PlaneStressToolbox() override {}
 
   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:
   /* ------------------------------------------------------------------------ */
-  virtual void initMaterial() {
+  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();
     }
   }
 
   /* ------------------------------------------------------------------------ */
-  virtual void computeStress(ElementType el_type, GhostType ghost_type) {
+  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
-  virtual void computeAllCauchyStresses(GhostType ghost_type = _not_ghost) {
+  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 66ee3d1a9..f3e6decda 100644
--- a/src/model/solid_mechanics/materials/random_internal_field.hh
+++ b/src/model/solid_mechanics/materials/random_internal_field.hh
@@ -1,108 +1,108 @@
 /**
  * @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
  *
  * @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)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
  * terms  of the  GNU Lesser  General Public  License as  published by  the Free
  * Software Foundation, either version 3 of the License, or (at your option) any
  * later version.
  *
  * Akantu is  distributed in the  hope that it  will be useful, but  WITHOUT ANY
  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  * A  PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 #include "aka_common.hh"
 #include "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);
 
-  virtual ~RandomInternalField();
+  ~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
-  virtual void initialize(UInt nb_component);
+  void initialize(UInt nb_component) override;
 
   /// set the field to a given value
-  void setDefaultValue(const T & 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
-  virtual void printself(std::ostream & stream, int indent = 0) const;
+  void printself(std::ostream & stream, int indent = 0) const override;
 
 protected:
-  virtual void setArrayValues(T * begin, T * end);
+  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/weight_functions/damaged_weight_function.hh b/src/model/solid_mechanics/materials/weight_functions/damaged_weight_function.hh
index 2ef20c741..7ffbfdbf3 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 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
  *
  * @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)
  *
  * Akantu is free  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 "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(NULL) {
+      : BaseWeightFunction(manager, "damaged"), damage(nullptr) {
     this->init();
   }
 
   /* --------------------------------------------------------------------------
    */
   /* Base Weight Function inherited methods */
   /* --------------------------------------------------------------------------
    */
 
   /// set the pointers of internals to the right flattend version
-  virtual void init();
+  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/remove_damaged_weight_function.hh b/src/model/solid_mechanics/materials/weight_functions/remove_damaged_weight_function.hh
index 54b9c49b7..3a5ca0524 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
  *
  * @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)
  *
  * Akantu is free  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 "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(NULL) {
+      : 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 */
   /* --------------------------------------------------------------------------
    */
 
-  virtual inline void init();
+  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_with_damage_rate_weight_function.hh b/src/model/solid_mechanics/materials/weight_functions/remove_damaged_with_damage_rate_weight_function.hh
index dca670cba..31eb2dbc8 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,82 +1,83 @@
 /**
  * @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
  *
  * @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)
  *
  * Akantu is free  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 "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(NULL) {
+  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);
 
-  virtual inline void init();
+  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/stress_based_weight_function.hh b/src/model/solid_mechanics/materials/weight_functions/stress_based_weight_function.hh
index fd3e0744e..07a742faa 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,104 +1,104 @@
 /**
  * @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
  *
  * @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)
  *
  * Akantu is free  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 "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();
+  void init() override;
 
-  virtual inline void updateInternals();
+  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/solid_mechanics_model.hh b/src/model/solid_mechanics/solid_mechanics_model.hh
index c0f013d23..495e28103 100644
--- a/src/model/solid_mechanics/solid_mechanics_model.hh
+++ b/src/model/solid_mechanics/solid_mechanics_model.hh
@@ -1,581 +1,581 @@
 /**
  * @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
  *
  * @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)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
  * terms  of the  GNU Lesser  General Public  License as  published by  the Free
  * Software Foundation, either version 3 of the License, or (at your option) any
  * later version.
  *
  * Akantu is  distributed in the  hope that it  will be useful, but  WITHOUT ANY
  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  * A  PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 /* -------------------------------------------------------------------------- */
 #include "boundary_condition.hh"
 #include "data_accessor.hh"
 #include "fe_engine.hh"
 #include "model.hh"
 #include "non_local_manager.hh"
 #include "solid_mechanics_model_event_handler.hh"
 /* -------------------------------------------------------------------------- */
 //#include "integrator_gauss.hh"
 //#include "shape_lagrange.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 {
 
 struct SolidMechanicsModelOptions : public ModelOptions {
   explicit SolidMechanicsModelOptions(
       AnalysisMethod analysis_method = _explicit_lumped_mass);
 
   template <typename... pack>
   SolidMechanicsModelOptions(use_named_args_t, pack &&... _pack);
 };
 
 /* -------------------------------------------------------------------------- */
 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);
 
-  virtual ~SolidMechanicsModel();
+  ~SolidMechanicsModel() override;
 
   /* ------------------------------------------------------------------------ */
   /* Methods                                                                  */
   /* ------------------------------------------------------------------------ */
 public:
   template <typename P, typename T, typename... pack>
   void initFull(named_argument::param_t<P, T &&> && first, pack &&... _pack) {
     this->initFull(SolidMechanicsModelOptions{use_named_args, first, _pack...});
   }
 
   /// initialize completely the model
   void initFull(
       const ModelOptions & options = SolidMechanicsModelOptions()) override;
 
   /// initialize the fem object needed for boundary conditions
   void initFEEngineBoundary();
 
 protected:
   /// 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;
 
   /// 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
   void
-  assignMaterialToElements(const ElementTypeMapArray<UInt> * filter = NULL);
+  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(); }
 
   inline void setMaterialSelector(MaterialSelector & selector);
 
   /// 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);
 
   /// get the FEEngine object to integrate or interpolate on the boundary
   FEEngine & getFEEngineBoundary(const ID & name = "") override;
 
   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);
 
   /// Access the non_local_manager interface
   AKANTU_GET_MACRO(NonLocalManager, *non_local_manager, NonLocalManager &);
 
 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;
 
 #ifdef SWIGPYTHON
 public:
 #endif
   /// 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;
 #ifdef SWIGPYTHON
 protected:
 #endif
 
   /// class defining of to choose a material
   MaterialSelector * material_selector;
 
   /// define if it is the default selector or not
   bool is_default_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;
 
   typedef std::map<std::pair<std::string, ElementKind>,
                    ElementTypeMapArray<Real> *>
       flatten_internal_map;
 
   /// 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 {
     typedef FromHigherDim FromStress;
     typedef FromSameDim FromTraction;
   } // 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 80bd758d2..1d001ff32 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,615 +1,615 @@
 /**
  * @file   fragment_manager.cc
  *
  * @author Marco Vocialta <marco.vocialta@epfl.ch>
  *
  * @date creation: Thu Jan 23 2014
  * @date last modification: Mon Dec 14 2015
  *
  * @brief  Group manager to handle fragments
  *
  * @section LICENSE
  *
  * Copyright  (©)  2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free  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 "fragment_manager.hh"
 #include "aka_iterators.hh"
 #include "material_cohesive.hh"
 #include "mesh_iterators.hh"
 #include "solid_mechanics_model_cohesive.hh"
 #include "communicator.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 {
+  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 MaterialCohesive & 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
   Array<Real>::const_vector_iterator 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);
       Array<Real>::const_vector_iterator 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);
   Array<Real>::vector_iterator 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();
   Array<Real>::vector_iterator 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);
       Array<Real>::const_vector_iterator 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/material_selector_cohesive.hh b/src/model/solid_mechanics/solid_mechanics_model_cohesive/material_selector_cohesive.hh
index 84b18a443..269fdd115 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,75 +1,76 @@
 /**
  * @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
  *
  * @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)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
  * terms  of the  GNU Lesser  General Public  License as  published by  the Free
  * Software Foundation, either version 3 of the License, or (at your option) any
  * later version.
  *
  * Akantu is  distributed in the  hope that it  will be useful, but  WITHOUT ANY
  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  * A  PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 /* -------------------------------------------------------------------------- */
 #include "material_selector.hh"
 /* -------------------------------------------------------------------------- */
 
 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 DefaultMaterialSelector {
 public:
   DefaultMaterialCohesiveSelector(const SolidMechanicsModelCohesive & model);
-  virtual UInt operator()(const Element & element);
+  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 MeshDataMaterialSelector<std::string> {
 public:
   MeshDataMaterialCohesiveSelector(const SolidMechanicsModelCohesive & model);
-  virtual UInt operator()(const Element & element);
+  UInt operator()(const Element & element) override;
+
 protected:
   const Mesh &mesh_facets;
   const ElementTypeMapArray<UInt> & material_index;
   bool third_dimension;
 };
 
 #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 241604669..946884013 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,70 +1,71 @@
 /**
  * @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
  *
  * @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)
  *
  * Akantu is free  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 "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);
-  virtual ~CohesiveInternalField();
+  ~CohesiveInternalField() override;
 
   /// initialize the field to a given number of component
-  void initialize(UInt nb_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);
-  virtual ~FacetInternalField();
+  ~FacetInternalField() override;
 
   /// initialize the field to a given number of component
-  void initialize(UInt nb_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/material_cohesive.hh b/src/model/solid_mechanics/solid_mechanics_model_cohesive/materials/material_cohesive.hh
index 52c228a0d..ee1d80f9d 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,261 +1,256 @@
 /**
  * @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
  *
  * @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)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
  * terms  of the  GNU Lesser  General Public  License as  published by  the Free
  * Software Foundation, either version 3 of the License, or (at your option) any
  * later version.
  *
  * Akantu is  distributed in the  hope that it  will be useful, but  WITHOUT ANY
  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  * A  PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 #include "material.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:
   typedef FEEngineTemplate<IntegratorGauss, ShapeLagrange, _ek_cohesive>
       MyFEEngineCohesiveType;
 
 public:
   MaterialCohesive(SolidMechanicsModel & model, const ID & id = "");
-  virtual ~MaterialCohesive();
+  ~MaterialCohesive() override;
 
   /* ------------------------------------------------------------------------ */
   /* Methods                                                                  */
   /* ------------------------------------------------------------------------ */
 public:
   /// initialize the material computed parameter
-  virtual void initMaterial();
+  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);
+  void assembleInternalForces(GhostType ghost_type = _not_ghost) override;
 
   /// compute reversible and total energies by element
   void computeEnergies();
 
   /// check stress for cohesive elements' insertion, by default it
   /// also updates the cohesive elements' data
-  virtual void checkInsertion(__attribute__((unused)) bool check_only = false) {
+  virtual void checkInsertion(bool /*check_only*/ = false) {
     AKANTU_DEBUG_TO_IMPLEMENT();
   }
 
   /// check delta_max for cohesive elements in case of no convergence
   /// in the solveStep (only for extrinsic-implicit)
-  virtual void checkDeltaMax(__attribute__((unused))
-                             GhostType ghost_type = _not_ghost) {
+  virtual void checkDeltaMax(GhostType /*ghost_type*/ = _not_ghost) {
     AKANTU_DEBUG_TO_IMPLEMENT();
   }
 
   /// reset variables when convergence is reached (only for
   /// extrinsic-implicit)
-  virtual void resetVariables(__attribute__((unused))
-                              GhostType ghost_type = _not_ghost) {
+  virtual void resetVariables(GhostType /*ghost_type*/ = _not_ghost) {
     AKANTU_DEBUG_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(__attribute__((unused)) const ElementType type,
-                                 __attribute__((unused))
-                                 Array<Real> & result){};
+  virtual void interpolateStress(const ElementType /*type*/,
+
+                                 Array<Real> & /*result*/){};
 
   /// compute the stresses
-  virtual void computeAllStresses(__attribute__((unused))
-                                  GhostType ghost_type = _not_ghost){};
+  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(__attribute__((unused)) const ElementType & el_type,
-                         __attribute__((unused)) Array<Real> & tangent_matrix,
-                         __attribute__((unused)) const Array<Real> & normal,
-                         __attribute__((unused))
-                         GhostType ghost_type = _not_ghost) {
+  virtual void computeTangentTraction(const ElementType & /*el_type*/,
+                                      Array<Real> & /*tangent_matrix*/,
+                                      const Array<Real> & /*normal*/,
+                                      GhostType /*ghost_type*/ = _not_ghost) {
     AKANTU_DEBUG_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);
+  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);
 
   /* ------------------------------------------------------------------------ */
   /* 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
-  virtual Real getEnergy(std::string type);
+  Real getEnergy(std::string type) override;
 
   /// return the energy (identified by id) for the provided element
-  virtual Real getEnergy(std::string energy_id, ElementType type, UInt index) {
+  Real getEnergy(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;
 
   /// opening in all elements and quadrature points (previous time step)
   CohesiveInternalField<Real> opening_old;
 
   /// traction in all elements and quadrature points
   CohesiveInternalField<Real> tractions;
 
   /// traction in all elements and quadrature points (previous time step)
   CohesiveInternalField<Real> tractions_old;
 
   /// 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/solid_mechanics_model_cohesive_parallel.cc b/src/model/solid_mechanics/solid_mechanics_model_cohesive/solid_mechanics_model_cohesive_parallel.cc
index 551bd967e..7dbc2a198 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,397 +1,397 @@
 /**
  * @file   solid_mechanics_model_cohesive_parallel.cc
  *
  * @author Marco Vocialta <marco.vocialta@epfl.ch>
  *
  *
  * @brief  Functions for parallel cohesive elements
  *
  * @section LICENSE
  *
  * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  */
 /* -------------------------------------------------------------------------- */
 #include "element_synchronizer.hh"
 #include "solid_mechanics_model_cohesive.hh"
 #include "solid_mechanics_model_tmpl.hh"
 #include "communicator.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,
         _ghost_type = _not_ghost);
 
     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];
 
           auto && cohesive_type = FEEngine::getCohesiveElementType(facet.type);
           auto old_nb_cohesive_elements =
               mesh.getNbElement(cohesive_type, facet.ghost_type);
           old_nb_cohesive_elements -=
             mesh.getData<UInt>("facet_to_double", facet.type,
                                facet.ghost_type).size();
 
           if (cohesive_element.kind() == _ek_cohesive and
               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
   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());
   });
 }
 
 /* -------------------------------------------------------------------------- */
 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 = 0;
   Mesh & mesh_facets = inserter->getMeshFacets();
 
-  Array<T> * vect = NULL;
-  Array<std::vector<Element>> * element_to_facet = NULL;
+  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 != 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;
     }
     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;
     }
     default: { SolidMechanicsModel::packData(buffer, elements, tag); }
     }
   } else 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;
     }
     default: { SolidMechanicsModel::unpackData(buffer, elements, tag); }
     }
   } else 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_mass.cc b/src/model/solid_mechanics/solid_mechanics_model_mass.cc
index b44d2e995..9cce541a0 100644
--- a/src/model/solid_mechanics/solid_mechanics_model_mass.cc
+++ b/src/model/solid_mechanics/solid_mechanics_model_mass.cc
@@ -1,159 +1,159 @@
 /**
  * @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
  *
  * @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)
  *
  * Akantu is free  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 "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 == NULL) {
+  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();
 
   MyFEEngineType & 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();
 
   MyFEEngineType & 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/time_step_solver.hh b/src/model/time_step_solver.hh
index c1d44e7d4..fab8342e3 100644
--- a/src/model/time_step_solver.hh
+++ b/src/model/time_step_solver.hh
@@ -1,132 +1,132 @@
 /**
  * @file   time_step_solver.hh
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date   Mon Aug 24 12:42:04 2015
  *
  * @brief  This corresponding to the time step evolution solver
  *
  * @section LICENSE
  *
  * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
  * terms  of the  GNU Lesser  General Public  License as  published by  the Free
  * Software Foundation, either version 3 of the License, or (at your option) any
  * later version.
  *
  * Akantu is  distributed in the  hope that it  will be useful, but  WITHOUT ANY
  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  * A  PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 #include "aka_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);
-  virtual ~TimeStepSolver();
+  ~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 &) override final { return _mt_not_defined; }
+  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) override final;
+  void assembleLumpedMatrix(const ID & matrix_id) final;
   /// implementation of the SolverCallback::assembleResidual()
   void assembleResidual() override;
 
   void beforeSolveStep() override;
   void afterSolveStep() override;
   /* ------------------------------------------------------------------------ */
   /* 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_default.cc b/src/model/time_step_solvers/time_step_solver_default.cc
index dcf576d46..747378f1d 100644
--- a/src/model/time_step_solvers/time_step_solver_default.cc
+++ b/src/model/time_step_solvers/time_step_solver_default.cc
@@ -1,282 +1,282 @@
 /**
  * @file   time_step_solver_default.cc
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date   Wed Sep 16 10:20:55 2015
  *
  * @brief  Default implementation of the time step solver
  *
  * @section LICENSE
  *
  * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free  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 "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_DEBUG_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 = NULL;
+  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();
 }
 
 /* -------------------------------------------------------------------------- */
 
 } // 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 fd7cfc201..e77633ca1 100644
--- a/src/model/time_step_solvers/time_step_solver_default.hh
+++ b/src/model/time_step_solvers/time_step_solver_default.hh
@@ -1,111 +1,111 @@
 /**
  * @file   time_step_solver_default.hh
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date   Mon Aug 24 17:10:29 2015
  *
  * @brief  Default implementation for the time stepper
  *
  * @section LICENSE
  *
  * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free  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 "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);
 
-  virtual ~TimeStepSolverDefault();
+  ~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;
 
   /// implementation of the generic TimeStepSolver::solveStep()
   void solveStep(SolverCallback & solver_callback) override;
 
   /* ------------------------------------------------------------------------ */
   /* Class Members                                                            */
   /* ------------------------------------------------------------------------ */
 private:
   typedef std::map<ID, std::unique_ptr<IntegrationScheme>>
       DOFsIntegrationSchemes;
   typedef std::map<ID, IntegrationScheme::SolutionType>
       DOFsIntegrationSchemesSolutionTypes;
   typedef std::set<ID> DOFsIntegrationSchemesOwner;
 
   /// 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/python/python_functor.hh b/src/python/python_functor.hh
index 970419e0a..7516baeea 100644
--- a/src/python/python_functor.hh
+++ b/src/python/python_functor.hh
@@ -1,127 +1,129 @@
 /**
  * @file   python_functor.hh
  *
  * @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
  *
  * @date creation: Fri Jun 18 2010
  * @date last modification: Sun Nov 15 2015
  *
  * @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)
  *
  * Akantu is free  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 <Python.h>
-/* -------------------------------------------------------------------------- */
 #include "aka_common.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                                                                  */
   /* ------------------------------------------------------------------------ */
 protected:
   /// 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
   inline void packArguments(std::vector<PyObject *> & pArgs) const;
 
   /// 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>
   inline void packArguments(std::vector<PyObject *> & pArgs, T & p,
                             Args &... params) const;
 
   /// convert an akantu object to python
   template <typename T>
   inline PyObject * convertToPython(const T & akantu_obj) const;
 
   /// convert a stl vector to python
   template <typename T>
   inline PyObject * convertToPython(const std::vector<T> & akantu_obj) const;
 
   /// convert a stl vector to python
   template <typename T>
   inline PyObject * convertToPython(const std::vector<Array<T> *> & akantu_obj) const;
 
   /// convert a stl vector to python
   template <typename T1, typename T2>
   inline PyObject * convertToPython(const std::map<T1, T2> & akantu_obj) const;
   
   /// convert an akantu vector to python
   template <typename T>
   inline PyObject * convertToPython(const Vector<T> & akantu_obj) const;
 
   /// convert an akantu vector to python
   template <typename T>
   inline PyObject * convertToPython(const Array<T> & akantu_obj) const;
 
   /// convert an akantu vector to python
   template <typename T>
   inline PyObject * convertToPython(Array<T> * akantu_obj) const;
 
   /// convert a akantu matrix to python
   template <typename T>
   inline PyObject * convertToPython(const Matrix<T> & akantu_obj) const;
 
   /// convert a python object to an akantu object
   template <typename return_type>
   inline return_type convertToAkantu(PyObject * python_obj) const;
 
   /// convert a python object to an akantu object
   template <typename T>
   inline std::vector<T> convertListToAkantu(PyObject * python_obj) const;
 
   /// returns the numpy data type code
   template <typename T> inline int getPythonDataTypeCode() const;
 
   /* ------------------------------------------------------------------------ */
   /* Class Members                                                            */
   /* ------------------------------------------------------------------------ */
 protected:
   PyObject * python_obj;
 };
-/* -------------------------------------------------------------------------- */
+
 } // akantu
-/* -------------------------------------------------------------------------- */
-#define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION
-#include "python_functor_inline_impl.cc"
 
 #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 a652c938c..ad679181d 100644
--- a/src/python/python_functor_inline_impl.cc
+++ b/src/python/python_functor_inline_impl.cc
@@ -1,316 +1,319 @@
 /**
  * @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
  *
  * @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)
  *
  * Akantu is free  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 "integration_point.hh"
 /* -------------------------------------------------------------------------- */
 #define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION
 #include <numpy/arrayobject.h>
 #include <typeinfo>
 /* -------------------------------------------------------------------------- */
 
+#ifndef __AKANTU_PYTHON_FUNCTOR_INLINE_IMPL_CC__
+#define __AKANTU_PYTHON_FUNCTOR_INLINE_IMPL_CC__
+
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 template <typename T> inline int PythonFunctor::getPythonDataTypeCode() const {
   AKANTU_EXCEPTION("undefined type: " << debug::demangle(typeid(T).name()));
 }
 
 /* -------------------------------------------------------------------------- */
 template <> inline int PythonFunctor::getPythonDataTypeCode<bool>() const {
   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>() const {
   return NPY_DOUBLE;
 }
 
 /* -------------------------------------------------------------------------- */
 template <typename T>
 PyObject * PythonFunctor::convertToPython(const T &) const {
   AKANTU_DEBUG_ERROR(
       __func__ << " : not implemented yet !" << std::endl
       << debug::demangle(typeid(T).name()));
 }
 
 /* -------------------------------------------------------------------------- */
 template <>
 inline PyObject *
 PythonFunctor::convertToPython<double>(const double & akantu_object) const {
   return PyFloat_FromDouble(akantu_object);
 }
 
 /* -------------------------------------------------------------------------- */
 template <>
 inline PyObject *
 PythonFunctor::convertToPython<UInt>(const UInt & akantu_object) const {
   return PyInt_FromLong(akantu_object);
 }
 
 /* -------------------------------------------------------------------------- */
 template <>
 inline PyObject *
 PythonFunctor::convertToPython<bool>(const bool & akantu_object) const {
   return PyBool_FromLong(long(akantu_object));
 }
 
 /* -------------------------------------------------------------------------- */
 template <typename T>
 inline PyObject *
 PythonFunctor::convertToPython(const std::vector<T> & array) const {
   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]));
   PyArrayObject * res = (PyArrayObject *)obj;
   return (PyObject *)res;
 }
 /* -------------------------------------------------------------------------- */
 template <typename T>
 inline PyObject *
 PythonFunctor::convertToPython(const std::vector<Array<T> *> & array) const {
 
   PyObject * res = PyDict_New();
 
   for (auto a : array) {
     PyObject * obj = this->convertToPython(*a);
     PyObject * name = this->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) const {
 
   PyObject * res = PyDict_New();
 
   for (auto a : map) {
     PyObject * key = this->convertToPython(a.first);
     PyObject * value = this->convertToPython(a.second);
     PyDict_SetItem(res, key, value);
   }
   return (PyObject *)res;
 }
 
 /* -------------------------------------------------------------------------- */
 template <typename T>
 PyObject * PythonFunctor::convertToPython(const Vector<T> & array) const {
   int data_typecode = getPythonDataTypeCode<T>();
   npy_intp dims[1] = {array.size()};
   PyObject * obj =
       PyArray_SimpleNewFromData(1, dims, data_typecode, array.storage());
   PyArrayObject * res = (PyArrayObject *)obj;
   return (PyObject *)res;
 }
 
 /* -------------------------------------------------------------------------- */
 template <typename T>
 PyObject * PythonFunctor::convertToPython(const Array<T> & array) const {
   int data_typecode = getPythonDataTypeCode<T>();
   npy_intp dims[2] = {array.size(), array.getNbComponent()};
   PyObject * obj =
       PyArray_SimpleNewFromData(2, dims, data_typecode, array.storage());
   PyArrayObject * res = (PyArrayObject *)obj;
   return (PyObject *)res;
 }
 /* -------------------------------------------------------------------------- */
 template <typename T>
 PyObject * PythonFunctor::convertToPython(Array<T> * array) const {
   return this->convertToPython(*array);
 }
 
 /* -------------------------------------------------------------------------- */
 template <typename T>
 PyObject * PythonFunctor::convertToPython(const Matrix<T> & mat) const {
   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());
   PyArrayObject * res = (PyArrayObject *)obj;
   return (PyObject *)res;
 }
 
 /* -------------------------------------------------------------------------- */
 template <>
 inline PyObject *
 PythonFunctor::convertToPython<std::string>(const std::string & str) const {
   return PyString_FromString(str.c_str());
 }
 
 /* -------------------------------------------------------------------------- */
 template <>
 inline PyObject * PythonFunctor::convertToPython<IntegrationPoint>(
     const IntegrationPoint & qp) const {
 
   PyObject * input = PyDict_New();
   PyObject * num_point = this->convertToPython(qp.num_point);
   PyObject * global_num = this->convertToPython(qp.global_num);
   PyObject * material_id = this->convertToPython(qp.material_id);
   PyObject * position = this->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 (!PyInstance_Check(this->python_obj))
     AKANTU_EXCEPTION("Python object is not an instance");
 
   PyObject * pFunctor =
       PyObject_GetAttrString(this->python_obj, functor_name.c_str());
   if (!pFunctor)
     AKANTU_EXCEPTION("Python dictionary has no " << functor_name << " entry");
 
   return pFunctor;
 }
 
 /* -------------------------------------------------------------------------- */
 inline void
 PythonFunctor::packArguments(__attribute__((unused))
                              std::vector<PyObject *> & p_args) const {}
 
 /* -------------------------------------------------------------------------- */
 template <typename T, typename... Args>
 inline void PythonFunctor::packArguments(std::vector<PyObject *> & p_args,
                                          T & p, Args &... params) const {
   p_args.push_back(this->convertToPython(p));
   if (sizeof...(params) != 0)
     this->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 = 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) const {
 
   if (PyList_Check(python_obj)) {
     return this->convertListToAkantu<typename return_type::value_type>(
         python_obj);
   }
   AKANTU_DEBUG_TO_IMPLEMENT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <>
 inline void PythonFunctor::convertToAkantu<void>(PyObject * python_obj) const {
   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) const {
   if (!PyString_Check(python_obj))
     AKANTU_EXCEPTION("cannot convert object to string");
   return PyString_AsString(python_obj);
 }
 
 /* -------------------------------------------------------------------------- */
 template <>
 inline Real PythonFunctor::convertToAkantu<Real>(PyObject * python_obj) const {
   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) const {
   if (!PyInt_Check(python_obj))
     AKANTU_EXCEPTION("cannot convert object to integer");
   return PyInt_AsLong(python_obj);
 }
 
 /* -------------------------------------------------------------------------- */
 template <typename T>
 inline std::vector<T>
 PythonFunctor::convertListToAkantu(PyObject * python_obj) const {
   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(this->convertToAkantu<T>(item));
   }
   return res;
 }
 
 /* -------------------------------------------------------------------------- */
 
 } // akantu
 
 #endif /* __AKANTU_PYTHON_FUNCTOR_INLINE_IMPL_CC__ */
diff --git a/src/solver/sparse_matrix_aij.hh b/src/solver/sparse_matrix_aij.hh
index 3b015e8aa..11d04b448 100644
--- a/src/solver/sparse_matrix_aij.hh
+++ b/src/solver/sparse_matrix_aij.hh
@@ -1,179 +1,179 @@
 /**
  * @file   sparse_matrix_aij.hh
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date   Mon Aug 17 21:22:57 2015
  *
  * @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)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
  * terms  of the  GNU Lesser  General Public  License as  published by  the Free
  * Software Foundation, either version 3 of the License, or (at your option) any
  * later version.
  *
  * Akantu is  distributed in the  hope that it  will be useful, but  WITHOUT ANY
  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  * A  PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 #include "aka_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");
 
-  virtual ~SparseMatrixAIJ();
+  ~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_solver.hh b/src/solver/sparse_solver.hh
index dbdbf4f8f..8ac558ef3 100644
--- a/src/solver/sparse_solver.hh
+++ b/src/solver/sparse_solver.hh
@@ -1,122 +1,122 @@
 /**
  * @file   sparse_solver.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 Jan 19 2016
  *
  * @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)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
  * terms  of the  GNU Lesser  General Public  License as  published by  the Free
  * Software Foundation, either version 3 of the License, or (at your option) any
  * later version.
  *
  * Akantu is  distributed in the  hope that it  will be useful, but  WITHOUT ANY
  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  * A  PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 #include "aka_memory.hh"
 //#include "data_accessor.hh"
 #include "parsable.hh"
 #include "communicator.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);
 
-  virtual ~SparseSolver();
+  ~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:
-  virtual void onCommunicatorFinalize();
+  void onCommunicatorFinalize() override;
 
-// inline virtual UInt getNbDataForDOFs(const Array<UInt> & dofs,
+  // 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
   const Communicator & communicator;
 };
 
 } // akantu
 
 #endif /* __AKANTU_SOLVER_HH__ */
diff --git a/src/solver/sparse_solver_mumps.cc b/src/solver/sparse_solver_mumps.cc
index 4be72ba7a..5f5313299 100644
--- a/src/solver/sparse_solver_mumps.cc
+++ b/src/solver/sparse_solver_mumps.cc
@@ -1,440 +1,441 @@
 /**
  * @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
  *
  * @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)
  *
  * Akantu is free  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/>.
  *
  * @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();
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void SparseSolverMumps::destroyInternalData() {
   if (this->is_initialized) {
     this->mumps_data.job = _smj_destroy; // destroy
     dmumps_c(&this->mumps_data);
     this->is_initialized = false;
   }
 }
 
 /* -------------------------------------------------------------------------- */
 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 = NULL;
       this->mumps_data.jcn = NULL;
     }
     break;
   default:
     AKANTU_DEBUG_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
-    // [[fallthrough]]; un-comment when compiler will get it
+    /* FALLTHRU */
+    /* [[fallthrough]]; un-comment when compiler will get it */
   case _fully_distributed:
 #ifdef AKANTU_USE_MPI
     const MPICommunicatorData & 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_DEBUG_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_DEBUG_ERROR("The matrix is singular");
       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_DEBUG_ERROR("The MUMPS workarray is too small INFO(2)="
                            << info(2) << "No further increase possible");
       }
       break;
     }
     default:
       AKANTU_DEBUG_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 1787f52c3..f200333b5 100644
--- a/src/solver/sparse_solver_mumps.hh
+++ b/src/solver/sparse_solver_mumps.hh
@@ -1,157 +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
  *
  * @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)
  *
  * Akantu is free  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 "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);
 
-  virtual ~SparseSolverMumps();
+  ~SparseSolverMumps() override;
 
   /* ------------------------------------------------------------------------ */
   /* Methods                                                                  */
   /* ------------------------------------------------------------------------ */
 public:
   /// build the profile and do the analysis part
-  virtual void initialize();
+  void initialize() override;
 
   /// analysis (symbolic facto + permutations)
-  virtual void analysis();
+  void analysis() override;
 
   /// factorize the matrix
-  virtual void factorize();
+  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
-  virtual void solve();
+  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
-  virtual void destroyInternalData();
+  void destroyInternalData() override;
 
   /// check if initialized and except if it is not the case
   void checkInitialized();
 
   /* ------------------------------------------------------------------------ */
   /* 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/synchronizer/communication_request.hh b/src/synchronizer/communication_request.hh
index ba9c858cb..f93ba330c 100644
--- a/src/synchronizer/communication_request.hh
+++ b/src/synchronizer/communication_request.hh
@@ -1,111 +1,113 @@
 /**
  * @file   real_static_communicator.hh
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Mon Jun 14 2010
  * @date last modification: Wed Jan 13 2016
  *
  * @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)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
  * terms  of the  GNU Lesser  General Public  License as  published by  the Free
  * Software Foundation, either version 3 of the License, or (at your option) any
  * later version.
  *
  * Akantu is  distributed in the  hope that it  will be useful, but  WITHOUT ANY
  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  * A  PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 #include "aka_common.hh"
 /* -------------------------------------------------------------------------- */
 #include <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/communications_tmpl.hh b/src/synchronizer/communications_tmpl.hh
index 6b07dae12..badefca03 100644
--- a/src/synchronizer/communications_tmpl.hh
+++ b/src/synchronizer/communications_tmpl.hh
@@ -1,560 +1,560 @@
 /**
  * @file   communications_tmpl.hh
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date   Tue Sep  6 17:14:06 2016
  *
  * @brief  Implementation of Communications
  *
  * @section LICENSE
  *
  * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free  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 "communications.hh"
 /* -------------------------------------------------------------------------- */
 
 #ifndef __AKANTU_COMMUNICATIONS_TMPL_HH__
 #define __AKANTU_COMMUNICATIONS_TMPL_HH__
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 template <class Entity> class Communications<Entity>::iterator {
   typedef
       typename std::map<UInt, Communication>::iterator communication_iterator;
 
 public:
-  iterator() : communications(NULL) {}
+  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 {
   typedef std::map<SynchronizationTag, UInt>::const_iterator internal_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) {
   scheme_iterator it = this->schemes[sr].begin();
   scheme_iterator 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>
 Communications<Entity>::Communications(const Communicator & communicator)
     : communicator(communicator) {}
 
 /* ---------------------------------------------------------------------- */
 // template <class Entity>
 // typename Communications<Entity>::iterator
 // Communications<Entity>::begin_send(const SynchronizationTag & tag) {
 //   return this->begin(tag, _send);
 // }
 
 // template <class Entity>
 // typename Communications<Entity>::iterator
 // Communications<Entity>::end_send(const SynchronizationTag & tag) {
 //   return this->end(tag, _send);
 // }
 
 // /* ---------------------------------------------------------------------- */
 // template <class Entity>
 // typename Communications<Entity>::iterator
 // Communications<Entity>::begin_recv(const SynchronizationTag & tag) {
 //   return this->begin(tag, _recv);
 // }
 
 // template <class Entity>
 // typename Communications<Entity>::iterator
 // Communications<Entity>::end_recv(const SynchronizationTag & tag) {
 //   return this->end(tag, _recv);
 // }
 
 /* -------------------------------------------------------------------------- */
 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.hh b/src/synchronizer/communicator.hh
index 4ece11d46..900b6b0dd 100644
--- a/src/synchronizer/communicator.hh
+++ b/src/synchronizer/communicator.hh
@@ -1,456 +1,456 @@
 /**
  * @file   static_communicator.hh
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Fri Jun 18 2010
  * @date last modification: Tue Jan 19 2016
  *
  * @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)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
  * terms  of the  GNU Lesser  General Public  License as  published by  the Free
  * Software Foundation, either version 3 of the License, or (at your option) any
  * later version.
  *
  * Akantu is  distributed in the  hope that it  will be useful, but  WITHOUT ANY
  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  * A  PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 /* -------------------------------------------------------------------------- */
 #include "aka_array.hh"
 #include "aka_common.hh"
 #include "aka_event_handler_manager.hh"
 #include "communication_buffer.hh"
 #include "communication_request.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;
 
 struct FinalizeCommunicatorEvent {
   explicit FinalizeCommunicatorEvent(const Communicator & comm)
       : communicator(comm) {}
   const Communicator & communicator;
 };
 
 class CommunicatorEventHandler {
 public:
   virtual ~CommunicatorEventHandler() {}
   virtual void onCommunicatorFinalize() {}
 
 private:
   inline void sendEvent(const FinalizeCommunicatorEvent &) {
     onCommunicatorFinalize();
   }
 
   template <class EventHandler> friend class EventHandlerManager;
 };
 
 /* -------------------------------------------------------------------------- */
 /* -------------------------------------------------------------------------- */
 
 class Communicator : public EventHandlerManager<CommunicatorEventHandler> {
   struct private_member {};
   /* ------------------------------------------------------------------------ */
   /* Constructors/Destructors                                                 */
   /* ------------------------------------------------------------------------ */
 public:
   Communicator(int & argc, char **& argv, const private_member &);
-  virtual ~Communicator();
+  ~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, 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, 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_mpi_inline_impl.cc b/src/synchronizer/communicator_mpi_inline_impl.cc
index a5e72fe98..9c3cf04ee 100644
--- a/src/synchronizer/communicator_mpi_inline_impl.cc
+++ b/src/synchronizer/communicator_mpi_inline_impl.cc
@@ -1,465 +1,465 @@
 /**
  * @file   static_communicator_mpi.cc
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Sun Sep 26 2010
  * @date last modification: Thu Jan 21 2016
  *
  * @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)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
  * terms  of the  GNU Lesser  General Public  License as  published by  the Free
  * Software Foundation, either version 3 of the License, or (at your option) any
  * later version.
  *
  * Akantu is  distributed in the  hope that it  will be useful, but  WITHOUT ANY
  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  * A  PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 #include "aka_iterators.hh"
 #include "communicator.hh"
 #include "mpi_communicator_data.hh"
 /* -------------------------------------------------------------------------- */
 #include <type_traits>
 #include <unordered_map>
 #include <vector>
 #include <memory>
 /* -------------------------------------------------------------------------- */
 #include <mpi.h>
 /* -------------------------------------------------------------------------- */
 
 #if (defined(__GNUC__) || defined(__GNUG__))
 #define GCC_VERSION                                                            \
   (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__)
 #if 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();
   CommunicationRequestMPI * 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();
   CommunicationRequestMPI * 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;
   CommunicationRequestMPI & 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;
   CommunicationRequestMPI & 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();
   CommunicationRequestMPI * 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 = NULL, *recv_buf = NULL;
+  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 = NULL, *recv_buf = NULL;
+  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.hh b/src/synchronizer/data_accessor.hh
index 6ef63932a..16cfab1e9 100644
--- a/src/synchronizer/data_accessor.hh
+++ b/src/synchronizer/data_accessor.hh
@@ -1,281 +1,279 @@
 /**
  * @file   data_accessor.hh
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Wed Sep 01 2010
  * @date last modification: Tue Dec 08 2015
  *
  * @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)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
  * terms  of the  GNU Lesser  General Public  License as  published by  the Free
  * Software Foundation, either version 3 of the License, or (at your option) any
  * later version.
  *
  * Akantu is  distributed in the  hope that it  will be useful, but  WITHOUT ANY
  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  * A  PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 #include "aka_common.hh"
 #include "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() {}
   virtual ~DataAccessorBase() {}
 };
 
 template <class T> class DataAccessor : public virtual DataAccessorBase {
   /* ------------------------------------------------------------------------ */
   /* Constructors/Destructors                                                 */
   /* ------------------------------------------------------------------------ */
 public:
   DataAccessor() {}
-  virtual ~DataAccessor() {}
+  ~DataAccessor() override {}
 
   /* ------------------------------------------------------------------------ */
   /* 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() {}
-  virtual ~DataAccessor() {}
+  ~DataAccessor() override {}
 
   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() {}
-  virtual ~DataAccessor() {}
+  ~DataAccessor() override {}
 
   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) {}
 
-  virtual ~ReduceUIntDataAccessor() {}
+  ~ReduceUIntDataAccessor() override {}
 
   /* ------------------------------------------------------------------------ */
   /* Methods                                                                  */
   /* ------------------------------------------------------------------------ */
 public:
   /* ------------------------------------------------------------------------ */
-  virtual UInt getNbData(const Array<UInt> & elements,
-                         const SynchronizationTag & tag) const {
+  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);
   }
 
   /* ------------------------------------------------------------------------ */
-  virtual void packData(CommunicationBuffer & buffer,
-                        const Array<UInt> & elements,
-                        const SynchronizationTag & tag) const {
+  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]);
     }
   }
 
   /* ------------------------------------------------------------------------ */
-  virtual void unpackData(CommunicationBuffer & buffer,
-                          const Array<UInt> & elements,
-                          const SynchronizationTag & tag) {
+  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.hh b/src/synchronizer/dof_synchronizer.hh
index 9e1eeb9a7..da02089fe 100644
--- a/src/synchronizer/dof_synchronizer.hh
+++ b/src/synchronizer/dof_synchronizer.hh
@@ -1,113 +1,116 @@
 /**
  * @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
  *
  * @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)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
  * terms  of the  GNU Lesser  General Public  License as  published by  the Free
  * Software Foundation, either version 3 of the License, or (at your option) any
  * later version.
  *
  * Akantu is  distributed in the  hope that it  will be useful, but  WITHOUT ANY
  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  * A  PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 #include "aka_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,
       const Communicator & comm = Communicator::getStaticCommunicator());
-  virtual ~DOFSynchronizer();
+  ~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 override final { AKANTU_DEBUG_TO_IMPLEMENT(); }
+  Int getRank(const UInt & /*node*/) const final {
+    AKANTU_DEBUG_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/element_synchronizer.hh b/src/synchronizer/element_synchronizer.hh
index 55d838646..103ddd79e 100644
--- a/src/synchronizer/element_synchronizer.hh
+++ b/src/synchronizer/element_synchronizer.hh
@@ -1,210 +1,210 @@
 /**
  * @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
  *
  * @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)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
  * terms  of the  GNU Lesser  General Public  License as  published by  the Free
  * Software Foundation, either version 3 of the License, or (at your option) any
  * later version.
  *
  * Akantu is  distributed in the  hope that it  will be useful, but  WITHOUT ANY
  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  * A  PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 
 #ifndef __AKANTU_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);
 
 public:
-  virtual ~ElementSynchronizer();
+  ~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                                                            */
   /* ------------------------------------------------------------------------ */
-  virtual UInt sanityCheckDataSize(const Array<Element> & elements,
-                                   const SynchronizationTag & tag) const;
+  UInt sanityCheckDataSize(const Array<Element> & elements,
+                                   const SynchronizationTag & tag) const override;
   /* ------------------------------------------------------------------------ */
-  virtual void
-  packSanityCheckData(CommunicationDescriptor<Element> & comm_desc) const;
+   void
+  packSanityCheckData(CommunicationDescriptor<Element> & comm_desc) const override;
   /* ------------------------------------------------------------------------ */
-  virtual void
-  unpackSanityCheckData(CommunicationDescriptor<Element> & comm_desc) const;
+   void
+  unpackSanityCheckData(CommunicationDescriptor<Element> & comm_desc) const override;
 
   /* ------------------------------------------------------------------------ */
   /* Accessors                                                                */
   /* ------------------------------------------------------------------------ */
 public:
   AKANTU_GET_MACRO(Mesh, mesh, Mesh &);
 
-  Int getRank(const Element & element) const override final;
+  Int getRank(const Element & element) const final;
   /* ------------------------------------------------------------------------ */
   /* Class Members                                                            */
   /* ------------------------------------------------------------------------ */
 protected:
   /// reference to the underlying mesh
   Mesh & mesh;
 
   friend class FilteredSynchronizer;
   friend class FacetSynchronizer;
 
   ElementTypeMapArray<Int> element_to_prank;
 };
 
 /* -------------------------------------------------------------------------- */
 } // namespace akantu
 
 #endif /* __AKANTU_ELEMENT_SYNCHRONIZER_HH__ */
diff --git a/src/synchronizer/grid_synchronizer.hh b/src/synchronizer/grid_synchronizer.hh
index 379e017d4..1005d0654 100644
--- a/src/synchronizer/grid_synchronizer.hh
+++ b/src/synchronizer/grid_synchronizer.hh
@@ -1,103 +1,103 @@
 /**
  * @file   grid_synchronizer.hh
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Fri Jun 18 2010
  * @date last modification: Tue Dec 08 2015
  *
  * @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)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
  * terms  of the  GNU Lesser  General Public  License as  published by  the Free
  * Software Foundation, either version 3 of the License, or (at your option) any
  * later version.
  *
  * Akantu is  distributed in the  hope that it  will be useful, but  WITHOUT ANY
  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  * A  PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 #include "aka_common.hh"
 #include "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);
 
-  virtual ~GridSynchronizer() = default;
+  ~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/mpi_communicator_data.hh b/src/synchronizer/mpi_communicator_data.hh
index 2a2b2e6bc..2b0222e90 100644
--- a/src/synchronizer/mpi_communicator_data.hh
+++ b/src/synchronizer/mpi_communicator_data.hh
@@ -1,136 +1,136 @@
 /**
  * @file   mpi_type_wrapper.hh
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Mon Jun 14 2010
  * @date last modification: Wed Oct 07 2015
  *
  * @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)
  *
  * Akantu is free  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
 #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() {
     int is_initialized = false;
     MPI_Initialized(&is_initialized);
     if (!is_initialized) {
-      MPI_Init(NULL, NULL); // valid according to the spec
+      MPI_Init(nullptr, nullptr); // valid according to the spec
     }
 
     MPI_Comm_create_errhandler(MPICommunicatorData::errorHandler, &error_handler);
     setMPICommunicator(MPI_COMM_WORLD);
     is_externaly_initialized = is_initialized;
   }
 
-  ~MPICommunicatorData() {
+  ~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};
   bool is_externaly_initialized{false};
 
   /* ------------------------------------------------------------------------ */
   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.hh b/src/synchronizer/node_info_per_processor.hh
index 9a28d965b..e75fcafd7 100644
--- a/src/synchronizer/node_info_per_processor.hh
+++ b/src/synchronizer/node_info_per_processor.hh
@@ -1,110 +1,110 @@
 /**
  * @file   node_info_per_processor.hh
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date   Fri Mar 11 14:45:15 2016
  *
  * @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)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free  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 "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();
-  void synchronizeTypes();
-  void synchronizeGroups();
+  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();
-  void synchronizeTypes();
-  void synchronizeGroups();
+  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.hh b/src/synchronizer/node_synchronizer.hh
index 45d42b786..8bfd76044 100644
--- a/src/synchronizer/node_synchronizer.hh
+++ b/src/synchronizer/node_synchronizer.hh
@@ -1,86 +1,88 @@
 /**
  * @file   node_synchronizer.hh
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date   Fri Sep 23 11:45:24 2016
  *
  * @brief  Synchronizer for nodal information
  *
  * @section LICENSE
  *
  * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free  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 "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);
 
-  virtual ~NodeSynchronizer();
+  ~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 override final { AKANTU_DEBUG_TO_IMPLEMENT(); }
+  Int getRank(const UInt & /*node*/) const final {
+    AKANTU_DEBUG_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/synchronizer.hh b/src/synchronizer/synchronizer.hh
index 1f15397f1..2fad3305a 100644
--- a/src/synchronizer/synchronizer.hh
+++ b/src/synchronizer/synchronizer.hh
@@ -1,130 +1,130 @@
 /**
  * @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
  *
  * @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)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
  * terms  of the  GNU Lesser  General Public  License as  published by  the Free
  * Software Foundation, either version 3 of the License, or (at your option) any
  * later version.
  *
  * Akantu is  distributed in the  hope that it  will be useful, but  WITHOUT ANY
  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  * A  PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 /* -------------------------------------------------------------------------- */
 #include "aka_memory.hh"
 #include "communicator.hh"
 /* -------------------------------------------------------------------------- */
 #include <map>
 /* -------------------------------------------------------------------------- */
 
 #ifndef __AKANTU_SYNCHRONIZER_HH__
 #define __AKANTU_SYNCHRONIZER_HH__
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 /* Base class for synchronizers                                               */
 /* -------------------------------------------------------------------------- */
 class Synchronizer : protected Memory {
   /* ------------------------------------------------------------------------ */
   /* Constructors/Destructors                                                 */
   /* ------------------------------------------------------------------------ */
 public:
   Synchronizer(const ID & id = "synchronizer", MemoryID memory_id = 0,
                const Communicator & comm =
                    Communicator::getStaticCommunicator());
 
-  virtual ~Synchronizer(){};
+  ~Synchronizer() override{};
 
   virtual void printself(__attribute__((unused)) std::ostream & stream,
                          __attribute__((unused)) int indent = 0) const {};
   /* ------------------------------------------------------------------------ */
   /* 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;
 };
 
 /// standard output stream operator
 inline std::ostream & operator<<(std::ostream & stream,
                                  const Synchronizer & _this) {
   _this.printself(stream);
   return stream;
 }
 
 } // akantu
 
 #include "synchronizer_tmpl.hh"
 
 #endif /* __AKANTU_SYNCHRONIZER_HH__ */
diff --git a/src/synchronizer/synchronizer_impl.hh b/src/synchronizer/synchronizer_impl.hh
index a8cfdfea4..1b28e3583 100644
--- a/src/synchronizer/synchronizer_impl.hh
+++ b/src/synchronizer/synchronizer_impl.hh
@@ -1,122 +1,122 @@
 /**
  * @file   synchronizer_impl.hh
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date   Wed Aug 24 13:26:47 2016
  *
  * @brief  Implementation of the generic part of synchronizers
  *
  * @section LICENSE
  *
  * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free  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 "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 ID & id = "synchronizer", MemoryID memory_id = 0,
       const Communicator & comm = Communicator::getStaticCommunicator());
 
-  virtual ~SynchronizerImpl(){};
+  ~SynchronizerImpl() override{};
 
   /* ------------------------------------------------------------------------ */
   /* 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;
 };
 
 } // akantu
 
 #include "synchronizer_impl_tmpl.hh"
 
 
 #endif /* __AKANTU_SYNCHRONIZER_IMPL_HH__ */
diff --git a/src/synchronizer/synchronizer_registry.cc b/src/synchronizer/synchronizer_registry.cc
index 0c8ce1398..38c318c89 100644
--- a/src/synchronizer/synchronizer_registry.cc
+++ b/src/synchronizer/synchronizer_registry.cc
@@ -1,139 +1,139 @@
 /**
  * @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
  *
  * @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)
  *
  * Akantu is free  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 "synchronizer_registry.hh"
 #include "synchronizer.hh"
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 SynchronizerRegistry::SynchronizerRegistry() : data_accessor(nullptr) {
   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 != NULL, "No data accessor set.");
+  AKANTU_DEBUG_ASSERT(data_accessor != nullptr, "No data accessor set.");
 
   std::pair<Tag2Sync::iterator, Tag2Sync::iterator> range =
       synchronizers.equal_range(tag);
 
   for (Tag2Sync::iterator 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 != NULL, "No data accessor set.");
+  AKANTU_DEBUG_ASSERT(data_accessor != nullptr, "No data accessor set.");
 
   std::pair<Tag2Sync::iterator, Tag2Sync::iterator> range =
       synchronizers.equal_range(tag);
 
   for (Tag2Sync::iterator 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 != NULL, "No data accessor set.");
+  AKANTU_DEBUG_ASSERT(data_accessor != nullptr, "No data accessor set.");
 
   std::pair<Tag2Sync::iterator, Tag2Sync::iterator> range =
       synchronizers.equal_range(tag);
 
   for (Tag2Sync::iterator 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();
 }
 
 /* -------------------------------------------------------------------------- */
 void SynchronizerRegistry::printself(std::ostream & stream, int indent) const {
   std::string space;
   for (Int i = 0; i < indent; i++, space += AKANTU_INDENT)
     ;
 
   stream << space << "SynchronizerRegistry [" << std::endl;
   Tag2Sync::const_iterator it;
   for (it = synchronizers.begin(); it != synchronizers.end(); it++) {
     stream << space << " + Synchronizers for tag " << (*it).first << " ["
            << std::endl;
     (*it).second->printself(stream, indent + 1);
     stream << space << " ]" << std::endl;
   }
 
   stream << space << "]" << std::endl;
 }
 
 } // akantu
diff --git a/test/test_mesh_utils/test_segment_nodetype/test_segment_nodetype.cc b/test/test_mesh_utils/test_segment_nodetype/test_segment_nodetype.cc
index bdd4aece5..8c696153e 100644
--- a/test/test_mesh_utils/test_segment_nodetype/test_segment_nodetype.cc
+++ b/test/test_mesh_utils/test_segment_nodetype/test_segment_nodetype.cc
@@ -1,97 +1,97 @@
 /**
  * @file   test_segment_nodetype.cc
  *
  * @author Marco Vocialta <marco.vocialta@epfl.ch>
  *
  * @date creation: Fri Sep 18 2015
  *
  * @brief  Test to verify that the node type is correctly associated to
  * the segments in parallel
  *
  * @section LICENSE
  *
  * Copyright (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne) Laboratory
  * (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
  * terms  of the  GNU Lesser  General Public  License as  published by  the Free
  * Software Foundation, either version 3 of the License, or (at your option) any
  * later version.
  *
  * Akantu is  distributed in the  hope that it  will be useful, but  WITHOUT ANY
  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  * A  PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 #include "element_synchronizer.hh"
 #include "mesh_utils.hh"
 
 /* -------------------------------------------------------------------------- */
 using namespace akantu;
 
 int main(int argc, char * argv[]) {
   initialize(argc, argv);
 
   UInt spatial_dimension = 3;
   Mesh mesh(spatial_dimension);
 
-  StaticCommunicator & comm = StaticCommunicator::getStaticCommunicator();
+  const auto & comm = Communicator::getStaticCommunicator();
   Int psize = comm.getNbProc();
   Int prank = comm.whoAmI();
 
   // partition the mesh
   if (prank == 0) {
     mesh.read("mesh.msh");
   }
 
   mesh.distribute();
 
   // compute the node types for each segment
   Mesh & mesh_facets = mesh.initMeshFacets();
   MeshUtils::buildSegmentToNodeType(mesh, mesh_facets);
 
   // verify that the number of segments per node type makes sense
   std::map<Int, UInt> nb_facets_per_nodetype;
   UInt nb_segments = 0;
 
   for (auto ghost_type : ghost_types) {
     const Array<Int> & segment_to_nodetype =
         mesh_facets.getData<Int>("segment_to_nodetype", _segment_2, ghost_type);
 
     // count the number of segments per node type
     for (auto & stn : segment_to_nodetype) {
       if (nb_facets_per_nodetype.find(stn) == nb_facets_per_nodetype.end())
         nb_facets_per_nodetype[stn] = 1;
       else
         ++nb_facets_per_nodetype[stn];
     }
     nb_segments += segment_to_nodetype.size();
   }
 
   // checking the solution
   if (nb_segments != 24)
     AKANTU_DEBUG_ERROR("The number of segments is wrong");
 
   if (prank == 0) {
     if (nb_facets_per_nodetype[-1] != 3 || nb_facets_per_nodetype[-2] != 9 ||
         nb_facets_per_nodetype[-3] != 12)
       AKANTU_DEBUG_ERROR(
           "The segments of processor 0 have the wrong node type");
 
     if (nb_facets_per_nodetype.size() > 3)
       AKANTU_DEBUG_ERROR("Processor 0 cannot have any slave segment");
   }
 
   if (prank == psize - 1 &&
       nb_facets_per_nodetype.find(-2) != nb_facets_per_nodetype.end())
     AKANTU_DEBUG_ERROR("The last processor must not have any master facets");
 
   finalize();
   return 0;
 }
diff --git a/test/test_model/test_model_solver/test_model_solver_my_model.hh b/test/test_model/test_model_solver/test_model_solver_my_model.hh
index 58fc2a0e9..9490b1a10 100644
--- a/test/test_model/test_model_solver/test_model_solver_my_model.hh
+++ b/test/test_model/test_model_solver/test_model_solver_my_model.hh
@@ -1,468 +1,468 @@
 /**
  * @file   test_dof_manager_default.cc
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date   Wed Feb 24 12:28:44 2016
  *
  * @brief  Test default dof manager
  *
  * @section LICENSE
  *
  * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
  * terms  of the  GNU Lesser  General Public  License as  published by  the Free
  * Software Foundation, either version 3 of the License, or (at your option) any
  * later version.
  *
  * Akantu is  distributed in the  hope that it  will be useful, but  WITHOUT ANY
  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  * A  PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 /* -------------------------------------------------------------------------- */
 #include "aka_iterators.hh"
 #include "data_accessor.hh"
 #include "dof_manager_default.hh"
 #include "element_synchronizer.hh"
 #include "mesh.hh"
 #include "model_solver.hh"
 #include "sparse_matrix.hh"
 #include "communicator.hh"
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 
 #ifndef __AKANTU_TEST_MODEL_SOLVER_MY_MODEL_HH__
 #define __AKANTU_TEST_MODEL_SOLVER_MY_MODEL_HH__
 
 /**
  *   =\o-----o-----o-> F
  *     |           |
  *     |---- L ----|
  */
 class MyModel : public ModelSolver, public DataAccessor<Element> {
 public:
   MyModel(Real F, Mesh & mesh, bool lumped)
       : ModelSolver(mesh, "model_solver", 0), nb_dofs(mesh.getNbNodes()),
         nb_elements(mesh.getNbElement()), E(1.), A(1.), rho(1.), lumped(lumped),
         mesh(mesh), displacement(nb_dofs, 1, "disp"),
         velocity(nb_dofs, 1, "velo"), acceleration(nb_dofs, 1, "accel"),
         blocked(nb_dofs, 1, "blocked"), forces(nb_dofs, 1, "force_ext"),
         internal_forces(nb_dofs, 1, "force_int"),
         stresses(nb_elements, 1, "stress"), strains(nb_elements, 1, "strain"),
         initial_lengths(nb_elements, 1, "L0") {
 
     this->initDOFManager();
     this->getDOFManager().registerDOFs("disp", displacement, _dst_nodal);
     this->getDOFManager().registerDOFsDerivative("disp", 1, velocity);
     this->getDOFManager().registerDOFsDerivative("disp", 2, acceleration);
     this->getDOFManager().registerBlockedDOFs("disp", blocked);
 
     displacement.set(0.);
     velocity.set(0.);
     acceleration.set(0.);
 
     forces.set(0.);
     blocked.set(false);
 
     UInt global_nb_nodes = mesh.getNbGlobalNodes();
     for (auto && n : arange(nb_dofs)) {
       auto global_id = mesh.getNodeGlobalId(n);
       if (global_id == (global_nb_nodes - 1))
         forces(n, _x) = F;
 
       if (global_id == 0)
         blocked(n, _x) = true;
     }
 
     auto cit = this->mesh.getConnectivity(_segment_2).begin(2);
     auto cend = this->mesh.getConnectivity(_segment_2).end(2);
     auto L_it = this->initial_lengths.begin();
 
     for (; cit != cend; ++cit, ++L_it) {
       const Vector<UInt> & conn = *cit;
       UInt n1 = conn(0);
       UInt n2 = conn(1);
       Real p1 = this->mesh.getNodes()(n1, _x);
       Real p2 = this->mesh.getNodes()(n2, _x);
 
       *L_it = std::abs(p2 - p1);
     }
 
     this->registerDataAccessor(*this);
     this->registerSynchronizer(
         const_cast<ElementSynchronizer &>(this->mesh.getElementSynchronizer()),
         _gst_user_1);
   }
 
   void assembleLumpedMass() {
     Array<Real> & M = this->getDOFManager().getLumpedMatrix("M");
     M.clear();
 
     this->assembleLumpedMass(_not_ghost);
     if (this->mesh.getNbElement(_segment_2, _ghost) > 0)
       this->assembleLumpedMass(_ghost);
 
     is_lumped_mass_assembled = true;
   }
 
   void assembleLumpedMass(const GhostType & ghost_type) {
     Array<Real> & M = this->getDOFManager().getLumpedMatrix("M");
 
     Array<Real> m_all_el(this->mesh.getNbElement(_segment_2, ghost_type), 2);
 
     Array<Real>::vector_iterator m_it = m_all_el.begin(2);
 
     auto cit = this->mesh.getConnectivity(_segment_2, ghost_type).begin(2);
     auto cend = this->mesh.getConnectivity(_segment_2, ghost_type).end(2);
 
     for (; cit != cend; ++cit, ++m_it) {
       const Vector<UInt> & conn = *cit;
       UInt n1 = conn(0);
       UInt n2 = conn(1);
 
       Real p1 = this->mesh.getNodes()(n1, _x);
       Real p2 = this->mesh.getNodes()(n2, _x);
 
       Real L = std::abs(p2 - p1);
 
       Real M_n = rho * A * L / 2;
       (*m_it)(0) = (*m_it)(1) = M_n;
     }
 
     this->getDOFManager().assembleElementalArrayLocalArray(
         m_all_el, M, _segment_2, ghost_type);
   }
 
   void assembleMass() {
     SparseMatrix & M = this->getDOFManager().getMatrix("M");
     M.clear();
 
     Array<Real> m_all_el(this->nb_elements, 4);
     Array<Real>::matrix_iterator m_it = m_all_el.begin(2, 2);
 
     auto cit = this->mesh.getConnectivity(_segment_2).begin(2);
     auto cend = this->mesh.getConnectivity(_segment_2).end(2);
 
     Matrix<Real> m(2, 2);
     m(0, 0) = m(1, 1) = 2;
     m(0, 1) = m(1, 0) = 1;
 
     // under integrated
     // m(0, 0) = m(1, 1) = 3./2.;
     // m(0, 1) = m(1, 0) = 3./2.;
 
     // lumping the mass matrix
     // m(0, 0) += m(0, 1);
     // m(1, 1) += m(1, 0);
     // m(0, 1) = m(1, 0) = 0;
 
     for (; cit != cend; ++cit, ++m_it) {
       const Vector<UInt> & conn = *cit;
       UInt n1 = conn(0);
       UInt n2 = conn(1);
 
       Real p1 = this->mesh.getNodes()(n1, _x);
       Real p2 = this->mesh.getNodes()(n2, _x);
 
       Real L = std::abs(p2 - p1);
 
       Matrix<Real> & m_el = *m_it;
       m_el = m;
       m_el *= rho * A * L / 6.;
     }
     this->getDOFManager().assembleElementalMatricesToMatrix(
         "M", "disp", m_all_el, _segment_2);
 
     is_mass_assembled = true;
   }
 
   MatrixType getMatrixType(const ID &) { return _symmetric; }
 
   void assembleMatrix(const ID & matrix_id) {
     if (matrix_id == "K") {
       if (not is_stiffness_assembled)
         this->assembleStiffness();
     } else if (matrix_id == "M") {
       if (not is_mass_assembled)
         this->assembleMass();
     } else if (matrix_id == "C") {
       // pass, no damping matrix
     } else {
       AKANTU_EXCEPTION("This solver does not know what to do with a matrix "
                        << matrix_id);
     }
   }
 
   void assembleLumpedMatrix(const ID & matrix_id) {
     if (matrix_id == "M") {
       if (not is_lumped_mass_assembled)
         this->assembleLumpedMass();
     } else {
       AKANTU_EXCEPTION("This solver does not know what to do with a matrix "
                        << matrix_id);
     }
   }
 
   void assembleStiffness() {
     SparseMatrix & K = this->getDOFManager().getMatrix("K");
     K.clear();
 
     Matrix<Real> k(2, 2);
     k(0, 0) = k(1, 1) = 1;
     k(0, 1) = k(1, 0) = -1;
 
     Array<Real> k_all_el(this->nb_elements, 4);
 
     auto k_it = k_all_el.begin(2, 2);
     auto cit = this->mesh.getConnectivity(_segment_2).begin(2);
     auto cend = this->mesh.getConnectivity(_segment_2).end(2);
 
     for (; cit != cend; ++cit, ++k_it) {
       const auto & conn = *cit;
       UInt n1 = conn(0);
       UInt n2 = conn(1);
 
       Real p1 = this->mesh.getNodes()(n1, _x);
       Real p2 = this->mesh.getNodes()(n2, _x);
 
       Real L = std::abs(p2 - p1);
 
       auto & k_el = *k_it;
       k_el = k;
       k_el *= E * A / L;
     }
 
     this->getDOFManager().assembleElementalMatricesToMatrix(
         "K", "disp", k_all_el, _segment_2);
 
     is_stiffness_assembled = true;
   }
 
   void assembleResidual() {
     this->getDOFManager().assembleToResidual("disp", forces);
     internal_forces.clear();
 
     this->assembleResidual(_not_ghost);
 
     this->synchronize(_gst_user_1);
 
     this->getDOFManager().assembleToResidual("disp", internal_forces, -1.);
 
-    // auto & comm = StaticCommunicator::getStaticCommunicator();
+    // auto & comm = Communicator::getStaticCommunicator();
     // const auto & dof_manager_default =
     //   dynamic_cast<DOFManagerDefault &>(this->getDOFManager());
     // const auto & residual = dof_manager_default.getResidual();
     // int prank = comm.whoAmI();
     // int psize = comm.getNbProc();
 
     // for (int p = 0; p < psize; ++p) {
     //   if (prank == p) {
     //     UInt local_dof = 0;
     //     for (auto res : residual) {
     //       UInt global_dof =
     //       dof_manager_default.localToGlobalEquationNumber(local_dof);
     //       std::cout << local_dof << " [" << global_dof << " - "
     //                 << dof_manager_default.getDOFType(local_dof) << "]: " <<
     //                 res
     //                 << std::endl;
     //       ++local_dof;
     //     }
     //     std::cout << std::flush;
     //   }
     //   comm.barrier();
     // }
 
     // comm.barrier();
     // if(prank == 0) std::cout << "===========================" << std::endl;
   }
 
   void assembleResidual(const GhostType & ghost_type) {
     Array<Real> forces_internal_el(
         this->mesh.getNbElement(_segment_2, ghost_type), 2);
 
     auto cit = this->mesh.getConnectivity(_segment_2, ghost_type).begin(2);
     auto cend = this->mesh.getConnectivity(_segment_2, ghost_type).end(2);
 
     auto f_it = forces_internal_el.begin(2);
 
     auto strain_it = this->strains.begin();
     auto stress_it = this->stresses.begin();
     auto L_it = this->initial_lengths.begin();
 
     for (; cit != cend; ++cit, ++f_it, ++strain_it, ++stress_it, ++L_it) {
       const auto & conn = *cit;
       UInt n1 = conn(0);
       UInt n2 = conn(1);
 
       Real u1 = this->displacement(n1, _x);
       Real u2 = this->displacement(n2, _x);
 
       *strain_it = (u2 - u1) / *L_it;
       *stress_it = E * *strain_it;
       Real f_n = A * *stress_it;
       Vector<Real> & f = *f_it;
 
       f(0) = -f_n;
       f(1) = f_n;
     }
 
     this->getDOFManager().assembleElementalArrayLocalArray(
         forces_internal_el, internal_forces, _segment_2, ghost_type);
   }
 
   Real getPotentialEnergy() {
     Real res = 0;
 
     if (!lumped) {
       res = this->mulVectMatVect(this->displacement,
                                  this->getDOFManager().getMatrix("K"),
                                  this->displacement);
     } else {
       auto strain_it = this->strains.begin();
       auto stress_it = this->stresses.begin();
       auto strain_end = this->strains.end();
       auto L_it = this->initial_lengths.begin();
 
       for (; strain_it != strain_end; ++strain_it, ++stress_it, ++L_it) {
         res += *strain_it * *stress_it * A * *L_it;
       }
 
       mesh.getCommunicator().allReduce(res, SynchronizerOperation::_sum);
     }
 
     return res / 2.;
   }
 
   Real getKineticEnergy() {
     Real res = 0;
     if (!lumped) {
       res = this->mulVectMatVect(
           this->velocity, this->getDOFManager().getMatrix("M"), this->velocity);
     } else {
       auto & m = this->getDOFManager().getLumpedMatrix("M");
       auto it = velocity.begin();
       auto end = velocity.end();
       auto m_it = m.begin();
 
       for (UInt node = 0; it != end; ++it, ++m_it, ++node) {
         if (mesh.isLocalOrMasterNode(node))
           res += *m_it * *it * *it;
       }
 
       mesh.getCommunicator().allReduce(res, SynchronizerOperation::_sum);
     }
 
     return res / 2.;
   }
 
   Real getExternalWorkIncrement() {
     Real res = 0;
 
     auto it = velocity.begin();
     auto end = velocity.end();
     auto if_it = internal_forces.begin();
     auto ef_it = forces.begin();
     auto b_it = blocked.begin();
 
     for (UInt node = 0; it != end; ++it, ++if_it, ++ef_it, ++b_it, ++node) {
       if (mesh.isLocalOrMasterNode(node))
         res += (*b_it ? -*if_it : *ef_it) * *it;
     }
 
     mesh.getCommunicator().allReduce(res, SynchronizerOperation::_sum);
 
     return res * this->getTimeStep();
   }
 
   Real mulVectMatVect(const Array<Real> & x, const SparseMatrix & A,
                       const Array<Real> & y) {
     Array<Real> Ay(this->nb_dofs, 1, 0.);
     A.matVecMul(y, Ay);
     Real res = 0.;
 
     Array<Real>::const_scalar_iterator it = Ay.begin();
     Array<Real>::const_scalar_iterator end = Ay.end();
     Array<Real>::const_scalar_iterator x_it = x.begin();
 
     for (UInt node = 0; it != end; ++it, ++x_it, ++node) {
       if (mesh.isLocalOrMasterNode(node))
         res += *x_it * *it;
     }
 
     mesh.getCommunicator().allReduce(res, SynchronizerOperation::_sum);
     return res;
   }
 
   void predictor() {}
   void corrector() {}
 
   /* ------------------------------------------------------------------------ */
   UInt getNbData(const Array<Element> & elements,
                  const SynchronizationTag &) const {
     return elements.size() * sizeof(Real);
   }
 
   void packData(CommunicationBuffer & buffer, const Array<Element> & elements,
                 const SynchronizationTag & tag) const {
     if (tag == _gst_user_1) {
       for (const auto & el : elements) {
         buffer << this->stresses(el.element);
       }
     }
   }
 
   void unpackData(CommunicationBuffer & buffer, const Array<Element> & elements,
                   const SynchronizationTag & tag) {
     if (tag == _gst_user_1) {
       auto cit = this->mesh.getConnectivity(_segment_2, _ghost).begin(2);
 
       for (const auto & el : elements) {
         Real stress;
         buffer >> stress;
 
         Real f = A * stress;
 
         Vector<UInt> conn = cit[el.element];
         this->internal_forces(conn(0), _x) += -f;
         this->internal_forces(conn(1), _x) += f;
       }
     }
   }
 
 private:
   UInt nb_dofs;
   UInt nb_elements;
   Real E, A, rho;
 
   bool lumped;
 
   bool is_stiffness_assembled{false};
   bool is_mass_assembled{false};
   bool is_lumped_mass_assembled{false};
 
 public:
   Mesh & mesh;
   Array<Real> displacement;
   Array<Real> velocity;
   Array<Real> acceleration;
   Array<bool> blocked;
   Array<Real> forces;
   Array<Real> internal_forces;
 
   Array<Real> stresses;
   Array<Real> strains;
 
   Array<Real> initial_lengths;
 };
 
 #endif /* __AKANTU_TEST_MODEL_SOLVER_MY_MODEL_HH__ */
 
 } // akantu
diff --git a/test/test_model/test_non_local_toolbox/my_model.hh b/test/test_model/test_non_local_toolbox/my_model.hh
index 458712eae..6304cf19c 100644
--- a/test/test_model/test_non_local_toolbox/my_model.hh
+++ b/test/test_model/test_non_local_toolbox/my_model.hh
@@ -1,118 +1,122 @@
 /**
  * @file   my_model.hh
  *
  * @author Nicolas Richart
  *
  * @date creation  Sun Sep 10 2017
  *
  * @brief A Documented file.
  *
  * @section LICENSE
  *
  * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free  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 "integrator_gauss.hh"
 #include "model.hh"
 #include "non_local_manager.hh"
 #include "non_local_manager_callback.hh"
 #include "non_local_neighborhood_base.hh"
 #include "shape_lagrange.hh"
 /* -------------------------------------------------------------------------- */
 
 using namespace akantu;
 
 class MyModel : public Model, public NonLocalManagerCallback {
   using MyFEEngineType = FEEngineTemplate<IntegratorGauss, ShapeLagrange>;
 
 public:
   MyModel(Mesh & mesh, UInt spatial_dimension)
       : Model(mesh, spatial_dimension), manager(*this, *this) {
     registerFEEngineObject<MyFEEngineType>("FEEngine", mesh, spatial_dimension);
     manager.registerNeighborhood("test_region", "test_region");
 
     getFEEngine().initShapeFunctions();
     manager.initialize();
   }
 
   void initModel() override {}
 
   MatrixType getMatrixType(const ID &) override { return _mt_not_defined; }
+  std::tuple<ID, TimeStepSolverType>
+  getDefaultSolverID(const AnalysisMethod & /*method*/) {
+    return {"test", _tsst_static};
+  }
+
   void assembleMatrix(const ID &) override {}
   void assembleLumpedMatrix(const ID &) override {}
   void assembleResidual() override {}
 
   void onNodesAdded(const Array<UInt> &, const NewNodesEvent &) override {}
 
   void onNodesRemoved(const Array<UInt> &, const Array<UInt> &,
                       const RemovedNodesEvent &) override {}
   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 {}
 
   void insertIntegrationPointsInNeighborhoods(
       const GhostType & ghost_type) override {
     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);
 
     IntegrationPoint q;
     q.ghost_type = ghost_type;
-    q.kind = _ek_regular;
     q.global_num = 0;
 
     auto & neighborhood = manager.getNeighborhood("test_region");
 
     for (auto & type : quadrature_points_coordinates.elementTypes(
              spatial_dimension, ghost_type)) {
       q.type = type;
       auto & quads = quadrature_points_coordinates(type, ghost_type);
       this->getFEEngine().computeIntegrationPointsCoordinates(quads, type,
                                                               ghost_type);
       auto quad_it = quads.begin(quads.getNbComponent());
       auto quad_end = quads.end(quads.getNbComponent());
       q.num_point = 0;
       for (; quad_it != quad_end; ++quad_it) {
         neighborhood.insertIntegrationPoint(q, *quad_it);
         ++q.num_point;
         ++q.global_num;
       }
     }
   }
 
   void computeNonLocalStresses(const GhostType &) override {}
 
   void updateLocalInternal(ElementTypeMapReal &, const GhostType &,
                            const ElementKind &) override {}
 
   void updateNonLocalInternal(ElementTypeMapReal &, const GhostType &,
                               const ElementKind &) override {}
 
   const auto & getNonLocalManager() const { return manager; }
 
 private:
   NonLocalManager manager;
 };
diff --git a/test/test_model/test_non_local_toolbox/test_build_neighborhood_parallel.cc b/test/test_model/test_non_local_toolbox/test_build_neighborhood_parallel.cc
index 756685754..c199735a3 100644
--- a/test/test_model/test_non_local_toolbox/test_build_neighborhood_parallel.cc
+++ b/test/test_model/test_non_local_toolbox/test_build_neighborhood_parallel.cc
@@ -1,191 +1,191 @@
 /**
  * @file   test_build_neighborhood_parallel.cc
  *
  * @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
  *
  * @date creation: Sat Sep 26 2015
  * @date last modification: Wed Nov 25 2015
  *
  * @brief  test in parallel for the class NonLocalNeighborhood
  *
  * @section LICENSE
  *
  * Copyright (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne) Laboratory
  * (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free  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 "dumper_paraview.hh"
 #include "non_local_neighborhood_base.hh"
 #include "solid_mechanics_model.hh"
 #include "test_material.hh"
 /* -------------------------------------------------------------------------- */
 using namespace akantu;
 /* -------------------------------------------------------------------------- */
 int main(int argc, char * argv[]) {
   akantu::initialize("material_parallel_test.dat", argc, argv);
 
-  auto & comm = akantu::StaticCommunicator::getStaticCommunicator();
+  const auto & comm = Communicator::getStaticCommunicator();
   Int psize = comm.getNbProc();
   Int prank = comm.whoAmI();
 
   // some configuration variables
   const UInt spatial_dimension = 2;
 
   // mesh creation and read
   Mesh mesh(spatial_dimension);
   if (prank == 0) {
     mesh.read("parallel_test.msh");
   }
 
   mesh.distribute();
 
   /// model creation
   SolidMechanicsModel model(mesh);
 
   /// dump the ghost elements before the non-local part is intialized
   DumperParaview dumper_ghost("ghost_elements");
   dumper_ghost.registerMesh(mesh, spatial_dimension, _ghost);
   if (psize > 1) {
     dumper_ghost.dump();
   }
 
   /// creation of material selector
   MeshDataMaterialSelector<std::string> mat_selector("physical_names", model);
   model.setMaterialSelector(mat_selector);
 
   /// dump material index in paraview
   model.addDumpField("partitions");
   model.dump();
 
   /// model initialization changed to use our material
   model.initFull();
 
   /// dump the ghost elements after ghosts for non-local have been added
   if (psize > 1)
     dumper_ghost.dump();
 
   model.addDumpField("grad_u");
   model.addDumpField("grad_u non local");
   model.addDumpField("material_index");
 
   /// apply constant strain field everywhere in the plate
   Matrix<Real> applied_strain(spatial_dimension, spatial_dimension);
   applied_strain.clear();
   for (UInt i = 0; i < spatial_dimension; ++i)
     applied_strain(i, i) = 2.;
 
   ElementType element_type = _triangle_3;
   GhostType ghost_type = _not_ghost;
   /// apply constant grad_u field in all elements
   for (UInt m = 0; m < model.getNbMaterials(); ++m) {
     auto & mat = model.getMaterial(m);
     auto & grad_u = const_cast<Array<Real> &>(
         mat.getInternal<Real>("grad_u")(element_type, ghost_type));
     auto grad_u_it = grad_u.begin(spatial_dimension, spatial_dimension);
     auto grad_u_end = grad_u.end(spatial_dimension, spatial_dimension);
     for (; grad_u_it != grad_u_end; ++grad_u_it)
       (*grad_u_it) = -1. * applied_strain;
   }
 
   /// double the strain in the center: find the closed gauss point to the center
   /// compute the quadrature points
   ElementTypeMapReal quad_coords("quad_coords");
   quad_coords.initialize(mesh, _nb_component = spatial_dimension,
                          _spatial_dimension = spatial_dimension,
                          _with_nb_element = true);
   model.getFEEngine().computeIntegrationPointsCoordinates(quad_coords);
 
   Vector<Real> center(spatial_dimension, 0.);
   Mesh::type_iterator it =
       mesh.firstType(spatial_dimension, _not_ghost, _ek_regular);
   Mesh::type_iterator last_type =
       mesh.lastType(spatial_dimension, _not_ghost, _ek_regular);
   Real min_distance = 2;
   IntegrationPoint q_min;
   for (; it != last_type; ++it) {
     ElementType type = *it;
     UInt nb_elements = mesh.getNbElement(type, _not_ghost);
     UInt nb_quads = model.getFEEngine().getNbIntegrationPoints(type);
     Array<Real> & coords = quad_coords(type, _not_ghost);
     Array<Real>::const_vector_iterator coord_it =
         coords.begin(spatial_dimension);
     for (UInt e = 0; e < nb_elements; ++e) {
       for (UInt q = 0; q < nb_quads; ++q, ++coord_it) {
         Real dist = center.distance(*coord_it);
         if (dist < min_distance) {
           min_distance = dist;
           q_min.element = e;
           q_min.num_point = q;
           q_min.global_num = nb_elements * nb_quads + q;
           q_min.type = type;
         }
       }
     }
   }
 
   Real global_min = min_distance;
-  comm.allReduce(global_min, _so_min);
+  comm.allReduce(global_min, SynchronizerOperation::_min);
 
   if (Math::are_float_equal(global_min, min_distance)) {
     UInt mat_index = model.getMaterialByElement(q_min.type, _not_ghost)
                          .begin()[q_min.element];
     Material & mat = model.getMaterial(mat_index);
     UInt nb_quads = model.getFEEngine().getNbIntegrationPoints(q_min.type);
     UInt local_el_index =
         model.getMaterialLocalNumbering(q_min.type, _not_ghost)
             .begin()[q_min.element];
     UInt local_num = (local_el_index * nb_quads) + q_min.num_point;
     Array<Real> & grad_u = const_cast<Array<Real> &>(
         mat.getInternal<Real>("grad_u")(q_min.type, _not_ghost));
     Array<Real>::iterator<Matrix<Real>> grad_u_it =
         grad_u.begin(spatial_dimension, spatial_dimension);
     grad_u_it += local_num;
     Matrix<Real> & g_u = *grad_u_it;
     g_u += applied_strain;
   }
 
   /// compute the non-local strains
   model.assembleInternalForces();
   model.dump();
 
   /// damage the element with higher grad_u completely, so that it is
   /// not taken into account for the averaging
   if (Math::are_float_equal(global_min, min_distance)) {
     UInt mat_index = model.getMaterialByElement(q_min.type, _not_ghost)
                          .begin()[q_min.element];
     Material & mat = model.getMaterial(mat_index);
     UInt nb_quads = model.getFEEngine().getNbIntegrationPoints(q_min.type);
     UInt local_el_index =
         model.getMaterialLocalNumbering(q_min.type, _not_ghost)
             .begin()[q_min.element];
     UInt local_num = (local_el_index * nb_quads) + q_min.num_point;
     Array<Real> & damage = const_cast<Array<Real> &>(
         mat.getInternal<Real>("damage")(q_min.type, _not_ghost));
     Real * dam_ptr = damage.storage();
     dam_ptr += local_num;
     *dam_ptr = 0.9;
   }
 
   /// compute the non-local strains
   model.assembleInternalForces();
   model.dump();
 
   finalize();
 
   return EXIT_SUCCESS;
 }
diff --git a/test/test_model/test_non_local_toolbox/test_pair_computation.cc b/test/test_model/test_non_local_toolbox/test_pair_computation.cc
index 84207e7cb..d88839d3a 100644
--- a/test/test_model/test_non_local_toolbox/test_pair_computation.cc
+++ b/test/test_model/test_non_local_toolbox/test_pair_computation.cc
@@ -1,227 +1,224 @@
 /**
  * @file   test_pair_computation.cc
  *
  * @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
  *
  * @date creation: Wed Nov 25 2015
  *
  * @brief  test the weight computation with and without grid
  *
  * @section LICENSE
  *
  * Copyright (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne) Laboratory
  * (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free  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 "dumper_paraview.hh"
 #include "non_local_manager.hh"
 #include "non_local_neighborhood.hh"
 #include "solid_mechanics_model.hh"
 #include "test_material_damage.hh"
 /* -------------------------------------------------------------------------- */
 using namespace akantu;
 typedef std::vector<std::pair<IntegrationPoint, IntegrationPoint>> PairList;
 
 /* -------------------------------------------------------------------------- */
 void computePairs(SolidMechanicsModel & model, PairList * pair_list);
 int main(int argc, char * argv[]) {
   akantu::initialize("material_remove_damage.dat", argc, argv);
 
   // some configuration variables
   const UInt spatial_dimension = 2;
 
-  StaticCommunicator & comm =
-      akantu::StaticCommunicator::getStaticCommunicator();
+  const auto & comm = Communicator::getStaticCommunicator();
   Int prank = comm.whoAmI();
 
   // mesh creation and read
   Mesh mesh(spatial_dimension);
   if (prank == 0) {
     mesh.read("pair_test.msh");
   }
   mesh.distribute();
 
   /// model creation
   SolidMechanicsModel model(mesh);
 
   /// creation of material selector
   MeshDataMaterialSelector<std::string> mat_selector("physical_names", model);
   model.setMaterialSelector(mat_selector);
 
   /// model initialization changed to use our material
   model.initFull();
 
   /// dump material index in paraview
   model.addDumpField("material_index");
   model.dump();
 
   /// compute the pairs by looping over all the quadrature points
   PairList pair_list[2];
   computePairs(model, pair_list);
 
   const PairList * pairs_mat_1 = model.getNonLocalManager().getNeighborhood("mat_1").getPairLists();
   const PairList * pairs_mat_2 = model.getNonLocalManager().getNeighborhood("mat_2").getPairLists();
 
   /// compare the number of pairs
   UInt nb_not_ghost_pairs_grid = pairs_mat_1[0].size() + pairs_mat_2[0].size();
   UInt nb_ghost_pairs_grid = pairs_mat_1[1].size() + pairs_mat_2[1].size();
   UInt nb_not_ghost_pairs_no_grid = pair_list[0].size();
   UInt nb_ghost_pairs_no_grid = pair_list[1].size();
 
   if ((nb_not_ghost_pairs_grid != nb_not_ghost_pairs_no_grid) ||
       (nb_ghost_pairs_grid != nb_ghost_pairs_no_grid)) {
     std::cout << "The number of pairs is not correct: TEST FAILED!!!"
               << std::endl;
     finalize();
     return EXIT_FAILURE;
   }
 
   for (UInt i = 0; i < pairs_mat_1[0].size(); ++i) {
     PairList::const_iterator it = std::find(
         pair_list[0].begin(), pair_list[0].end(), (pairs_mat_1[0])[i]);
     if (it == pair_list[0].end()) {
       std::cout << "The pairs are not correct" << std::endl;
       finalize();
       return EXIT_FAILURE;
     }
   }
 
   for (UInt i = 0; i < pairs_mat_2[0].size(); ++i) {
     PairList::const_iterator it = std::find(
         pair_list[0].begin(), pair_list[0].end(), (pairs_mat_2[0])[i]);
     if (it == pair_list[0].end()) {
       std::cout << "The pairs are not correct" << std::endl;
       finalize();
       return EXIT_FAILURE;
     }
   }
 
   for (UInt i = 0; i < pairs_mat_1[1].size(); ++i) {
     PairList::const_iterator it = std::find(
         pair_list[1].begin(), pair_list[1].end(), (pairs_mat_1[1])[i]);
     if (it == pair_list[1].end()) {
       std::cout << "The pairs are not correct" << std::endl;
       finalize();
       return EXIT_FAILURE;
     }
   }
 
   for (UInt i = 0; i < pairs_mat_2[1].size(); ++i) {
     PairList::const_iterator it = std::find(
         pair_list[1].begin(), pair_list[1].end(), (pairs_mat_2[1])[i]);
     if (it == pair_list[1].end()) {
       std::cout << "The pairs are not correct" << std::endl;
       finalize();
       return EXIT_FAILURE;
     }
   }
 
   finalize();
 
   return 0;
 }
 
 /* -------------------------------------------------------------------------- */
 void computePairs(SolidMechanicsModel & model, PairList * pair_list) {
   ElementKind kind = _ek_regular;
   Mesh & mesh = model.getMesh();
   UInt spatial_dimension = model.getSpatialDimension();
   /// compute the quadrature points
   ElementTypeMapReal quad_coords("quad_coords");
   quad_coords.initialize(mesh, _nb_component = spatial_dimension,
                          _spatial_dimension = spatial_dimension,
                          _with_nb_element = true);
   model.getFEEngine().computeIntegrationPointsCoordinates(quad_coords);
 
   /// loop in a n^2 way over all the quads to generate the pairs
   Real neighborhood_radius = 0.5;
   Mesh::type_iterator it_1 =
       mesh.firstType(spatial_dimension, _not_ghost, kind);
   Mesh::type_iterator last_type_1 =
       mesh.lastType(spatial_dimension, _not_ghost, kind);
   IntegrationPoint q1;
   IntegrationPoint q2;
-  q1.kind = kind;
-  q2.kind = kind;
   GhostType ghost_type_1 = _not_ghost;
   q1.ghost_type = ghost_type_1;
   Vector<Real> q1_coords(spatial_dimension);
   Vector<Real> q2_coords(spatial_dimension);
 
   for (; it_1 != last_type_1; ++it_1) {
     ElementType type_1 = *it_1;
     q1.type = type_1;
     UInt nb_elements_1 = mesh.getNbElement(type_1, ghost_type_1);
     UInt nb_quads_1 = model.getFEEngine().getNbIntegrationPoints(type_1);
     Array<Real> & quad_coords_1 = quad_coords(q1.type, q1.ghost_type);
     Array<Real>::const_vector_iterator coord_it_1 =
         quad_coords_1.begin(spatial_dimension);
     for (UInt e_1 = 0; e_1 < nb_elements_1; ++e_1) {
       q1.element = e_1;
       UInt mat_index_1 = model.getMaterialByElement(q1.type, q1.ghost_type)
                              .begin()[q1.element];
       for (UInt q_1 = 0; q_1 < nb_quads_1; ++q_1) {
         q1.global_num = nb_quads_1 * e_1 + q_1;
         q1.num_point = q_1;
         q1_coords = coord_it_1[q1.global_num];
         /// loop over all other quads and create pairs for this given quad
         for (ghost_type_t::iterator gt = ghost_type_t::begin();
              gt != ghost_type_t::end(); ++gt) {
           GhostType ghost_type_2 = *gt;
           q2.ghost_type = ghost_type_2;
           Mesh::type_iterator it_2 =
               mesh.firstType(spatial_dimension, ghost_type_2, kind);
           Mesh::type_iterator last_type_2 =
               mesh.lastType(spatial_dimension, ghost_type_2, kind);
           for (; it_2 != last_type_2; ++it_2) {
             ElementType type_2 = *it_2;
             q2.type = type_2;
             UInt nb_elements_2 = mesh.getNbElement(type_2, ghost_type_2);
             UInt nb_quads_2 =
                 model.getFEEngine().getNbIntegrationPoints(type_2);
             Array<Real> & quad_coords_2 = quad_coords(q2.type, q2.ghost_type);
             Array<Real>::const_vector_iterator coord_it_2 =
                 quad_coords_2.begin(spatial_dimension);
             for (UInt e_2 = 0; e_2 < nb_elements_2; ++e_2) {
               q2.element = e_2;
               UInt mat_index_2 =
                   model.getMaterialByElement(q2.type, q2.ghost_type)
                       .begin()[q2.element];
               for (UInt q_2 = 0; q_2 < nb_quads_2; ++q_2) {
                 q2.global_num = nb_quads_2 * e_2 + q_2;
                 q2.num_point = q_2;
                 q2_coords = coord_it_2[q2.global_num];
                 Real distance = q1_coords.distance(q2_coords);
                 if (mat_index_1 != mat_index_2)
                   continue;
                 else if (distance <=
                              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));
                 }
               }
             }
           }
         }
       }
     }
   }
 }
diff --git a/test/test_model/test_solid_mechanics_model/test_cohesive/test_parallel_cohesive/test_cohesive_facet_stress_synchronizer/test_cohesive_facet_stress_synchronizer.cc b/test/test_model/test_solid_mechanics_model/test_cohesive/test_parallel_cohesive/test_cohesive_facet_stress_synchronizer/test_cohesive_facet_stress_synchronizer.cc
index 1a32681bf..a9a04a914 100644
--- a/test/test_model/test_solid_mechanics_model/test_cohesive/test_parallel_cohesive/test_cohesive_facet_stress_synchronizer/test_cohesive_facet_stress_synchronizer.cc
+++ b/test/test_model/test_solid_mechanics_model/test_cohesive/test_parallel_cohesive/test_cohesive_facet_stress_synchronizer/test_cohesive_facet_stress_synchronizer.cc
@@ -1,205 +1,205 @@
 /**
  * @file   test_cohesive_facet_stress_synchronizer.cc
  *
  * @author Marco Vocialta <marco.vocialta@epfl.ch>
  *
  *
  * @brief  Test for facet stress synchronizer
  *
  * @section LICENSE
  *
  * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  */
 
 /* -------------------------------------------------------------------------- */
 #include <limits>
 #include <fstream>
 #include <iostream>
 
 
 /* -------------------------------------------------------------------------- */
 #include "solid_mechanics_model_cohesive.hh"
 /* -------------------------------------------------------------------------- */
 
 using namespace akantu;
 
 Real function(Real constant, Real x, Real y, Real z) {
   return constant + 2. * x + 3. * y + 4 * z;
 }
 
 int main(int argc, char *argv[]) {
   initialize("material.dat", argc, argv);
 
   const UInt spatial_dimension = 3;
 
   ElementType type = _tetrahedron_10;
   ElementType type_facet = Mesh::getFacetType(type);
   Math::setTolerance(1.e-11);
 
   Mesh mesh(spatial_dimension);
 
-  StaticCommunicator & comm = StaticCommunicator::getStaticCommunicator();
+  const auto & comm = Communicator::getStaticCommunicator();
   Int psize = comm.getNbProc();
   Int prank = comm.whoAmI();
 
   akantu::MeshPartition * partition = NULL;
   if(prank == 0) {
     // Read the mesh
     mesh.read("tetrahedron.msh");
 
     /// partition the mesh
     partition = new MeshPartitionScotch(mesh, spatial_dimension);
     partition->partitionate(psize);
   }
 
   SolidMechanicsModelCohesive model(mesh);
   model.initParallel(partition, NULL, true);
   model.initFull(SolidMechanicsModelCohesiveOptions(_explicit_lumped_mass, true));
 
   Array<Real> & position = mesh.getNodes();
 
   /* ------------------------------------------------------------------------ */
   /* Facet part                                                               */
   /* ------------------------------------------------------------------------ */
 
   /// compute quadrature points positions on facets
   const Mesh & mesh_facets = model.getMeshFacets();
   UInt nb_facet = mesh_facets.getNbElement(type_facet);
   UInt nb_quad_per_facet = model.getFEEngine("FacetsFEEngine").getNbIntegrationPoints(type_facet);
   UInt nb_tot_quad = nb_quad_per_facet * nb_facet;
 
   Array<Real> quad_facets(nb_tot_quad, spatial_dimension);
 
   model.getFEEngine("FacetsFEEngine").interpolateOnIntegrationPoints(position,
 							  quad_facets,
 							  spatial_dimension,
 							  type_facet);
 
   /* ------------------------------------------------------------------------ */
   /* End of facet part                                                        */
   /* ------------------------------------------------------------------------ */
 
 
   /// compute quadrature points position of the elements
   UInt nb_quad_per_element = model.getFEEngine().getNbIntegrationPoints(type);
   UInt nb_element = mesh.getNbElement(type);
   UInt nb_tot_quad_el = nb_quad_per_element * nb_element;
 
   Array<Real> quad_elements(nb_tot_quad_el, spatial_dimension);
 
 
   model.getFEEngine().interpolateOnIntegrationPoints(position,
 					       quad_elements,
 					       spatial_dimension,
 					       type);
 
   /// assign some values to stresses
   Array<Real> & stress
     = const_cast<Array<Real>&>(model.getMaterial(0).getStress(type));
 
   Array<Real>::iterator<Matrix<Real> > stress_it
     = stress.begin(spatial_dimension, spatial_dimension);
 
   for (UInt q = 0; q < nb_tot_quad_el; ++q, ++stress_it) {
 
     /// compute values
     for (UInt i = 0; i < spatial_dimension; ++i) {
       for (UInt j = i; j < spatial_dimension; ++j) {
     	UInt index = i * spatial_dimension + j;
     	(*stress_it)(i, j) = function(index,
 				      quad_elements(q, 0),
 				      quad_elements(q, 1),
 				      quad_elements(q, 2));
       }
     }
 
     /// fill symmetrical part
     for (UInt i = 0; i < spatial_dimension; ++i) {
       for (UInt j = 0; j < i; ++j) {
     	(*stress_it)(i, j) = (*stress_it)(j, i);
       }
     }
 
     // stress_it->clear();
     // for (UInt i = 0; i < spatial_dimension; ++i)
     //   (*stress_it)(i, i) = sigma_c * 5;
   }
 
 
   /// compute and communicate stress on facets
   model.checkCohesiveStress();
 
   /* ------------------------------------------------------------------------ */
   /* Check facet stress                                                       */
   /* ------------------------------------------------------------------------ */
 
   const Array<Real> & facet_stress = model.getStressOnFacets(type_facet);
   const Array<bool> & facet_check
     = model.getElementInserter().getCheckFacets(type_facet);
   const Array<std::vector<Element> > & elements_to_facet
     = model.getMeshFacets().getElementToSubelement(type_facet);
 
   Array<Real>::iterator<Vector<Real> > quad_facet_it
     = quad_facets.begin(spatial_dimension);
   Array<Real>::const_iterator<Matrix<Real> > facet_stress_it
     = facet_stress.begin(spatial_dimension, spatial_dimension * 2);
 
   Matrix<Real> current_stress(spatial_dimension, spatial_dimension);
 
   for (UInt f = 0; f < nb_facet; ++f) {
 
     if (!facet_check(f) ||
 	(elements_to_facet(f)[0].ghost_type == _not_ghost &&
 	 elements_to_facet(f)[1].ghost_type == _not_ghost)) {
       quad_facet_it += nb_quad_per_facet;
       facet_stress_it += nb_quad_per_facet;
       continue;
     }
 
     for (UInt q = 0; q < nb_quad_per_facet; ++q, ++quad_facet_it, ++facet_stress_it) {
       /// compute current_stress
       for (UInt i = 0; i < spatial_dimension; ++i) {
 	for (UInt j = i; j < spatial_dimension; ++j) {
 	  UInt index = i * spatial_dimension + j;
 	  current_stress(i, j) = function(index,
 					  (*quad_facet_it)(0),
 					  (*quad_facet_it)(1),
 					  (*quad_facet_it)(2));
 	}
       }
 
       /// fill symmetrical part
       for (UInt i = 0; i < spatial_dimension; ++i) {
 	for (UInt j = 0; j < i; ++j) {
 	  current_stress(i, j) = current_stress(j, i);
 	}
       }
 
       /// compare it to interpolated one
       for (UInt s = 0; s < 2; ++s) {
 	Matrix<Real> stress_to_check(facet_stress_it->storage()
 				     + s * spatial_dimension * spatial_dimension,
 				     spatial_dimension,
 				     spatial_dimension);
 
 
 	for (UInt i = 0; i < spatial_dimension; ++i) {
 	  for (UInt j = 0; j < spatial_dimension; ++j) {
 	    if (!Math::are_float_equal(stress_to_check(i, j), current_stress(i, j))) {
 	      std::cout << "Stress doesn't match" << std::endl;
 	      finalize();
 	      return EXIT_FAILURE;
 	    }
 	  }
 	}
       }
     }
   }
 
   finalize();
   if (prank == 0)
     std::cout << "OK: test_cohesive_facet_stress_synchronizer passed!" << std::endl;
   return EXIT_SUCCESS;
 }
diff --git a/test/test_model/test_solid_mechanics_model/test_cohesive/test_parallel_cohesive/test_cohesive_parallel_buildfragments/test_cohesive_parallel_buildfragments.cc b/test/test_model/test_solid_mechanics_model/test_cohesive/test_parallel_cohesive/test_cohesive_parallel_buildfragments/test_cohesive_parallel_buildfragments.cc
index 0484a2351..f80e75f54 100644
--- a/test/test_model/test_solid_mechanics_model/test_cohesive/test_parallel_cohesive/test_cohesive_parallel_buildfragments/test_cohesive_parallel_buildfragments.cc
+++ b/test/test_model/test_solid_mechanics_model/test_cohesive/test_parallel_cohesive/test_cohesive_parallel_buildfragments/test_cohesive_parallel_buildfragments.cc
@@ -1,432 +1,432 @@
 /**
  * @file   test_cohesive_parallel_buildfragments.cc
  *
  * @author Marco Vocialta <marco.vocialta@epfl.ch>
  *
  *
  * @brief  Test to build fragments in parallel
  *
  * @section LICENSE
  *
  * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  */
 
 /* -------------------------------------------------------------------------- */
 #include <limits>
 #include <fstream>
 #include <iostream>
 #include <algorithm>
 #include <functional>
 /* -------------------------------------------------------------------------- */
 #include "solid_mechanics_model_cohesive.hh"
 #include "material_cohesive.hh"
 #include "fragment_manager.hh"
 /* -------------------------------------------------------------------------- */
 
 using namespace akantu;
 
 void verticalInsertionLimit(SolidMechanicsModelCohesive &);
 void displaceElements(SolidMechanicsModelCohesive &, const Real, const Real);
 bool isInertiaEqual(const Vector<Real> &, const Vector<Real> &);
 void rotateArray(Array<Real> & array, Real angle);
 UInt getNbBigFragments(FragmentManager &, UInt);
 
 const UInt spatial_dimension = 3;
 const UInt total_nb_fragment = 4;
 const Real rotation_angle = M_PI / 4.;
 const Real global_tolerance = 1.e-9;
 
 int main(int argc, char *argv[]) {
   initialize("material.dat", argc, argv);
 
   Math::setTolerance(global_tolerance);
 
   Mesh mesh(spatial_dimension);
 
-  StaticCommunicator & comm = StaticCommunicator::getStaticCommunicator();
+  const auto & comm = Communicator::getStaticCommunicator();
   Int psize = comm.getNbProc();
   Int prank = comm.whoAmI();
 
   akantu::MeshPartition * partition = NULL;
   if(prank == 0) {
     // Read the mesh
     mesh.read("mesh.msh");
 
     /// partition the mesh
     MeshUtils::purifyMesh(mesh);
     partition = new MeshPartitionScotch(mesh, spatial_dimension);
     partition->partitionate(psize);
   }
 
   SolidMechanicsModelCohesive model(mesh);
   model.initParallel(partition, NULL, true);
 
   delete partition;
 
   /// model initialization
   model.initFull(SolidMechanicsModelCohesiveOptions(_explicit_lumped_mass, true));
 
   mesh.computeBoundingBox();
   Real L = mesh.getUpperBounds()(0) - mesh.getLowerBounds()(0);
   Real h = mesh.getUpperBounds()(1) - mesh.getLowerBounds()(1);
   Real rho = model.getMaterial("bulk").getParam<Real>("rho");
 
   Real theoretical_mass = L * h * h * rho;
   Real frag_theo_mass = theoretical_mass / total_nb_fragment;
 
   UInt nb_element = mesh.getNbElement(spatial_dimension, _not_ghost, _ek_regular);
   comm.allReduce(&nb_element, 1, _so_sum);
   UInt nb_element_per_fragment = nb_element / total_nb_fragment;
 
   FragmentManager fragment_manager(model);
 
   fragment_manager.computeAllData();
   getNbBigFragments(fragment_manager, nb_element_per_fragment + 1);
 
   model.setBaseName("extrinsic");
   model.addDumpFieldVector("displacement");
   model.addDumpField("velocity");
   model.addDumpField("stress");
   model.addDumpField("partitions");
   model.addDumpField("fragments");
   model.addDumpField("fragments mass");
   model.addDumpField("moments of inertia");
   model.addDumpField("elements per fragment");
   model.dump();
 
   model.setBaseNameToDumper("cohesive elements", "cohesive_elements_test");
   model.addDumpFieldVectorToDumper("cohesive elements", "displacement");
   model.addDumpFieldToDumper("cohesive elements", "damage");
   model.dump("cohesive elements");
 
   /// set check facets
   verticalInsertionLimit(model);
 
   model.assembleMassLumped();
   model.synchronizeBoundaries();
 
   /// impose initial displacement
   Array<Real> & displacement = model.getDisplacement();
   Array<Real> & velocity = model.getVelocity();
   const Array<Real> & position = mesh.getNodes();
   UInt nb_nodes = mesh.getNbNodes();
 
   for (UInt n = 0; n < nb_nodes; ++n) {
     displacement(n, 0) = position(n, 0) * 0.1;
     velocity(n, 0) = position(n, 0);
   }
 
   rotateArray(mesh.getNodes(), rotation_angle);
   //  rotateArray(displacement, rotation_angle);
   //  rotateArray(velocity, rotation_angle);
 
   model.updateResidual();
   model.checkCohesiveStress();
   model.dump();
   model.dump("cohesive elements");
 
   const Array<Real> & fragment_mass = fragment_manager.getMass();
   const Array<Real> & fragment_center = fragment_manager.getCenterOfMass();
 
   Real el_size = L / total_nb_fragment;
   Real lim = -L/2 + el_size * 0.99;
 
   /// define theoretical inertia moments
   Vector<Real> small_frag_inertia(spatial_dimension);
   small_frag_inertia(0) = frag_theo_mass * (h*h + h*h) / 12.;
   small_frag_inertia(1) = frag_theo_mass * (el_size*el_size + h*h) / 12.;
   small_frag_inertia(2) = frag_theo_mass * (el_size*el_size + h*h) / 12.;
 
   std::sort(small_frag_inertia.storage(),
 	    small_frag_inertia.storage() + spatial_dimension,
 	    std::greater<Real>());
 
   const Array<Real> & inertia_moments = fragment_manager.getMomentsOfInertia();
   Array<Real>::const_iterator< Vector<Real> > inertia_moments_begin
     = inertia_moments.begin(spatial_dimension);
 
   /// displace one fragment each time
   for (UInt frag = 1; frag <= total_nb_fragment; ++frag) {
     if (prank == 0)
       std::cout << "Generating fragment: " << frag << std::endl;
 
     fragment_manager.computeAllData();
 
     /// check number of big fragments
     UInt nb_big_fragment = getNbBigFragments(fragment_manager,
 					     nb_element_per_fragment + 1);
 
     model.dump();
     model.dump("cohesive elements");
 
 
     if (frag < total_nb_fragment) {
       if (nb_big_fragment != 1) {
 	AKANTU_DEBUG_ERROR("The number of big fragments is wrong: " << nb_big_fragment);
 	return EXIT_FAILURE;
       }
     }
     else {
       if (nb_big_fragment != 0) {
 	AKANTU_DEBUG_ERROR("The number of big fragments is wrong: " << nb_big_fragment);
 	return EXIT_FAILURE;
       }
     }
 
     /// check number of fragments
     UInt nb_fragment_num = fragment_manager.getNbFragment();
 
     if (nb_fragment_num != frag) {
       AKANTU_DEBUG_ERROR("The number of fragments is wrong! Numerical: " << nb_fragment_num << " Theoretical: " << frag);
       return EXIT_FAILURE;
     }
 
     /// check mass computation
     if (frag < total_nb_fragment) {
       Real total_mass = 0.;
       UInt small_fragments = 0;
 
       for (UInt f = 0; f < nb_fragment_num; ++f) {
 	const Vector<Real> & current_inertia = inertia_moments_begin[f];
 
 	if (Math::are_float_equal(fragment_mass(f, 0), frag_theo_mass)) {
 
 	  /// check center of mass
 	  if (fragment_center(f, 0) > (L * frag / total_nb_fragment - L / 2)) {
 	    AKANTU_DEBUG_ERROR("Fragment center is wrong!");
 	    return EXIT_FAILURE;
 	  }
 
 	  /// check moment of inertia
 	  if (!isInertiaEqual(current_inertia, small_frag_inertia)) {
 	    AKANTU_DEBUG_ERROR("Inertia moments are wrong");
 	    return EXIT_FAILURE;
 	  }
 
 	  ++small_fragments;
 	  total_mass += frag_theo_mass;
 	}
 	else {
 	  /// check the moment of inertia for the biggest fragment
 	  Real big_frag_mass = frag_theo_mass * (total_nb_fragment - frag + 1);
 	  Real big_frag_size = el_size * (total_nb_fragment - frag + 1);
 
 	  Vector<Real> big_frag_inertia(spatial_dimension);
 	  big_frag_inertia(0) = big_frag_mass * (h*h + h*h) / 12.;
 	  big_frag_inertia(1)
 	    = big_frag_mass * (big_frag_size*big_frag_size + h*h) / 12.;
 	  big_frag_inertia(2)
 	    = big_frag_mass * (big_frag_size*big_frag_size + h*h) / 12.;
 
 	  std::sort(big_frag_inertia.storage(),
 		    big_frag_inertia.storage() + spatial_dimension,
 		    std::greater<Real>());
 
 	  if (!isInertiaEqual(current_inertia, big_frag_inertia)) {
 	    AKANTU_DEBUG_ERROR("Inertia moments are wrong");
 	    return EXIT_FAILURE;
 	  }
 
 	}
       }
 
       if (small_fragments != nb_fragment_num - 1) {
 	AKANTU_DEBUG_ERROR("The number of small fragments is wrong!");
 	return EXIT_FAILURE;
       }
 
       if (!Math::are_float_equal(total_mass,
 				 small_fragments * frag_theo_mass)) {
 	AKANTU_DEBUG_ERROR("The mass of small fragments is wrong!");
 	return EXIT_FAILURE;
       }
     }
 
 
     /// displace fragments
     rotateArray(mesh.getNodes(), -rotation_angle);
     //    rotateArray(displacement, -rotation_angle);
     displaceElements(model, lim, el_size * 2);
     rotateArray(mesh.getNodes(), rotation_angle);
     //    rotateArray(displacement, rotation_angle);
 
     model.updateResidual();
 
     lim += el_size;
   }
 
   model.dump();
   model.dump("cohesive elements");
 
   /// check centers
   const Array<Real> & fragment_velocity = fragment_manager.getVelocity();
 
   Real initial_position = -L / 2. + el_size / 2.;
 
   for (UInt frag = 0; frag < total_nb_fragment; ++frag) {
     Real theoretical_center = initial_position + el_size * frag;
 
     UInt f_index = 0;
     while (f_index < total_nb_fragment &&
   	   !Math::are_float_equal(fragment_center(f_index, 0), theoretical_center))
       ++f_index;
 
     if (f_index == total_nb_fragment) {
       AKANTU_DEBUG_ERROR("The fragments' center is wrong!");
       return EXIT_FAILURE;
     }
 
     f_index = 0;
     while (f_index < total_nb_fragment &&
   	   !Math::are_float_equal(fragment_velocity(f_index, 0),
 				  theoretical_center))
       ++f_index;
 
     if (f_index == total_nb_fragment) {
       AKANTU_DEBUG_ERROR("The fragments' velocity is wrong!");
       return EXIT_FAILURE;
     }
   }
 
   finalize();
 
   if (prank == 0)
     std::cout << "OK: test_cohesive_buildfragments was passed!" << std::endl;
   return EXIT_SUCCESS;
 }
 
 void verticalInsertionLimit(SolidMechanicsModelCohesive & model) {
   UInt spatial_dimension = model.getSpatialDimension();
   const Mesh & mesh_facets = model.getMeshFacets();
   const Array<Real> & position = mesh_facets.getNodes();
 
   for (ghost_type_t::iterator gt = ghost_type_t::begin();
        gt != ghost_type_t::end();
        ++gt) {
     GhostType ghost_type = *gt;
 
     Mesh::type_iterator it  = mesh_facets.firstType(spatial_dimension - 1, ghost_type);
     Mesh::type_iterator end = mesh_facets.lastType(spatial_dimension - 1, ghost_type);
     for(; it != end; ++it) {
       ElementType type = *it;
 
       Array<bool> & check_facets
 	= model.getElementInserter().getCheckFacets(type, ghost_type);
 
       const Array<UInt> & connectivity = mesh_facets.getConnectivity(type, ghost_type);
       UInt nb_nodes_per_facet = connectivity.getNbComponent();
 
       for (UInt f = 0; f < check_facets.getSize(); ++f) {
 	if (!check_facets(f)) continue;
 
 	UInt nb_aligned_nodes = 1;
 	Real first_node_pos = position(connectivity(f, 0), 0);
 
 	for (; nb_aligned_nodes < nb_nodes_per_facet; ++nb_aligned_nodes) {
 	  Real other_node_pos = position(connectivity(f, nb_aligned_nodes), 0);
 
 	  if (! Math::are_float_equal(first_node_pos, other_node_pos))
 	    break;
 	}
 
 	if (nb_aligned_nodes != nb_nodes_per_facet) {
 	  check_facets(f) = false;
 	}
       }
     }
   }
 }
 
 void displaceElements(SolidMechanicsModelCohesive & model,
 		      const Real lim,
 		      const Real amount) {
   UInt spatial_dimension = model.getSpatialDimension();
   Array<Real> & displacement = model.getDisplacement();
   Mesh & mesh = model.getMesh();
   UInt nb_nodes = mesh.getNbNodes();
   Array<bool> displaced(nb_nodes);
   displaced.clear();
   Vector<Real> barycenter(spatial_dimension);
 
   for (ghost_type_t::iterator gt = ghost_type_t::begin();
        gt != ghost_type_t::end();
        ++gt) {
     GhostType ghost_type = *gt;
 
     Mesh::type_iterator it  = mesh.firstType(spatial_dimension, ghost_type);
     Mesh::type_iterator end = mesh.lastType(spatial_dimension, ghost_type);
     for(; it != end; ++it) {
       ElementType type = *it;
       const Array<UInt> & connectivity = mesh.getConnectivity(type, ghost_type);
       UInt nb_element = connectivity.getSize();
       UInt nb_nodes_per_element = connectivity.getNbComponent();
 
       Array<UInt>::const_vector_iterator conn_el
 	= connectivity.begin(nb_nodes_per_element);
 
       for (UInt el = 0; el < nb_element; ++el) {
 	mesh.getBarycenter(el, type, barycenter.storage(), ghost_type);
 
 	if (barycenter(0) < lim) {
 	  const Vector<UInt> & conn = conn_el[el];
 
 	  for (UInt n = 0; n < nb_nodes_per_element; ++n) {
 	    UInt node = conn(n);
 	    if (!displaced(node)) {
 	      displacement(node, 0) -= amount;
 	      displaced(node) = true;
 	    }
 	  }
 	}
       }
     }
   }
 }
 
 bool isInertiaEqual(const Vector<Real> & a, const Vector<Real> & b) {
   UInt nb_terms = a.size();
   UInt equal_terms = 0;
 
   while (equal_terms < nb_terms &&
 	 std::abs(a(equal_terms) - b(equal_terms)) / a(equal_terms) < Math::getTolerance())
     ++equal_terms;
 
   return equal_terms == nb_terms;
 }
 
 void rotateArray(Array<Real> & array, Real angle) {
   UInt spatial_dimension = array.getNbComponent();
 
   Real rotation_values[] = {std::cos(angle), std::sin(angle), 0,
 			    -std::sin(angle), std::cos(angle), 0,
 			    0, 0, 1};
   Matrix<Real> rotation(rotation_values, spatial_dimension, spatial_dimension);
 
   RVector displaced_node(spatial_dimension);
   Array<Real>::vector_iterator node_it = array.begin(spatial_dimension);
   Array<Real>::vector_iterator node_end = array.end(spatial_dimension);
 
   for (; node_it != node_end; ++node_it) {
     displaced_node.mul<false>(rotation, *node_it);
     *node_it = displaced_node;
   }
 }
 
 UInt getNbBigFragments(FragmentManager & fragment_manager,
 		       UInt minimum_nb_elements) {
   fragment_manager.computeNbElementsPerFragment();
   const Array<UInt> & nb_elements_per_fragment
     = fragment_manager.getNbElementsPerFragment();
   UInt nb_fragment = fragment_manager.getNbFragment();
   UInt nb_big_fragment = 0;
 
   for (UInt frag = 0; frag < nb_fragment; ++frag) {
     if (nb_elements_per_fragment(frag) >= minimum_nb_elements) {
       ++nb_big_fragment;
     }
   }
 
   return nb_big_fragment;
 }
diff --git a/test/test_model/test_solid_mechanics_model/test_cohesive/test_parallel_cohesive/test_cohesive_parallel_extrinsic/test_cohesive_parallel_extrinsic.cc b/test/test_model/test_solid_mechanics_model/test_cohesive/test_parallel_cohesive/test_cohesive_parallel_extrinsic/test_cohesive_parallel_extrinsic.cc
index f5b83daac..ece21b065 100644
--- a/test/test_model/test_solid_mechanics_model/test_cohesive/test_parallel_cohesive/test_cohesive_parallel_extrinsic/test_cohesive_parallel_extrinsic.cc
+++ b/test/test_model/test_solid_mechanics_model/test_cohesive/test_parallel_cohesive/test_cohesive_parallel_extrinsic/test_cohesive_parallel_extrinsic.cc
@@ -1,172 +1,172 @@
 /**
  * @file   test_cohesive_parallel_extrinsic.cc
  *
  * @author Marco Vocialta <marco.vocialta@epfl.ch>
  *
  *
  * @brief  parallel test for cohesive elements
  *
  * @section LICENSE
  *
  * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  */
 
 /* -------------------------------------------------------------------------- */
 #include "solid_mechanics_model_cohesive.hh"
 #include "dumper_paraview.hh"
 /* -------------------------------------------------------------------------- */
 using namespace akantu;
 
 int main(int argc, char *argv[]) {
   initialize("material.dat", argc, argv);
 
   const UInt max_steps = 500;
 
   UInt spatial_dimension = 2;
   Mesh mesh(spatial_dimension);
 
-  StaticCommunicator & comm = StaticCommunicator::getStaticCommunicator();
+  const auto & comm = Communicator::getStaticCommunicator();
   Int psize = comm.getNbProc();
   Int prank = comm.whoAmI();
 
   akantu::MeshPartition * partition = NULL;
   if(prank == 0) {
     // Read the mesh
     mesh.read("mesh.msh");
 
     /// partition the mesh
     partition = new MeshPartitionScotch(mesh, spatial_dimension);
     //    debug::setDebugLevel(dblDump);
     partition->partitionate(psize);
     //    debug::setDebugLevel(dblWarning);
   }
 
   SolidMechanicsModelCohesive model(mesh);
 
   model.initParallel(partition, NULL, true);
 
   // debug::setDebugLevel(dblDump);
   // std::cout << mesh << std::endl;
   // debug::setDebugLevel(dblWarning);
 
 
   model.initFull(SolidMechanicsModelCohesiveOptions(_explicit_lumped_mass, true));
   model.limitInsertion(_y, -0.30, -0.20);
   model.updateAutomaticInsertion();
 
   // debug::setDebugLevel(dblDump);
   // std::cout << mesh_facets << std::endl;
   // debug::setDebugLevel(dblWarning);
 
   Real time_step = model.getStableTimeStep()*0.1;
   model.setTimeStep(time_step);
   std::cout << "Time step: " << time_step << std::endl;
 
   model.assembleMassLumped();
 
 
   Array<Real> & position = mesh.getNodes();
   Array<Real> & velocity = model.getVelocity();
   Array<bool> & boundary = model.getBlockedDOFs();
   Array<Real> & displacement = model.getDisplacement();
   //  const Array<Real> & residual = model.getResidual();
 
   UInt nb_nodes = mesh.getNbNodes();
 
   /// boundary conditions
   for (UInt n = 0; n < nb_nodes; ++n) {
     if (position(n, 1) > 0.99 || position(n, 1) < -0.99)
       boundary(n, 1) = true;
 
     if (position(n, 0) > 0.99 || position(n, 0) < -0.99)
       boundary(n, 0) = true;
   }
 
   /// initial conditions
   Real loading_rate = 0.5;
   Real disp_update = loading_rate * time_step;
   for (UInt n = 0; n < nb_nodes; ++n) {
     velocity(n, 1) = loading_rate * position(n, 1);
   }
 
   model.synchronizeBoundaries();
   model.updateResidual();
 
   model.setBaseName("extrinsic_parallel");
   model.addDumpFieldVector("displacement");
   model.addDumpField("velocity"    );
   model.addDumpField("acceleration");
   model.addDumpField("residual"    );
   model.addDumpField("stress");
   model.addDumpField("grad_u");
   model.addDumpField("partitions");
   //  model.getDumper().getDumper().setMode(iohelper::BASE64);
   model.dump();
 
   model.setBaseNameToDumper("cohesive elements",
 			    "extrinsic_parallel_cohesive_elements");
   model.addDumpFieldVectorToDumper("cohesive elements", "displacement");
   model.addDumpFieldToDumper("cohesive elements", "damage");
   model.dump("cohesive elements");
 
   /// Main loop
   for (UInt s = 1; s <= max_steps; ++s) {
 
     /// update displacement on extreme nodes
     for (UInt n = 0; n < nb_nodes; ++n) {
       if (position(n, 1) > 0.99 || position(n, 1) < -0.99)
 	displacement(n, 1) += disp_update * position(n, 1);
     }
 
     model.checkCohesiveStress();
     model.solveStep();
 
     // model.dump();
     if(s % 10 == 0) {
       if(prank == 0) std::cout << "passing step " << s << "/" << max_steps << std::endl;
     }
 
     // // update displacement
     // for (UInt n = 0; n < nb_nodes; ++n) {
     //   if (position(n, 1) + displacement(n, 1) > 0) {
     // 	displacement(n, 0) -= 0.01;
     //   }
     // }
 
     //    Real Ed = dynamic_cast<MaterialCohesive&> (model.getMaterial(1)).getDissipatedEnergy();
     //    Real Er = dynamic_cast<MaterialCohesive&> (model.getMaterial(1)).getReversibleEnergy();
 
     // edis << s << " "
     // 	 << Ed << std::endl;
 
     // erev << s << " "
     // 	 << Er << std::endl;
 
   }
 
   model.dump();
   model.dump("cohesive elements");
 
   // edis.close();
   // erev.close();
 
   Real Ed = model.getEnergy("dissipated");
 
   Real Edt = 200 * sqrt(2);
 
 
   if(prank == 0) {
     std::cout << Ed << " " << Edt << std::endl;
 
     if (Ed < Edt * 0.999 || Ed > Edt * 1.001 || std::isnan(Ed)) {
       std::cout << "The dissipated energy is incorrect" << std::endl;
       finalize();
       return EXIT_FAILURE;
     }
   }
 
   finalize();
   return EXIT_SUCCESS;
 }
diff --git a/test/test_model/test_solid_mechanics_model/test_cohesive/test_parallel_cohesive/test_cohesive_parallel_extrinsic/test_cohesive_parallel_extrinsic_tetrahedron.cc b/test/test_model/test_solid_mechanics_model/test_cohesive/test_parallel_cohesive/test_cohesive_parallel_extrinsic/test_cohesive_parallel_extrinsic_tetrahedron.cc
index 05e10df9c..256c12b66 100644
--- a/test/test_model/test_solid_mechanics_model/test_cohesive/test_parallel_cohesive/test_cohesive_parallel_extrinsic/test_cohesive_parallel_extrinsic_tetrahedron.cc
+++ b/test/test_model/test_solid_mechanics_model/test_cohesive/test_parallel_cohesive/test_cohesive_parallel_extrinsic/test_cohesive_parallel_extrinsic_tetrahedron.cc
@@ -1,230 +1,230 @@
 /**
  * @file   test_cohesive_parallel_extrinsic_tetrahedron.cc
  *
  * @author Marco Vocialta <marco.vocialta@epfl.ch>
  *
  *
  * @brief  3D extrinsic cohesive elements test
  *
  * @section LICENSE
  *
  * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  */
 
 /* -------------------------------------------------------------------------- */
 #include "solid_mechanics_model_cohesive.hh"
 #include "material_cohesive_linear.hh"
 
 /* -------------------------------------------------------------------------- */
 using namespace akantu;
 
 Real function(Real constant, Real x, Real y, Real z) {
   return constant + 2. * x + 3. * y + 4 * z;
 }
 
 int main(int argc, char *argv[]) {
   initialize("material.dat", argc, argv);
 
   debug::setDebugLevel(dblWarning);
 
   // const UInt max_steps = 1000;
   // Real increment = 0.005;
   const UInt spatial_dimension = 3;
   Math::setTolerance(1.e-12);
 
   ElementType type = _tetrahedron_10;
   ElementType type_facet = Mesh::getFacetType(type);
   ElementType type_cohesive = FEEngine::getCohesiveElementType(type_facet);
 
   Mesh mesh(spatial_dimension);
 
-  StaticCommunicator & comm = StaticCommunicator::getStaticCommunicator();
+  const auto & comm = Communicator::getStaticCommunicator();
   Int psize = comm.getNbProc();
   Int prank = comm.whoAmI();
 
   akantu::MeshPartition * partition = NULL;
   if(prank == 0) {
     // Read the mesh
     mesh.read("tetrahedron.msh");
 
     /// partition the mesh
     partition = new MeshPartitionScotch(mesh, spatial_dimension);
     partition->partitionate(psize);
   }
 
   SolidMechanicsModelCohesive model(mesh);
 
   /// model initialization
   model.initParallel(partition, NULL, true);
   model.initFull(SolidMechanicsModelCohesiveOptions(_explicit_lumped_mass, true));
 
   const MaterialCohesiveLinear<3> & mat_cohesive
     = dynamic_cast < const MaterialCohesiveLinear<3> & > (model.getMaterial(1));
 
   const Real sigma_c = mat_cohesive.getParam< RandomInternalField<Real, FacetInternalField> >("sigma_c");
   const Real beta = mat_cohesive.getParam<Real>("beta");
   //  const Real G_cI = mat_cohesive.getParam<Real>("G_cI");
 
   Array<Real> & position = mesh.getNodes();
 
   /* ------------------------------------------------------------------------ */
   /* Facet part                                                               */
   /* ------------------------------------------------------------------------ */
 
   /// compute quadrature points positions on facets
   const Mesh & mesh_facets = model.getMeshFacets();
   UInt nb_facet = mesh_facets.getNbElement(type_facet);
   UInt nb_quad_per_facet = model.getFEEngine("FacetsFEEngine").getNbIntegrationPoints(type_facet);
   UInt nb_tot_quad = nb_quad_per_facet * nb_facet;
 
   Array<Real> quad_facets(nb_tot_quad, spatial_dimension);
 
   model.getFEEngine("FacetsFEEngine").interpolateOnIntegrationPoints(position,
 							  quad_facets,
 							  spatial_dimension,
 							  type_facet);
 
   /* ------------------------------------------------------------------------ */
   /* End of facet part                                                        */
   /* ------------------------------------------------------------------------ */
 
 
   /// compute quadrature points position of the elements
   UInt nb_quad_per_element = model.getFEEngine().getNbIntegrationPoints(type);
   UInt nb_element = mesh.getNbElement(type);
   UInt nb_tot_quad_el = nb_quad_per_element * nb_element;
 
   Array<Real> quad_elements(nb_tot_quad_el, spatial_dimension);
 
 
   model.getFEEngine().interpolateOnIntegrationPoints(position,
 					       quad_elements,
 					       spatial_dimension,
 					       type);
 
   /// assign some values to stresses
   Array<Real> & stress
     = const_cast<Array<Real>&>(model.getMaterial(0).getStress(type));
 
   Array<Real>::iterator<Matrix<Real> > stress_it
     = stress.begin(spatial_dimension, spatial_dimension);
 
   for (UInt q = 0; q < nb_tot_quad_el; ++q, ++stress_it) {
 
     /// compute values
     for (UInt i = 0; i < spatial_dimension; ++i) {
       for (UInt j = i; j < spatial_dimension; ++j) {
     	UInt index = i * spatial_dimension + j;
     	(*stress_it)(i, j) = index * function(sigma_c * 5,
     					      quad_elements(q, 0),
     					      quad_elements(q, 1),
     					      quad_elements(q, 2));
       }
     }
 
     /// fill symmetrical part
     for (UInt i = 0; i < spatial_dimension; ++i) {
       for (UInt j = 0; j < i; ++j) {
     	(*stress_it)(i, j) = (*stress_it)(j, i);
       }
     }
   }
 
 
   /// compute stress on facet quads
   Array<Real> stress_facets(nb_tot_quad, spatial_dimension * spatial_dimension);
 
   Array<Real>::iterator<Matrix<Real> > stress_facets_it
     = stress_facets.begin(spatial_dimension, spatial_dimension);
 
   for (UInt q = 0; q < nb_tot_quad; ++q, ++stress_facets_it) {
     /// compute values
     for (UInt i = 0; i < spatial_dimension; ++i) {
       for (UInt j = i; j < spatial_dimension; ++j) {
     	UInt index = i * spatial_dimension + j;
     	(*stress_facets_it)(i, j) = index * function(sigma_c * 5,
     						     quad_facets(q, 0),
     						     quad_facets(q, 1),
     						     quad_facets(q, 2));
       }
     }
 
     /// fill symmetrical part
     for (UInt i = 0; i < spatial_dimension; ++i) {
       for (UInt j = 0; j < i; ++j) {
     	(*stress_facets_it)(i, j) = (*stress_facets_it)(j, i);
       }
     }
   }
 
 
   /// insert cohesive elements
   model.checkCohesiveStress();
 
 
   /// check insertion stress
   const Array<Real> & normals =
     model.getFEEngine("FacetsFEEngine").getNormalsOnIntegrationPoints(type_facet);
   const Array<Real> & tangents = model.getTangents(type_facet);
   const Array<Real> & sigma_c_eff = mat_cohesive.getInsertionTraction(type_cohesive);
 
   Vector<Real> normal_stress(spatial_dimension);
 
   const Array<std::vector<Element> > & coh_element_to_facet
     = mesh_facets.getElementToSubelement(type_facet);
 
   Array<Real>::iterator<Matrix<Real> > quad_facet_stress
     = stress_facets.begin(spatial_dimension, spatial_dimension);
 
   Array<Real>::const_iterator<Vector<Real> > quad_normal
     = normals.begin(spatial_dimension);
 
   Array<Real>::const_iterator<Vector<Real> > quad_tangents
     = tangents.begin(tangents.getNbComponent());
 
   for (UInt f = 0; f < nb_facet; ++f) {
     const Element & cohesive_element = coh_element_to_facet(f)[1];
 
     for (UInt q = 0; q < nb_quad_per_facet; ++q, ++quad_facet_stress,
 	   ++quad_normal, ++quad_tangents) {
       if (cohesive_element == ElementNull) continue;
 
       normal_stress.mul<false>(*quad_facet_stress, *quad_normal);
 
       Real normal_contrib = normal_stress.dot(*quad_normal);
 
       Real first_tangent_contrib = 0;
 
       for (UInt dim = 0; dim < spatial_dimension; ++dim)
 	first_tangent_contrib += normal_stress(dim) * (*quad_tangents)(dim);
 
       Real second_tangent_contrib = 0;
 
       for (UInt dim = 0; dim < spatial_dimension; ++dim)
 	second_tangent_contrib
 	  += normal_stress(dim) * (*quad_tangents)(dim + spatial_dimension);
 
       Real tangent_contrib = std::sqrt(first_tangent_contrib * first_tangent_contrib +
 				       second_tangent_contrib * second_tangent_contrib);
 
       normal_contrib = std::max(0., normal_contrib);
 
       Real effective_norm = std::sqrt(normal_contrib * normal_contrib
 				      + tangent_contrib * tangent_contrib / beta / beta);
 
       if (effective_norm < sigma_c) continue;
 
       if (!Math::are_float_equal(effective_norm,
 				 sigma_c_eff(cohesive_element.element
 					     * nb_quad_per_facet + q))) {
 	std::cout << "Insertion tractions do not match" << std::endl;
 	finalize();
 	return EXIT_FAILURE;
       }
     }
   }
   finalize();
   return EXIT_SUCCESS;
 }
diff --git a/test/test_model/test_solid_mechanics_model/test_cohesive/test_parallel_cohesive/test_cohesive_parallel_extrinsic/test_cohesive_parallel_extrinsic_tetrahedron_displacement.cc b/test/test_model/test_solid_mechanics_model/test_cohesive/test_parallel_cohesive/test_cohesive_parallel_extrinsic/test_cohesive_parallel_extrinsic_tetrahedron_displacement.cc
index 2abbd0b12..70404b8ef 100644
--- a/test/test_model/test_solid_mechanics_model/test_cohesive/test_parallel_cohesive/test_cohesive_parallel_extrinsic/test_cohesive_parallel_extrinsic_tetrahedron_displacement.cc
+++ b/test/test_model/test_solid_mechanics_model/test_cohesive/test_parallel_cohesive/test_cohesive_parallel_extrinsic/test_cohesive_parallel_extrinsic_tetrahedron_displacement.cc
@@ -1,395 +1,395 @@
 /**
  * @file   test_cohesive_parallel_extrinsic_tetrahedron_displacement.cc
  *
  * @author Marco Vocialta <marco.vocialta@epfl.ch>
  *
  *
  * @brief  Displacement test for 3D cohesive elements
  *
  * @section LICENSE
  *
  * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  */
 
 /* -------------------------------------------------------------------------- */
 
 /* -------------------------------------------------------------------------- */
 #include "solid_mechanics_model_cohesive.hh"
 #include "dumper_paraview.hh"
 #include "material_cohesive_linear.hh"
 
 #ifdef AKANTU_USE_IOHELPER
 #  include "dumper_paraview.hh"
 #endif
 
 /* -------------------------------------------------------------------------- */
 using namespace akantu;
 
 bool checkDisplacement(SolidMechanicsModelCohesive & model,
 		       ElementType type,
 		       std::ofstream & error_output,
 		       UInt step,
 		       bool barycenters);
 
 int main(int argc, char *argv[]) {
   initialize("material.dat", argc, argv);
 
   debug::setDebugLevel(dblWarning);
 
   const UInt max_steps = 500;
   Math::setTolerance(1.e-12);
 
   UInt spatial_dimension = 3;
   ElementType type = _tetrahedron_10;
 
   Mesh mesh(spatial_dimension);
 
-  StaticCommunicator & comm = StaticCommunicator::getStaticCommunicator();
+  const auto & comm = Communicator::getStaticCommunicator();
   Int psize = comm.getNbProc();
   Int prank = comm.whoAmI();
 
   akantu::MeshPartition * partition = NULL;
   if(prank == 0) {
     // Read the mesh
     mesh.read("tetrahedron.msh");
 
     /// partition the mesh
     partition = new MeshPartitionScotch(mesh, spatial_dimension);
     //    debug::setDebugLevel(dblDump);
     partition->partitionate(psize);
     //    debug::setDebugLevel(dblWarning);
   }
 
   SolidMechanicsModelCohesive model(mesh);
 
   model.initParallel(partition, NULL, true);
 
   // debug::setDebugLevel(dblDump);
   // std::cout << mesh << std::endl;
   // debug::setDebugLevel(dblWarning);
 
   model.initFull(SolidMechanicsModelCohesiveOptions(_explicit_lumped_mass, true));
 
   /* ------------------------------------------------------------------------ */
   /* Facet part                                                               */
   /* ------------------------------------------------------------------------ */
 
   // Array<Real> limits(spatial_dimension, 2);
   // limits(0, 0) = -0.01;
   // limits(0, 1) = 0.01;
   // limits(1, 0) = -100;
   // limits(1, 1) = 100;
   // limits(2, 0) = -100;
   // limits(2, 1) = 100;
 
   // model.enableFacetsCheckOnArea(limits);
 
   /* ------------------------------------------------------------------------ */
   /* End of facet part                                                        */
   /* ------------------------------------------------------------------------ */
 
   // debug::setDebugLevel(dblDump);
   // std::cout << mesh_facets << std::endl;
   // debug::setDebugLevel(dblWarning);
 
   Real time_step = model.getStableTimeStep()*0.1;
   model.setTimeStep(time_step);
   std::cout << "Time step: " << time_step << std::endl;
 
   model.assembleMassLumped();
 
 
   Array<Real> & position = mesh.getNodes();
   Array<Real> & velocity = model.getVelocity();
   Array<bool> & boundary = model.getBlockedDOFs();
   Array<Real> & displacement = model.getDisplacement();
   //  const Array<Real> & residual = model.getResidual();
 
   UInt nb_nodes = mesh.getNbNodes();
 
   /// boundary conditions
   for (UInt n = 0; n < nb_nodes; ++n) {
     if (position(n, 0) > 0.99 || position(n, 0) < -0.99) {
       for (UInt dim = 0; dim < spatial_dimension; ++dim) {
 	boundary(n, dim) = true;
       }
     }
 
     if (position(n, 0) > 0.99 || position(n, 0) < -0.99) {
       for (UInt dim = 0; dim < spatial_dimension; ++dim) {
 	boundary(n, dim) = true;
       }
     }
   }
 
 // #if defined (AKANTU_DEBUG_TOOLS)
 //   Vector<Real> facet_center(spatial_dimension);
 //   facet_center(0) =  0;
 //   facet_center(1) = -0.16666667;
 //   facet_center(2) =  0.5;
 
 //   debug::element_manager.setMesh(mesh);
 //   debug::element_manager.addModule(debug::_dm_material_cohesive);
 //   debug::element_manager.addModule(debug::_dm_debug_tools);
 //   //debug::element_manager.addModule(debug::_dm_integrator);
 // #endif
 
   /// initial conditions
   Real loading_rate = 1;
   Real disp_update = loading_rate * time_step;
   for (UInt n = 0; n < nb_nodes; ++n) {
     velocity(n, 0) = loading_rate * position(n, 0);
     velocity(n, 1) = loading_rate * position(n, 0);
   }
 
   model.synchronizeBoundaries();
   model.updateResidual();
 
   std::stringstream paraview_output;
   paraview_output << "extrinsic_parallel_tetrahedron_" << psize;
 
   model.setBaseName(paraview_output.str());
   model.addDumpFieldVector("displacement");
   model.addDumpFieldVector("velocity"    );
   model.addDumpFieldVector("acceleration");
   model.addDumpFieldVector("residual"    );
   model.addDumpFieldTensor("stress");
   model.addDumpFieldTensor("grad_u");
   model.addDumpField("partitions");
   //  model.getDumper().getDumper().setMode(iohelper::BASE64);
   model.dump();
 
 
   model.setBaseNameToDumper("cohesive elements",
 			    paraview_output.str()+"_cohesive_elements");
   model.addDumpFieldVectorToDumper("cohesive elements", "displacement");
   model.addDumpFieldToDumper("cohesive elements", "damage");
   model.dump("cohesive elements");
 
 
   std::stringstream error_stream;
   error_stream << "error" << ".csv";
   std::ofstream error_output;
   error_output.open(error_stream.str().c_str());
   error_output << "# Step, Average, Max, Min" << std::endl;
 
   if (checkDisplacement(model, type, error_output, 0, true)) {}
 
   /// Main loop
   for (UInt s = 1; s <= max_steps; ++s) {
 
     /// update displacement on extreme nodes
     for (UInt n = 0; n < mesh.getNbNodes(); ++n) {
       if (position(n, 0) > 0.99 || position(n, 0) < -0.99) {
 	displacement(n, 0) += disp_update * position(n, 0);
 	displacement(n, 1) += disp_update * position(n, 0);
       }
     }
 
     model.checkCohesiveStress();
 
     model.solveStep();
 
     if(s % 100 == 0) {
       if(prank == 0) std::cout << "passing step " << s << "/" << max_steps << std::endl;
     }
   }
 
   model.dump();
   model.dump("cohesive elements");
 
   if (!checkDisplacement(model, type, error_output, max_steps, false)) {
     finalize();
     return EXIT_FAILURE;
   }
 
   finalize();
   return EXIT_SUCCESS;
 }
 
 bool checkDisplacement(SolidMechanicsModelCohesive & model,
 		       ElementType type,
 		       std::ofstream & error_output,
 		       UInt step,
 		       bool barycenters) {
 
   Mesh & mesh = model.getMesh();
   UInt spatial_dimension = mesh.getSpatialDimension();
   const Array<UInt> & connectivity = mesh.getConnectivity(type);
   const Array<Real> & displacement = model.getDisplacement();
   UInt nb_element = mesh.getNbElement(type);
   UInt nb_nodes_per_elem = Mesh::getNbNodesPerElement(type);
 
-  StaticCommunicator & comm = StaticCommunicator::getStaticCommunicator();
+  const auto & comm = Communicator::getStaticCommunicator();
   Int psize = comm.getNbProc();
   Int prank = comm.whoAmI();
 
   if (psize == 1) {
     std::stringstream displacement_file;
     displacement_file << "displacement/displacement_"
 		      << std::setfill('0') << std::setw(6)
 		      << step;
     std::ofstream displacement_output;
     displacement_output.open(displacement_file.str().c_str());
 
     for (UInt el = 0; el < nb_element; ++el) {
       for (UInt n = 0; n < nb_nodes_per_elem; ++n) {
 	UInt node = connectivity(el, n);
 
 	for (UInt dim = 0; dim < spatial_dimension; ++dim) {
 	  displacement_output << std::setprecision(15)
 			      << displacement(node, dim) << " ";
 	}
 	displacement_output << std::endl;
       }
     }
 
     displacement_output.close();
 
     if (barycenters) {
       std::stringstream barycenter_file;
       barycenter_file << "displacement/barycenters";
       std::ofstream barycenter_output;
       barycenter_output.open(barycenter_file.str().c_str());
 
       Element element(type, 0);
       Vector<Real> bary(spatial_dimension);
 
       for (UInt el = 0; el < nb_element; ++el) {
 	element.element = el;
 	mesh.getBarycenter(element, bary);
 
 	for (UInt dim = 0; dim < spatial_dimension; ++dim) {
 	  barycenter_output << std::setprecision(15)
 			    << bary(dim) << " ";
 	}
 	barycenter_output << std::endl;
       }
 
       barycenter_output.close();
     }
   }
   else {
 
     if (barycenters) return true;
 
     /// read data
     std::stringstream displacement_file;
     displacement_file << "displacement/displacement_"
 		      << std::setfill('0') << std::setw(6)
 		      << step;
     std::ifstream displacement_input;
     displacement_input.open(displacement_file.str().c_str());
 
     Array<Real> displacement_serial(0, spatial_dimension);
     Vector<Real> disp_tmp(spatial_dimension);
 
     while (displacement_input.good()) {
       for (UInt i = 0; i < spatial_dimension; ++i)
 	displacement_input >> disp_tmp(i);
 
       displacement_serial.push_back(disp_tmp);
     }
 
     std::stringstream barycenter_file;
     barycenter_file << "displacement/barycenters";
     std::ifstream barycenter_input;
     barycenter_input.open(barycenter_file.str().c_str());
 
     Array<Real> barycenter_serial(0, spatial_dimension);
 
     while (barycenter_input.good()) {
       for (UInt dim = 0; dim < spatial_dimension; ++dim)
 	barycenter_input >> disp_tmp(dim);
 
       barycenter_serial.push_back(disp_tmp);
     }
 
     Element element(type, 0);
     Vector<Real> bary(spatial_dimension);
 
     Array<Real>::iterator<Vector<Real> > it;
     Array<Real>::iterator<Vector<Real> > begin
       = barycenter_serial.begin(spatial_dimension);
     Array<Real>::iterator<Vector<Real> > end
       = barycenter_serial.end(spatial_dimension);
 
     Array<Real>::const_iterator<Vector<Real> > disp_it;
     Array<Real>::iterator<Vector<Real> > disp_serial_it;
 
     Vector<Real> difference(spatial_dimension);
     Array<Real> error;
 
     /// compute error
     for (UInt el = 0; el < nb_element; ++el) {
       element.element = el;
       mesh.getBarycenter(element, bary);
 
       /// find element
       for (it = begin; it != end; ++it) {
 	UInt matched_dim = 0;
 
 	while (matched_dim < spatial_dimension &&
 	       Math::are_float_equal(bary(matched_dim), (*it)(matched_dim)))
 	  ++matched_dim;
 
 	if (matched_dim == spatial_dimension) break;
       }
 
       if (it == end) {
 	std::cout << "Element barycenter not found!" << std::endl;
 	return false;
       }
 
       UInt matched_el = it - begin;
 
       disp_serial_it = displacement_serial.begin(spatial_dimension)
 	+ matched_el * nb_nodes_per_elem;
 
       for (UInt n = 0; n < nb_nodes_per_elem; ++n, ++disp_serial_it) {
 	UInt node = connectivity(el, n);
 	if (!mesh.isLocalOrMasterNode(node)) continue;
 
 	disp_it = displacement.begin(spatial_dimension) + node;
 
 	difference = *disp_it;
 	difference -= *disp_serial_it;
 
 	error.push_back(difference.norm());
       }
     }
 
     /// compute average error
     Real average_error = std::accumulate(error.begin(), error.end(), 0.);
     comm.allReduce(&average_error, 1, _so_sum);
 
     UInt error_size = error.getSize();
     comm.allReduce(&error_size, 1, _so_sum);
 
     average_error /= error_size;
 
     /// compute maximum and minimum
     Real max_error = *std::max_element(error.begin(), error.end());
     comm.allReduce(&max_error, 1, _so_max);
 
     Real min_error = *std::min_element(error.begin(), error.end());
     comm.allReduce(&min_error, 1, _so_min);
 
     /// output data
     if (prank == 0) {
       error_output << step << ", "
 		   << average_error << ", "
 		   << max_error << ", "
 		   << min_error << std::endl;
     }
 
     if (max_error > 1.e-9) {
       std::cout << "Displacement error is too big!" << std::endl;
       return false;
     }
   }
 
   return true;
 }
diff --git a/test/test_model/test_solid_mechanics_model/test_cohesive/test_parallel_cohesive/test_cohesive_parallel_extrinsic_IG_TG/test_cohesive_parallel_extrinsic_IG_TG.cc b/test/test_model/test_solid_mechanics_model/test_cohesive/test_parallel_cohesive/test_cohesive_parallel_extrinsic_IG_TG/test_cohesive_parallel_extrinsic_IG_TG.cc
index 84d56d478..e5aba2874 100644
--- a/test/test_model/test_solid_mechanics_model/test_cohesive/test_parallel_cohesive/test_cohesive_parallel_extrinsic_IG_TG/test_cohesive_parallel_extrinsic_IG_TG.cc
+++ b/test/test_model/test_solid_mechanics_model/test_cohesive/test_parallel_cohesive/test_cohesive_parallel_extrinsic_IG_TG/test_cohesive_parallel_extrinsic_IG_TG.cc
@@ -1,295 +1,295 @@
 /**
  * @file   test_cohesive_parallel_extrinsic_IG_TG.cc
  *
  * @author Seyedeh Mohadeseh Taheri Mousavi <mohadeseh.taherimousavi@epfl.ch>
  * @author Marco Vocialta <marco.vocialta@epfl.ch>
  *
  *
  * @brief  Test for considering different cohesive properties for
  * intergranular (IG) and transgranular (TG) fractures in extrinsic
  * cohesive elements
  *
  * @section LICENSE
  *
  * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  */
 
 /* -------------------------------------------------------------------------- */
 
 #include <limits>
 #include <fstream>
 #include <iostream>
 
 
 /* -------------------------------------------------------------------------- */
 #include "solid_mechanics_model_cohesive.hh"
 #include "material_cohesive_linear.hh"
 /* -------------------------------------------------------------------------- */
 
 using namespace akantu;
 
 class MultiGrainMaterialSelector : public DefaultMaterialCohesiveSelector {
 public:
   MultiGrainMaterialSelector(const SolidMechanicsModelCohesive & model, const ID & transgranular_id, const ID & intergranular_id) :
     DefaultMaterialCohesiveSelector(model),
     transgranular_id(transgranular_id),
     intergranular_id(intergranular_id),
     model(model),
     mesh(model.getMesh()),
     mesh_facets(model.getMeshFacets()),
     spatial_dimension(model.getSpatialDimension()),
     nb_IG(0), nb_TG(0) {
   }
 
   UInt 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);
 
       const Element & el1 = element_to_subelement[0];
       const Element & el2 = element_to_subelement[1];
 
       UInt grain_id1 = mesh.getData<UInt>("tag_0", el1.type, el1.ghost_type)(el1.element);
       if(el2 != ElementNull) {
 	UInt grain_id2 = mesh.getData<UInt>("tag_0", el2.type, el2.ghost_type)(el2.element);
 	if (grain_id1 == grain_id2){
 	  //transgranular = 0 indicator
 	  nb_TG++;
 	  return model.getMaterialIndex(transgranular_id);
 	} else  {
 	  //intergranular = 1 indicator
 	  nb_IG++;
 	  return model.getMaterialIndex(intergranular_id);
 	}
       } else {
 	//transgranular = 0 indicator
 	nb_TG++;
 	return model.getMaterialIndex(transgranular_id);
       }
     } else {
       return DefaultMaterialCohesiveSelector::operator()(element);
     }
   }
 
 private:
   ID transgranular_id, intergranular_id;
   const SolidMechanicsModelCohesive & model;
   const Mesh & mesh;
   const Mesh & mesh_facets;
   UInt spatial_dimension;
 
   UInt nb_IG;
   UInt nb_TG;
 };
 
 /* -------------------------------------------------------------------------- */
 void limitInsertion(SolidMechanicsModelCohesive & model) {
 
   Real tolerance = 0.1;
 
   const Mesh & mesh = model.getMesh();
   const Mesh & mesh_facets = model.getMeshFacets();
   CohesiveElementInserter & inserter = model.getElementInserter();
 
   UInt spatial_dimension = mesh.getSpatialDimension();
   Vector<Real> bary_facet(spatial_dimension);
 
   for (ghost_type_t::iterator gt = ghost_type_t::begin();
        gt != ghost_type_t::end();
        ++gt) {
     GhostType ghost_type = *gt;
 
     Mesh::type_iterator it  = mesh_facets.firstType(spatial_dimension - 1, ghost_type);
     Mesh::type_iterator end = mesh_facets.lastType(spatial_dimension - 1, ghost_type);
     for(; it != end; ++it) {
       ElementType type = *it;
       Array<bool> & f_check = inserter.getCheckFacets(type, ghost_type);
       UInt nb_facet = mesh_facets.getNbElement(type, ghost_type);
 
       for (UInt f = 0; f < nb_facet; ++f) {
 	if (f_check(f)) {
 
 	  mesh_facets.getBarycenter(f, type, bary_facet.storage(), ghost_type);
 
 	  if ( !(bary_facet(0) > -tolerance && bary_facet(0) < tolerance) &&
 	       !(bary_facet(1) > -tolerance && bary_facet(1) < tolerance) )
 	    f_check(f) = false;
 	}
       }
     }
   }
 
   model.updateAutomaticInsertion();
 }
 
 
 int main(int argc, char *argv[]) {
   initialize("material.dat", argc, argv);
 
   debug::setDebugLevel(dblWarning);
 
   const UInt spatial_dimension = 2;
   const UInt max_steps = 600;
 
   Mesh mesh(spatial_dimension);
 
-  StaticCommunicator & comm = StaticCommunicator::getStaticCommunicator();
+  const auto & comm = Communicator::getStaticCommunicator();
   Int psize = comm.getNbProc();
   Int prank = comm.whoAmI();
 
   akantu::MeshPartition * partition = NULL;
   if(prank == 0) {
     mesh.read("square.msh");
     partition = new MeshPartitionScotch(mesh, spatial_dimension);
     partition->partitionate(psize);
   }
 
   SolidMechanicsModelCohesive model(mesh);
 
   /// model initialization
   model.initParallel(partition, NULL, true);
 
   delete partition;
 
   MultiGrainMaterialSelector material_selector(model, "TG_cohesive", "IG_cohesive");
   model.setMaterialSelector(material_selector);
   model.initFull(SolidMechanicsModelCohesiveOptions(_explicit_lumped_mass, true, false));
 
   Real time_step = model.getStableTimeStep()*0.1;
   model.setTimeStep(time_step);
   //  std::cout << "Time step: " << time_step << std::endl;
 
   limitInsertion(model);
 
   //  std::cout << mesh << std::endl;
 
   Array<Real> & position = mesh.getNodes();
   Array<Real> & velocity = model.getVelocity();
   Array<bool> & boundary = model.getBlockedDOFs();
   Array<Real> & displacement = model.getDisplacement();
   //  const Array<Real> & residual = model.getResidual();
 
   UInt nb_nodes = mesh.getNbNodes();
 
   /// boundary conditions
   for (UInt n = 0; n < nb_nodes; ++n) {
     if (position(n, 1) > 0.99|| position(n, 1) < -0.99)
       boundary(n, 1) = true;
 
     if (position(n, 0) > 0.99 || position(n, 0) < -0.99)
       boundary(n, 0) = true;
   }
 
   model.synchronizeBoundaries();
   model.updateResidual();
 
   model.setBaseName("extrinsic");
   model.addDumpFieldVector("displacement");
   model.addDumpField("velocity"    );
   model.addDumpField("acceleration");
   model.addDumpField("residual"    );
   model.addDumpField("stress");
   model.addDumpField("strain");
   model.addDumpField("partitions");
 
   model.setBaseNameToDumper("cohesive elements", "extrinsic_cohesive");
   model.addDumpFieldVectorToDumper("cohesive elements", "displacement");
   model.addDumpFieldToDumper("cohesive elements", "damage");
 
   model.dump();
   model.dump("cohesive elements");
 
   /// initial conditions
   Real loading_rate = 0.1;
   // bar_height  = 2
   Real VI = loading_rate * 2* 0.5;
   for (UInt n = 0; n < nb_nodes; ++n) {
     velocity(n, 1) = loading_rate * position(n, 1);
     velocity(n, 0) = loading_rate * position(n, 0);
   }
 
   // std::ofstream edis("edis.txt");
   // std::ofstream erev("erev.txt");
 
   //  Array<Real> & residual = model.getResidual();
   //  model.dump();
   //  const Array<Real> & stress = model.getMaterial(0).getStress(type);
   Real dispy = 0;
   // UInt nb_coh_elem = 0;
 
   /// Main loop
   for (UInt s = 1; s <= max_steps; ++s) {
     dispy += VI * time_step;
     /// update displacement on extreme nodes
     for (UInt n = 0; n < mesh.getNbNodes(); ++n) {
       if (position(n, 1) > 0.99){
 	displacement(n, 1) = dispy;
 	velocity(n,1) = VI;}
       if (position(n, 1) < -0.99){
 	displacement(n, 1) = -dispy;
 	velocity(n,1) = -VI;}
       if (position(n, 0) > 0.99){
 	displacement(n, 0) = dispy;
 	velocity(n,0) = VI;}
       if (position(n, 0) < -0.99){
 	displacement(n, 0) = -dispy;
 	velocity(n,0) = -VI;}
     }
 
     model.checkCohesiveStress();
 
     model.solveStep();
 
     if(s % 10 == 0) {
       if(prank == 0)
 	std::cout << "passing step " << s << "/" << max_steps << std::endl;
 
       // model.dump();
       // model.dump("cohesive elements");
     }
 
     // Real Ed = model.getEnergy("dissipated");
 
     // edis << s << " "
     //	 << Ed << std::endl;
 
     // erev << s << " "
     //	 << Er << std::endl;
   }
 
   model.dump();
   model.dump("cohesive elements");
 
   // edis.close();
   // erev.close();
 
   //  mesh.write("mesh_final.msh");
 
   Real Ed = model.getEnergy("dissipated");
 
   Real Edt = 40;
 
   if(prank == 0)
     std::cout << Ed << " " << Edt << std::endl;
 
   if (Ed < Edt * 0.99 || Ed > Edt * 1.01 || std::isnan(Ed)) {
     if(prank == 0)
       std::cout << "The dissipated energy is incorrect" << std::endl;
     finalize();
     return EXIT_FAILURE;
   }
 
   // for (UInt n = 0; n < position.getSize(); ++n) {
   //   for (UInt s = 0; s < spatial_dimension; ++s) {
   //     position(n, s) += displacement(n, s);
   //   }
   // }
 
 
   finalize();
 
   if(prank == 0)
     std::cout << "OK: test_cohesive_extrinsic_IG_TG was passed!" << std::endl;
   return EXIT_SUCCESS;
 }
diff --git a/test/test_model/test_solid_mechanics_model/test_cohesive/test_parallel_cohesive/test_cohesive_parallel_insertion/test_cohesive_parallel_insertion_along_physical_surfaces.cc b/test/test_model/test_solid_mechanics_model/test_cohesive/test_parallel_cohesive/test_cohesive_parallel_insertion/test_cohesive_parallel_insertion_along_physical_surfaces.cc
index 74d52adbf..b37321c1b 100644
--- a/test/test_model/test_solid_mechanics_model/test_cohesive/test_parallel_cohesive/test_cohesive_parallel_insertion/test_cohesive_parallel_insertion_along_physical_surfaces.cc
+++ b/test/test_model/test_solid_mechanics_model/test_cohesive/test_parallel_cohesive/test_cohesive_parallel_insertion/test_cohesive_parallel_insertion_along_physical_surfaces.cc
@@ -1,118 +1,118 @@
 /**
  * @file   test_cohesive_insertion_along_physical_surfaces.cc
  * @author Fabian Barras <fabian.barras@epfl.ch>
  * @date   Fri Aug  7 09:07:44 2015
  *
  * @brief Test parallel intrinsic insertion of cohesive elements along physical surfaces 
  *
  * @section LICENSE
  *
  * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free  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 <limits>
 #include <fstream>
 #include <iostream>
 /* -------------------------------------------------------------------------- */
 #include "aka_common.hh"
 #include "mesh.hh"
 #include "mesh_io.hh"
 #include "mesh_io_msh.hh"
 #include "mesh_utils.hh"
 #include "solid_mechanics_model_cohesive.hh"
 #include "material.hh"
 #include "material_cohesive.hh"
 
 /* -------------------------------------------------------------------------- */
 using namespace akantu;
 
 int main(int argc, char *argv[]) {
 
   initialize("input_file.dat", argc, argv);
 
   Math::setTolerance(1e-15);
   
   const UInt spatial_dimension = 3;
 
   Mesh mesh(spatial_dimension);
 
-  StaticCommunicator & comm = StaticCommunicator::getStaticCommunicator();
+  const auto & comm = Communicator::getStaticCommunicator();
   Int psize = comm.getNbProc();
   Int prank = comm.whoAmI();
   akantu::MeshPartition * partition = NULL;
 
   if(prank==0){
 
     mesh.read("3d_spherical_inclusion.msh");
   
     partition = new MeshPartitionScotch(mesh, spatial_dimension);
     partition->partitionate(psize);
 
   }
   SolidMechanicsModelCohesive model(mesh);
   model.initParallel(partition);
   mesh.createGroupsFromMeshData<std::string>("physical_names");
   model.initFull(SolidMechanicsModelCohesiveOptions(_static));
   
   std::vector<std::string> surfaces_name = {"interface", "coh1", "coh2", "coh3", "coh4", "coh5"};
   UInt nb_surf = surfaces_name.size();
 
   for (ghost_type_t::iterator gt = ghost_type_t::begin();  gt != ghost_type_t::end(); ++gt) {
 
     std::string ghost_str;
   
     if(*gt == 1) ghost_str = "ghost";
     else ghost_str = "not ghost";
 
     Mesh::type_iterator it  = mesh.firstType(spatial_dimension, *gt, _ek_cohesive);
     Mesh::type_iterator end = mesh.lastType(spatial_dimension, *gt, _ek_cohesive);
 
     for(; it != end; ++it) {
       
       Array<UInt> & material_id = mesh.getMeshFacets().getData<UInt>("physical_names")(mesh.getFacetType(*it), *gt);
       
       for (UInt i = 0; i < nb_surf; ++i) {
 
 	UInt expected_insertion = 0;
       
 	for(UInt m = 0; m<material_id.getSize();++m) {
 	  if(material_id(m)==model.SolidMechanicsModel::getMaterialIndex(surfaces_name[i])) ++expected_insertion;
 	}
 	
 	UInt inserted_elements;
 
 	inserted_elements = model.getMaterial(surfaces_name[i]).getElementFilter()(*it,*gt).getSize();
 	if (expected_insertion != inserted_elements) { 
 	  std::cerr << std::endl << "!!! Mismatch in insertion of surface named " 
 		    << surfaces_name[i] << " in proc n° " << prank
 		    << " --> " << inserted_elements << " inserted elements of type " << ghost_str  
 		    << " out of " 
 		    << expected_insertion << std::endl;
 	  return EXIT_FAILURE;
 	}
       }      
     }
   }
 
   model.assembleStiffnessMatrix();
 
   finalize();
 
   return EXIT_SUCCESS;
 }
diff --git a/test/test_model/test_solid_mechanics_model/test_cohesive/test_parallel_cohesive/test_cohesive_parallel_insertion/test_cohesive_parallel_intrinsic_implicit_insertion.cc b/test/test_model/test_solid_mechanics_model/test_cohesive/test_parallel_cohesive/test_cohesive_parallel_insertion/test_cohesive_parallel_intrinsic_implicit_insertion.cc
index d6643a5a1..ad60ef2ef 100644
--- a/test/test_model/test_solid_mechanics_model/test_cohesive/test_parallel_cohesive/test_cohesive_parallel_insertion/test_cohesive_parallel_intrinsic_implicit_insertion.cc
+++ b/test/test_model/test_solid_mechanics_model/test_cohesive/test_parallel_cohesive/test_cohesive_parallel_insertion/test_cohesive_parallel_intrinsic_implicit_insertion.cc
@@ -1,270 +1,270 @@
 /**
  * @file   test_cohesive_parallel_intrinsic_implicit_insertion.cc
  * @author Fabian Barras <fabian.barras@epfl.ch>
  * @date   Fri Aug  5 17:05:59 2016
  *
  * @brief  Verifying the proper insertion and synchronization of intrinsic cohesive elements
  *
  * @section LICENSE
  *
  * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free  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 <limits>
 #include <fstream>
 #include <iostream>
 /* -------------------------------------------------------------------------- */
 #include "aka_common.hh"
 #include "mesh.hh"
 #include "mesh_io.hh"
 #include "mesh_io_msh.hh"
 #include "mesh_utils.hh"
 #include "solid_mechanics_model_cohesive.hh"
 #include "material.hh"
 #include "material_cohesive.hh"
 /* -------------------------------------------------------------------------- */
 using namespace akantu;
 std::ofstream output;
 
 /* -------------------------------------------------------------------------- */
 void printMeshContent(Mesh & mesh) {
 
-  StaticCommunicator & comm = StaticCommunicator::getStaticCommunicator();
+  const auto & comm = Communicator::getStaticCommunicator();
   Int prank = comm.whoAmI();
   comm.barrier();
   for (ghost_type_t::iterator gt = ghost_type_t::begin();  gt != ghost_type_t::end(); ++gt) {
     
     Mesh::type_iterator first = mesh.firstType(_all_dimensions, *gt, _ek_not_defined);
     Mesh::type_iterator last  = mesh.lastType(_all_dimensions, *gt, _ek_not_defined);
     
     for(; first != last; ++first) {
       UInt nb_element = mesh.getNbElement(*first,*gt);
       output << std::endl
 		<< "Element type: " << *first << ", " << *gt << ": "  
 		<< nb_element << " in the mesh of processor " << prank << std::endl;
       Array<UInt> & conn = mesh.getConnectivity(*first,*gt);
       for (UInt i = 0; i < conn.getSize(); ++i) {
 	output << "Element no " << i << " ";
 	for (UInt j = 0; j < conn.getNbComponent(); ++j) {
 	  output << conn(i,j) << " ";
 	}
 	output << std::endl;
       }
     }
   }
 }
 
 /* -------------------------------------------------------------------------- */
 void printNodeList(Mesh & mesh) {
 
   Array<double> & nodes = mesh.getNodes();
 
   output << "Number of nodes: " << mesh.getNbNodes()<< std::endl;
   for (UInt i = 0; i < mesh.getNbNodes(); ++i) {
     output<<"Node # " << i 
 	     << ", x-coord: " 
 	     << nodes(i,0)
 	     << ", y-coord: "
 	     << nodes(i,1)
 	     << ", of type: " << mesh.getNodeType(i) << std::endl;
   }
   output << std::endl;
 }
 
 /* -------------------------------------------------------------------------- */
 void getGlobalIDs(Mesh & mesh) {
 
   const Array<UInt> & glob_id = mesh.getGlobalNodesIds();
   if(&glob_id) {
     output << "Global nodes ID: " << std::endl;
     for (UInt i = 0; i < glob_id.getSize(); ++i) {
       output << i << " " << glob_id(i) << std::endl;
     }
   }
   output << std::endl;
 }
 
 /* -------------------------------------------------------------------------- */
 void printSynchroinfo(Mesh & mesh, const DistributedSynchronizer & synch) {
 
-  StaticCommunicator & comm = StaticCommunicator::getStaticCommunicator();
+  const auto & comm = Communicator::getStaticCommunicator();
   Int prank = comm.whoAmI();
   Int psize = comm.getNbProc();
 
   if(comm.getNbProc()==1)
     return;
  
   for (Int p = 0; p < psize; ++p) {
 
     if (p==prank)
       continue;
     output << "From processor " << prank << " to processor " << p << std::endl;
     const Array<Element> & sele = *(synch.getSendElement()+p);
     output << " Sending element(s): " << std::endl;
     for (UInt i = 0; i < sele.getSize(); ++i) {
       output << sele(i) << std::endl;
     }
 
     const Array<Element> & rele = *(synch.getReceiveElement()+p);
     output <<" Receiving element(s): " << std::endl;
     for (UInt i = 0; i < rele.getSize(); ++i) {
       output << rele(i) << std::endl;
     }
   }
   output << std::endl;
 }
 
 /* -------------------------------------------------------------------------- */
 void printDOF(SolidMechanicsModelCohesive & model) {
 
-  StaticCommunicator & comm = StaticCommunicator::getStaticCommunicator();
+  const auto & comm = Communicator::getStaticCommunicator();
   if(comm.getNbProc()==1)
     return;
   Int prank = comm.whoAmI();
 
   const DOFSynchronizer & dof =  model.getDOFSynchronizer();
 
   output << "Number of global dofs " << dof.getNbGlobalDOFs() << " for processor "<< prank << std::endl;
 
   const Array<UInt> & dof_global_ids = dof.getDOFGlobalIDs();
 
   for (UInt i = 0; i < dof_global_ids.getSize(); ++i) {
     
     output << "Local dof " << i << ", global id: " << dof_global_ids(i) << std::endl;
   }
   output << std::endl;
 }
 
 /* -------------------------------------------------------------------------- */
 int main(int argc, char *argv[]) {
 
   std::string input_file = "input_file_iii.dat"; 
   std::string mesh_file = "2d_basic_interface.msh";
   std::string dir = "output_dir/";
 
   initialize(input_file, argc, argv);
   
   debug::setDebugLevel(dbl0);
 
   const UInt spatial_dimension = 2;
 
   Mesh mesh(spatial_dimension);
 
-  StaticCommunicator & comm = StaticCommunicator::getStaticCommunicator();
+  const auto & comm = Communicator::getStaticCommunicator();
   Int psize = comm.getNbProc();
   Int prank = comm.whoAmI();
   akantu::MeshPartition * partition = NULL;
 
   std::stringstream filename;
   filename << dir.c_str() << "output_from_proc_" << prank << "_out_of_" << psize << ".out";
   output.open(filename.str());
 
   if(prank==0){
 
     mesh.read(mesh_file);    
     partition = new MeshPartitionScotch(mesh, spatial_dimension);
     partition->partitionate(psize);
 
     const ElementTypeMapArray<UInt> & partitions = partition->getPartitions();
 
     output << "The root processor read the mesh." << std::endl 
 	      << "Only GMSH physical objects are created in the mesh." <<std::endl;
 
     for (ghost_type_t::iterator gt = ghost_type_t::begin();  gt != ghost_type_t::end(); ++gt) {
    
       Mesh::type_iterator first = mesh.firstType(_all_dimensions, *gt);
       Mesh::type_iterator last  = mesh.lastType(_all_dimensions, *gt);
 
       for(; first != last; ++first) {
   
 	output << "Element type: " << *first << " ghost type: " << *gt << std::endl; 
 	UInt nb_element = mesh.getNbElement(*first,*gt);
 	output << nb_element << " to partitionate between " << psize << " processsors" << std::endl;
     
 	Array<UInt> part = partitions(*first, *gt);
 
 	for (UInt i = 0; i < part.getSize(); ++i) {
 	  output << i << " " << part(i) << std::endl;
 	}
       }
     }
     
     output << "Nodes are also read and set with type -1 (normal node)" << std::endl;
     printNodeList(mesh);
   }
  
   SolidMechanicsModelCohesive model(mesh);
   
   output << "Before initParallel(), non-root processors have empty Mesh object" << std::endl;
   printMeshContent(mesh);
   
   model.initParallel(partition);
   
   output << "After initParallel(), Mesh object on each processor is a local partionated mesh containing ghost elements" << std::endl;
   printMeshContent(mesh);
   
   output << "Nodes are also partionated and new node types are defined:" << std::endl;
   printNodeList(mesh);
   output << "-3: pure ghost node -> not a local node" << std::endl
 	 << "-2: master node -> node shared with other processor(s) -> local and global node" <<std::endl
 	 << ">0: slave node -> -> node shared with other processor(s) -> only local node (its id is the rank of the processor owning the master node)" <<std::endl;
   
   output << "Each local node has a corresponding global id used during assembly: " <<std::endl;
   getGlobalIDs(mesh);
   
   Mesh & mesh_facets = mesh.getMeshFacets();  
   
   output << "Within cohesive element model, initParallel() creates a second Mesh object usually called mesh_facet" << std::endl
 	 << "This Mesh object contains all sub-dimensional elements where potential cohesive element can be inserted" << std::endl;
   printMeshContent(mesh_facets);
   
   
   
   const DistributedSynchronizer & synch_model = model.getSynchronizer();  
   output << "The distributed synchronizer of solid mechanics model is used to synchronize fields with ghost element:" << std::endl;
   printSynchroinfo(mesh, synch_model);
   
   mesh.createGroupsFromMeshData<std::string>("physical_names");
   model.initFull(SolidMechanicsModelCohesiveOptions(_static));
   
   output << "In case of insertion along physical objects, cohesive elements are created during initFull()" << std::endl;
   output << "Elements list after insertion" << std::endl;
   printMeshContent(mesh);
   
   output << "Node list after insertion: (Total number of nodes " << mesh.getNbNodes()<< ")"<< std::endl;
   printNodeList(mesh);
   
   output << "Node global ids after insertion: (Total number of nodes " << mesh.getNbGlobalNodes()<< ")"<< std::endl;
   getGlobalIDs(mesh);
   
   const DistributedSynchronizer & coh_synch_model = *(model.getCohesiveSynchronizer());
   output << "Solid mechanics model cohesive has its own distributed synchronizer to handle ghost cohesive element:" << std::endl;
   printSynchroinfo(mesh, coh_synch_model);
 
   output << "A synchronizer dedicated to degrees of freedom (DOFs) is used by the solver to build matrices in parallel:" 
 	 << std::endl
 	 << "This DOFSynchronizer is built based on nodes global id " << std::endl;
   printDOF(model);
   
   output.close();
  
   finalize();
 
   return EXIT_SUCCESS;  
 }
diff --git a/test/test_model/test_solid_mechanics_model/test_cohesive/test_parallel_cohesive/test_cohesive_parallel_intrinsic/test_cohesive_parallel_intrinsic.cc b/test/test_model/test_solid_mechanics_model/test_cohesive/test_parallel_cohesive/test_cohesive_parallel_intrinsic/test_cohesive_parallel_intrinsic.cc
index 9bd19c8b7..f4d854bf0 100644
--- a/test/test_model/test_solid_mechanics_model/test_cohesive/test_parallel_cohesive/test_cohesive_parallel_intrinsic/test_cohesive_parallel_intrinsic.cc
+++ b/test/test_model/test_solid_mechanics_model/test_cohesive/test_parallel_cohesive/test_cohesive_parallel_intrinsic/test_cohesive_parallel_intrinsic.cc
@@ -1,160 +1,160 @@
 /**
  * @file   test_cohesive_parallel_intrinsic.cc
  *
  * @author Marco Vocialta <marco.vocialta@epfl.ch>
  *
  *
  * @brief  parallel test for intrinsic cohesive elements
  *
  * @section LICENSE
  *
  * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  */
 
 /* -------------------------------------------------------------------------- */
 #include "solid_mechanics_model_cohesive.hh"
 
 /* -------------------------------------------------------------------------- */
 using namespace akantu;
 
 int main(int argc, char *argv[]) {
   initialize("material.dat", argc, argv);
 
   const UInt max_steps = 350;
 
   UInt spatial_dimension = 2;
   Mesh mesh(spatial_dimension);
 
-  StaticCommunicator & comm = StaticCommunicator::getStaticCommunicator();
+  const auto & comm = Communicator::getStaticCommunicator();
   Int psize = comm.getNbProc();
   Int prank = comm.whoAmI();
 
   akantu::MeshPartition * partition = NULL;
   if(prank == 0) {
     // Read the mesh
     mesh.read("mesh.msh");
 
     // /// insert cohesive elements
     // CohesiveElementInserter inserter(mesh);
     // inserter.setLimit('x', -0.26, -0.24);
     // inserter.insertIntrinsicElements();
 
     /// partition the mesh
     partition = new MeshPartitionScotch(mesh, spatial_dimension);
     //    debug::setDebugLevel(dblDump);
     partition->partitionate(psize);
     //   debug::setDebugLevel(dblWarning);
   }
 
   SolidMechanicsModelCohesive model(mesh);
 
   model.initParallel(partition);
 
   model.initFull();
 
   model.limitInsertion(_x, -0.26, -0.24);
   model.insertIntrinsicElements();
 
   debug::setDebugLevel(dblDump);
   std::cout << mesh << std::endl;
   debug::setDebugLevel(dblWarning);
 
   Real time_step = model.getStableTimeStep()*0.8;
   model.setTimeStep(time_step);
   //  std::cout << "Time step: " << time_step << std::endl;
 
   model.assembleMassLumped();
 
 
   Array<Real> & position = mesh.getNodes();
   Array<Real> & velocity = model.getVelocity();
   Array<bool> & boundary = model.getBlockedDOFs();
   //  Array<Real> & displacement = model.getDisplacement();
   //  const Array<Real> & residual = model.getResidual();
 
   UInt nb_nodes = mesh.getNbNodes();
   Real epsilon = std::numeric_limits<Real>::epsilon();
 
   for (UInt n = 0; n < nb_nodes; ++n) {
     if (std::abs(position(n, 0) - 1.) < epsilon)
       boundary(n, 0) = true;
   }
 
   model.synchronizeBoundaries();
   model.updateResidual();
 
   model.setBaseName("intrinsic_parallel");
   model.addDumpFieldVector("displacement");
   model.addDumpField("velocity"    );
   model.addDumpField("acceleration");
   model.addDumpField("residual"    );
   model.addDumpField("stress");
   model.addDumpField("strain");
   model.addDumpField("partitions");
   model.addDumpField("force");
   model.dump();
 
   
   model.setBaseNameToDumper("cohesive elements",
 			    "cohesive_elements_parallel_intrinsic");
   model.addDumpFieldVectorToDumper("cohesive elements", "displacement");
   model.dump("cohesive elements");
 
   /// initial conditions
   Real loading_rate = .2;
   for (UInt n = 0; n < nb_nodes; ++n) {
     velocity(n, 0) = loading_rate * position(n, 0);
   }
 
   /// Main loop
   for (UInt s = 1; s <= max_steps; ++s) {
 
     model.solveStep();
 
     if(s % 20 == 0) {
       model.dump();
       model.dump("cohesive elements");
       if(prank == 0) std::cout << "passing step " << s << "/" << max_steps << std::endl;
     }
 
     // // update displacement
     // for (UInt n = 0; n < nb_nodes; ++n) {
     //   if (position(n, 1) + displacement(n, 1) > 0) {
     // 	displacement(n, 0) -= 0.01;
     //   }
     // }
 
     //    Real Ed = dynamic_cast<MaterialCohesive&> (model.getMaterial(1)).getDissipatedEnergy();
     //    Real Er = dynamic_cast<MaterialCohesive&> (model.getMaterial(1)).getReversibleEnergy();
 
     // edis << s << " "
     // 	 << Ed << std::endl;
 
     // erev << s << " "
     // 	 << Er << std::endl;
 
   }
 
   // edis.close();
   // erev.close();
 
   Real Ed = model.getEnergy("dissipated");
 
   Real Edt = 2 * sqrt(2);
 
 
   if(prank == 0) {
     std::cout << Ed << " " << Edt << std::endl;
 
     if (std::abs((Ed - Edt) / Edt) > 0.01 || std::isnan(Ed)) {
       std::cout << "The dissipated energy is incorrect" << std::endl;
       return EXIT_FAILURE;
     }
   }
 
   finalize();
   if(prank == 0) std::cout << "OK: Test passed!" << std::endl;
   return EXIT_SUCCESS;
 }
diff --git a/test/test_model/test_solid_mechanics_model/test_cohesive/test_parallel_cohesive/test_cohesive_parallel_intrinsic/test_cohesive_parallel_intrinsic_tetrahedron.cc b/test/test_model/test_solid_mechanics_model/test_cohesive/test_parallel_cohesive/test_cohesive_parallel_intrinsic/test_cohesive_parallel_intrinsic_tetrahedron.cc
index f6607255d..983104b34 100644
--- a/test/test_model/test_solid_mechanics_model/test_cohesive/test_parallel_cohesive/test_cohesive_parallel_intrinsic/test_cohesive_parallel_intrinsic_tetrahedron.cc
+++ b/test/test_model/test_solid_mechanics_model/test_cohesive/test_parallel_cohesive/test_cohesive_parallel_intrinsic/test_cohesive_parallel_intrinsic_tetrahedron.cc
@@ -1,704 +1,704 @@
 /**
  * @file   test_cohesive_parallel_intrinsic_tetrahedron.cc
  *
  * @author Marco Vocialta <marco.vocialta@epfl.ch>
  *
  *
  * @brief  Test for 3D intrinsic cohesive elements simulation in parallel
  *
  * @section LICENSE
  *
  * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  */
 
 /* -------------------------------------------------------------------------- */
 #include "solid_mechanics_model_cohesive.hh"
 #include "dumper_paraview.hh"
 #include "material_cohesive.hh"
 
 /* -------------------------------------------------------------------------- */
 using namespace akantu;
 
 void updateDisplacement(SolidMechanicsModelCohesive & model,
 			const ElementTypeMapArray<UInt> & elements,
 			Vector<Real> & increment);
 
 bool checkTractions(SolidMechanicsModelCohesive & model,
 		    Vector<Real> & opening,
 		    Vector<Real> & theoretical_traction,
 		    Matrix<Real> & rotation);
 
 void findNodesToCheck(const Mesh & mesh,
 		      const ElementTypeMapArray<UInt> & elements,
 		      Array<UInt> & nodes_to_check,
 		      Int psize);
 
 bool checkEquilibrium(const Mesh & mesh,
 		      const Array<Real> & residual);
 
 bool checkResidual(const Array<Real> & residual,
 		   const Vector<Real> & traction,
 		   const Array<UInt> & nodes_to_check,
 		   const Matrix<Real> & rotation);
 
 void findElementsToDisplace(const Mesh & mesh,
 			    ElementTypeMapArray<UInt> & elements);
 
 int main(int argc, char *argv[]) {
   initialize("material_tetrahedron.dat", argc, argv);
 
   const UInt spatial_dimension = 3;
   const UInt max_steps = 60;
   const Real increment_constant = 0.01;
   ElementType type = _tetrahedron_10;
   Math::setTolerance(1.e-10);
 
   Mesh mesh(spatial_dimension);
 
-  StaticCommunicator & comm = StaticCommunicator::getStaticCommunicator();
+  const auto & comm = Communicator::getStaticCommunicator();
   Int psize = comm.getNbProc();
   Int prank = comm.whoAmI();
 
   UInt nb_nodes_to_check_serial = 0;
   UInt total_nb_nodes = 0;
   UInt nb_elements_check_serial = 0;
 
   akantu::MeshPartition * partition = NULL;
   if(prank == 0) {
     // Read the mesh
     mesh.read("tetrahedron.msh");
 
     /// count nodes with zero position
     const Array<Real> & position = mesh.getNodes();
     for (UInt n = 0; n < position.getSize(); ++n) {
       if (std::abs(position(n, 0) - 0.) < 1e-6)
 	++nb_nodes_to_check_serial;
     }
 
     // /// insert cohesive elements
     // CohesiveElementInserter inserter(mesh);
     // inserter.setLimit(0, -0.01, 0.01);
     // inserter.insertIntrinsicElements();
 
     /// find nodes to check in serial
     ElementTypeMapArray<UInt> elements_serial("elements_serial", "");
     findElementsToDisplace(mesh, elements_serial);
     nb_elements_check_serial = elements_serial(type).getSize();
 
     total_nb_nodes = mesh.getNbNodes() + nb_nodes_to_check_serial;
 
     /// partition the mesh
     partition = new MeshPartitionScotch(mesh, spatial_dimension);
     debug::setDebugLevel(dblDump);
     partition->partitionate(psize);
     debug::setDebugLevel(dblInfo);
   }
 
   comm.broadcast(&nb_nodes_to_check_serial, 1, 0);
   comm.broadcast(&nb_elements_check_serial, 1, 0);
 
   SolidMechanicsModelCohesive model(mesh);
 
   model.initParallel(partition);
   model.initFull();
 
   model.limitInsertion(_x, -0.01, 0.01);
   model.insertIntrinsicElements();
 
   {
     comm.broadcast(&total_nb_nodes, 1, 0);
 
     Array<Int> nb_local_nodes(psize);
     nb_local_nodes.clear();
 
     for (UInt n = 0; n < mesh.getNbNodes(); ++n) {
       if (mesh.isLocalOrMasterNode(n)) ++nb_local_nodes(prank);
     }
 
     comm.allGather(nb_local_nodes.storage(), 1);
 
     UInt total_nb_nodes_parallel = std::accumulate(nb_local_nodes.begin(),
 						   nb_local_nodes.end(), 0);
 
     Array<UInt> global_nodes_list(total_nb_nodes_parallel);
 
     UInt first_global_node = std::accumulate(nb_local_nodes.begin(),
 					     nb_local_nodes.begin() + prank, 0);
 
     for (UInt n = 0; n < mesh.getNbNodes(); ++n) {
       if (mesh.isLocalOrMasterNode(n)) {
 	global_nodes_list(first_global_node) = mesh.getNodeGlobalId(n);
 	++first_global_node;
       }
     }
 
     comm.allGatherV(global_nodes_list.storage(), nb_local_nodes.storage());
 
     if (prank == 0)
       std::cout << "Maximum node index: "
 		<< *(std::max_element(global_nodes_list.begin(),
 				      global_nodes_list.end())) << std::endl;
 
     Array<UInt> repeated_nodes;
     repeated_nodes.resize(0);
 
     for (UInt n = 0; n < total_nb_nodes_parallel; ++n) {
       UInt appearances = std::count(global_nodes_list.begin() + n,
 				    global_nodes_list.end(),
 				    global_nodes_list(n));
 
       if (appearances > 1) {
 	std::cout << "Node " << global_nodes_list(n)
 		  << " appears " << appearances << " times" << std::endl;
 
 	std::cout << "  in position: " << n;
 
 	repeated_nodes.push_back(global_nodes_list(n));
 
 	UInt * node_position = global_nodes_list.storage() + n;
 
 	for (UInt i = 1; i < appearances; ++i) {
 	  node_position = std::find(node_position + 1,
 				    global_nodes_list.storage()
 				    + total_nb_nodes_parallel,
 				    global_nodes_list(n));
 
 	  UInt current_index = node_position - global_nodes_list.storage();
 
 	  std::cout << ", " << current_index;
 	}
 	std::cout << std::endl << std::endl;
       }
     }
 
 
     for (UInt n = 0; n < mesh.getNbNodes(); ++n) {
       UInt global_node = mesh.getNodeGlobalId(n);
 
       if (std::find(repeated_nodes.begin(), repeated_nodes.end(), global_node)
 	  != repeated_nodes.end()) {
 	std::cout << "Repeated global node " << global_node
 		  << " corresponds to local node " << n << std::endl;
       }
     }
 
 
     if (total_nb_nodes != total_nb_nodes_parallel) {
       if (prank == 0) {
 	std::cout << "Error: total number of nodes is wrong in parallel" << std::endl;
 	std::cout << "Serial: " << total_nb_nodes
 		  << " Parallel: " << total_nb_nodes_parallel << std::endl;
       }
       finalize();
       return EXIT_FAILURE;
     }
   }
 
   model.updateResidual();
 
   model.setBaseName("intrinsic_parallel_tetrahedron");
   model.addDumpFieldVector("displacement");
   model.addDumpField("residual");
   model.addDumpField("partitions");
   model.dump();
 
   model.setBaseNameToDumper("cohesive elements",
 			    "cohesive_elements_parallel_tetrahedron");
   model.addDumpFieldVectorToDumper("cohesive elements", "displacement");
   model.dump("cohesive elements");
 
   /// find elements to displace
   ElementTypeMapArray<UInt> elements("elements", "");
   findElementsToDisplace(mesh, elements);
 
   UInt nb_elements_check = elements(type).getSize();
   comm.allReduce(&nb_elements_check, 1, _so_sum);
 
   if (nb_elements_check != nb_elements_check_serial) {
     if (prank == 0) {
       std::cout << "Error: number of elements to check is wrong" << std::endl;
       std::cout << "Serial: " << nb_elements_check_serial
 		<< " Parallel: " << nb_elements_check << std::endl;
     }
     finalize();
     return EXIT_FAILURE;
   }
 
   /// find nodes to check
   Array<UInt> nodes_to_check;
   findNodesToCheck(mesh, elements, nodes_to_check, psize);
 
   Vector<Int> nodes_to_check_size(psize);
   nodes_to_check_size(prank) = nodes_to_check.getSize();
   comm.allGather(nodes_to_check_size.storage(), 1);
 
   UInt nodes_to_check_global_size = std::accumulate(nodes_to_check_size.storage(),
   						    nodes_to_check_size.storage()
   						    + psize, 0);
 
   if (nodes_to_check_global_size != nb_nodes_to_check_serial) {
     if (prank == 0) {
       std::cout << "Error: number of nodes to check is wrong in parallel" << std::endl;
       std::cout << "Serial: " << nb_nodes_to_check_serial
   		<< " Parallel: " << nodes_to_check_global_size << std::endl;
     }
     finalize();
     return EXIT_FAILURE;
   }
 
   /// rotate mesh
   Real angle = 1.;
 
   Matrix<Real> rotation(spatial_dimension, spatial_dimension);
   rotation.clear();
   rotation(0, 0) = std::cos(angle);
   rotation(0, 1) = std::sin(angle) * -1.;
   rotation(1, 0) = std::sin(angle);
   rotation(1, 1) = std::cos(angle);
   rotation(2, 2) = 1.;
 
 
   Vector<Real> increment_tmp(spatial_dimension);
   for (UInt dim = 0; dim < spatial_dimension; ++dim) {
     increment_tmp(dim) = (dim + 1) * increment_constant;
   }
 
   Vector<Real> increment(spatial_dimension);
   increment.mul<false>(rotation, increment_tmp);
 
   Array<Real> & position = mesh.getNodes();
   Array<Real> position_tmp(position);
 
   Array<Real>::iterator<Vector<Real> > position_it = position.begin(spatial_dimension);
   Array<Real>::iterator<Vector<Real> > position_end = position.end(spatial_dimension);
   Array<Real>::iterator<Vector<Real> > position_tmp_it
     = position_tmp.begin(spatial_dimension);
 
   for (; position_it != position_end; ++position_it, ++position_tmp_it)
     position_it->mul<false>(rotation, *position_tmp_it);
 
   model.dump();
   model.dump("cohesive elements");
 
   updateDisplacement(model, elements, increment);
 
 
   Real theoretical_Ed = 0;
 
   Vector<Real> opening(spatial_dimension);
   Vector<Real> traction(spatial_dimension);
   Vector<Real> opening_old(spatial_dimension);
   Vector<Real> traction_old(spatial_dimension);
 
   opening.clear();
   traction.clear();
   opening_old.clear();
   traction_old.clear();
 
   Vector<Real> Dt(spatial_dimension);
   Vector<Real> Do(spatial_dimension);
 
   const Array<Real> & residual = model.getResidual();
 
   /// Main loop
   for (UInt s = 1; s <= max_steps; ++s) {
 
     model.updateResidual();
 
     opening += increment_tmp;
     if (checkTractions(model, opening, traction, rotation) ||
 	checkEquilibrium(mesh, residual) ||
 	checkResidual(residual, traction, nodes_to_check, rotation)) {
       finalize();
       return EXIT_FAILURE;
     }
 
     /// compute energy
     Do = opening;
     Do -= opening_old;
 
     Dt = traction_old;
     Dt += traction;
 
     theoretical_Ed += .5 * Do.dot(Dt);
 
     opening_old = opening;
     traction_old = traction;
 
 
     updateDisplacement(model, elements, increment);
 
     if(s % 10 == 0) {
       if (prank == 0)
 	std::cout << "passing step " << s << "/" << max_steps << std::endl;
       model.dump();
       model.dump("cohesive elements");
     }
   }
 
   model.dump();
   model.dump("cohesive elements");
 
   Real Ed = model.getEnergy("dissipated");
 
   theoretical_Ed *= 4.;
 
   if (prank == 0)
     std::cout << "Dissipated energy: " << Ed
 	      << ", theoretical value: " << theoretical_Ed << std::endl;
 
   if (!Math::are_float_equal(Ed, theoretical_Ed) || std::isnan(Ed)) {
 
     if (prank == 0)
       std::cout << "Error: the dissipated energy is incorrect" << std::endl;
 
     finalize();
     return EXIT_FAILURE;
   }
 
   finalize();
   if(prank == 0) std::cout << "OK: Test passed!" << std::endl;
   return EXIT_SUCCESS;
 }
 
 /* -------------------------------------------------------------------------- */
 
 void updateDisplacement(SolidMechanicsModelCohesive & model,
 			const ElementTypeMapArray<UInt> & elements,
 			Vector<Real> & increment) {
 
   UInt spatial_dimension = model.getSpatialDimension();
   Mesh & mesh = model.getFEEngine().getMesh();
   UInt nb_nodes = mesh.getNbNodes();
 
   Array<Real> & displacement = model.getDisplacement();
   Array<bool> update(nb_nodes);
   update.clear();
 
   for (ghost_type_t::iterator gt = ghost_type_t::begin();
        gt != ghost_type_t::end();
        ++gt) {
 
     GhostType ghost_type = *gt;
     Mesh::type_iterator it   = mesh.firstType(spatial_dimension, ghost_type);
     Mesh::type_iterator last = mesh.lastType(spatial_dimension, ghost_type);
 
     for (; it != last; ++it) {
       ElementType type = *it;
 
       const Array<UInt> & elem = elements(type, ghost_type);
       const Array<UInt> & connectivity = mesh.getConnectivity(type, ghost_type);
       UInt nb_nodes_per_element = connectivity.getNbComponent();
 
       for (UInt el = 0; el < elem.getSize(); ++el) {
 	for (UInt n = 0; n < nb_nodes_per_element; ++n) {
 	  UInt node = connectivity(elem(el), n);
 	  if (!update(node)) {
 	    Vector<Real> node_disp(displacement.storage() + node * spatial_dimension,
 				   spatial_dimension);
 	    node_disp += increment;
 	    update(node) = true;
 	  }
 	}
       }
     }
   }
 }
 
 /* -------------------------------------------------------------------------- */
 
 bool checkTractions(SolidMechanicsModelCohesive & model,
 		    Vector<Real> & opening,
 		    Vector<Real> & theoretical_traction,
 		    Matrix<Real> & rotation) {
   UInt spatial_dimension = model.getSpatialDimension();
   const Mesh & mesh = model.getMesh();
 
   const MaterialCohesive & mat_cohesive
     = dynamic_cast < const MaterialCohesive & > (model.getMaterial(1));
 
   Real sigma_c = mat_cohesive.getParam< RandomInternalField<Real, FacetInternalField> >("sigma_c");
   const Real beta = mat_cohesive.getParam<Real>("beta");
   const Real G_cI = mat_cohesive.getParam<Real>("G_c");
   //  Real G_cII = mat_cohesive.getParam<Real>("G_cII");
   const Real delta_0 = mat_cohesive.getParam<Real>("delta_0");
   const Real kappa = mat_cohesive.getParam<Real>("kappa");
   Real delta_c = 2 * G_cI / sigma_c;
   sigma_c *= delta_c / (delta_c - delta_0);
 
   Vector<Real> normal_opening(spatial_dimension);
   normal_opening.clear();
   normal_opening(0) = opening(0);
   Real normal_opening_norm = normal_opening.norm();
 
   Vector<Real> tangential_opening(spatial_dimension);
   tangential_opening.clear();
   for (UInt dim = 1; dim < spatial_dimension; ++dim)
     tangential_opening(dim) = opening(dim);
 
   Real tangential_opening_norm = tangential_opening.norm();
 
   Real beta2_kappa2 = beta * beta/kappa/kappa;
   Real beta2_kappa  = beta * beta/kappa;
 
   Real delta = std::sqrt(tangential_opening_norm * tangential_opening_norm
 			 * beta2_kappa2 +
 			 normal_opening_norm * normal_opening_norm);
 
   delta = std::max(delta, delta_0);
 
   Real theoretical_damage = std::min(delta / delta_c, 1.);
 
   if (Math::are_float_equal(theoretical_damage, 1.))
     theoretical_traction.clear();
   else {
     theoretical_traction  = tangential_opening;
     theoretical_traction *= beta2_kappa;
     theoretical_traction += normal_opening;
     theoretical_traction *= sigma_c / delta * (1. - theoretical_damage);
   }
 
   Vector<Real> theoretical_traction_rotated(spatial_dimension);
   theoretical_traction_rotated.mul<false>(rotation, theoretical_traction);
 
   // adjust damage
   theoretical_damage = std::max((delta - delta_0) / (delta_c - delta_0), 0.);
   theoretical_damage = std::min(theoretical_damage, 1.);
 
   for (ghost_type_t::iterator gt = ghost_type_t::begin();
        gt != ghost_type_t::end();
        ++gt) {
 
     GhostType ghost_type = *gt;
     Mesh::type_iterator it
       = mesh.firstType(spatial_dimension, ghost_type, _ek_cohesive);
     Mesh::type_iterator last
     = mesh.lastType(spatial_dimension, ghost_type, _ek_cohesive);
     
     for (; it != last; ++it) {
       ElementType type = *it;
 
       const Array<Real> & traction = mat_cohesive.getTraction(type, ghost_type);
       const Array<Real> & damage = mat_cohesive.getDamage(type, ghost_type);
 
       UInt nb_quad_per_el
 	= model.getFEEngine("CohesiveFEEngine").getNbIntegrationPoints(type);
       UInt nb_element = model.getMesh().getNbElement(type, ghost_type);
       UInt tot_nb_quad = nb_element * nb_quad_per_el;
 
       for (UInt q = 0; q < tot_nb_quad; ++q) {
 	for (UInt dim = 0; dim < spatial_dimension; ++dim) {
 	  if (!Math::are_float_equal(std::abs(theoretical_traction_rotated(dim)),
 				     std::abs(traction(q, dim)))) {
 	    std::cout << "Error: tractions are incorrect" << std::endl;
 	    return 1;
 	  }
 	}
 
 	if (ghost_type == _not_ghost)
 	  if (!Math::are_float_equal(theoretical_damage, damage(q))) {
 	    std::cout << "Error: damage is incorrect" << std::endl;
 	    return 1;
 	}
       }
     }
   }
 
   return 0;
 }
 
 /* -------------------------------------------------------------------------- */
 
 void findNodesToCheck(const Mesh & mesh,
 		      const ElementTypeMapArray<UInt> & elements,
 		      Array<UInt> & nodes_to_check,
 		      Int psize) {
 
-  StaticCommunicator & comm = StaticCommunicator::getStaticCommunicator();
+  const auto & comm = Communicator::getStaticCommunicator();
   Int prank = comm.whoAmI();
 
   nodes_to_check.resize(0);
 
   Array<UInt> global_nodes_to_check;
 
   UInt spatial_dimension = mesh.getSpatialDimension();
   const Array<Real> & position = mesh.getNodes();
 
   UInt nb_nodes = position.getSize();
 
   Array<bool> checked_nodes(nb_nodes);
   checked_nodes.clear();
 
   Mesh::type_iterator it = mesh.firstType(spatial_dimension);
   Mesh::type_iterator last = mesh.lastType(spatial_dimension);
 
   for (; it != last; ++it) {
     ElementType type = *it;
 
     const Array<UInt> & elem = elements(type);
     const Array<UInt> & connectivity = mesh.getConnectivity(type);
     UInt nb_nodes_per_elem = connectivity.getNbComponent();
 
     for (UInt el = 0; el < elem.getSize(); ++el) {
 
       UInt element = elem(el);
       Vector<UInt> conn_el(connectivity.storage() + nb_nodes_per_elem * element,
 			   nb_nodes_per_elem);
 
       for (UInt n = 0; n < nb_nodes_per_elem; ++n) {
 	UInt node = conn_el(n);
 	if (std::abs(position(node, 0) - 0.) < 1.e-6
 	    && !checked_nodes(node)) {
 	  checked_nodes(node) = true;
 	  nodes_to_check.push_back(node);
 	  global_nodes_to_check.push_back(mesh.getNodeGlobalId(node));
 	}
       }
     }
   }
 
   std::vector<CommunicationRequest *> requests;
 
   for (Int p = prank + 1; p < psize; ++p) {
     requests.push_back(comm.asyncSend(global_nodes_to_check.storage(),
 				      global_nodes_to_check.getSize(),
 				      p, prank));
   }
 
   Array<UInt> recv_nodes;
 
   for (Int p = 0; p < prank; ++p) {
     CommunicationStatus status;
     comm.probe<UInt>(p, p, status);
 
     UInt recv_nodes_size = recv_nodes.getSize();
     recv_nodes.resize(recv_nodes_size + status.getSize());
 
     comm.receive(recv_nodes.storage() + recv_nodes_size, status.getSize(), p, p);
   }
 
   comm.waitAll(requests);
   comm.freeCommunicationRequest(requests);
 
   for (UInt i = 0; i < recv_nodes.getSize(); ++i) {
     Array<UInt>::iterator<UInt> node_position
       = std::find(global_nodes_to_check.begin(),
 		  global_nodes_to_check.end(),
 		  recv_nodes(i));
 
     if (node_position != global_nodes_to_check.end()) {
       UInt index = node_position - global_nodes_to_check.begin();
       nodes_to_check.erase(index);
       global_nodes_to_check.erase(index);
     }
   }
 }
 
 /* -------------------------------------------------------------------------- */
 
 bool checkEquilibrium(const Mesh & mesh,
 		      const Array<Real> & residual) {
 
   UInt spatial_dimension = residual.getNbComponent();
 
   Vector<Real> residual_sum(spatial_dimension);
   residual_sum.clear();
 
   Array<Real>::const_iterator<Vector<Real> > res_it
     = residual.begin(spatial_dimension);
 
   for (UInt n = 0; n < residual.getSize(); ++n, ++res_it) {
     if (mesh.isLocalOrMasterNode(n))
       residual_sum += *res_it;
   }
 
-  StaticCommunicator & comm = StaticCommunicator::getStaticCommunicator();
+  const auto & comm = Communicator::getStaticCommunicator();
   comm.allReduce(residual_sum.storage(), spatial_dimension, _so_sum);
 
   for (UInt s = 0; s < spatial_dimension; ++s) {
     if (!Math::are_float_equal(residual_sum(s), 0.)) {
 
       if (comm.whoAmI() == 0)
 	std::cout << "Error: system is not in equilibrium!" << std::endl;
 
       return 1;
     }
   }
 
   return 0;
 }
 
 /* -------------------------------------------------------------------------- */
 
 bool checkResidual(const Array<Real> & residual,
 		   const Vector<Real> & traction,
 		   const Array<UInt> & nodes_to_check,
 		   const Matrix<Real> & rotation) {
 
   UInt spatial_dimension = residual.getNbComponent();
 
   Vector<Real> total_force(spatial_dimension);
   total_force.clear();
 
   for (UInt n = 0; n < nodes_to_check.getSize(); ++n) {
     UInt node = nodes_to_check(n);
 
     Vector<Real> res(residual.storage() + node * spatial_dimension,
 		     spatial_dimension);
 
     total_force += res;
   }
 
-  StaticCommunicator & comm = StaticCommunicator::getStaticCommunicator();
+  const auto & comm = Communicator::getStaticCommunicator();
   comm.allReduce(total_force.storage(), spatial_dimension, _so_sum);
 
   Vector<Real> theoretical_total_force(spatial_dimension);
   theoretical_total_force.mul<false>(rotation, traction);
   theoretical_total_force *= -1 * 2 * 2;
 
   for (UInt s = 0; s < spatial_dimension; ++s) {
     if (!Math::are_float_equal(total_force(s), theoretical_total_force(s))) {
 
       if (comm.whoAmI() == 0)
 	std::cout << "Error: total force isn't correct!" << std::endl;
 
       return 1;
     }
   }
 
   return 0;
 }
 
 /* -------------------------------------------------------------------------- */
 
 void findElementsToDisplace(const Mesh & mesh,
 			    ElementTypeMapArray<UInt> & elements) {
   UInt spatial_dimension = mesh.getSpatialDimension();
 
   mesh.initElementTypeMapArray(elements, 1, spatial_dimension);
 
   Vector<Real> bary(spatial_dimension);
 
   for (ghost_type_t::iterator gt = ghost_type_t::begin();
        gt != ghost_type_t::end();
        ++gt) {
 
     GhostType ghost_type = *gt;
     Mesh::type_iterator it   = mesh.firstType(spatial_dimension, ghost_type);
     Mesh::type_iterator last = mesh.lastType(spatial_dimension, ghost_type);
 
     for (; it != last; ++it) {
       ElementType type = *it;
 
       Array<UInt> & elem = elements(type, ghost_type);
       UInt nb_element = mesh.getNbElement(type, ghost_type);
 
       for (UInt el = 0; el < nb_element; ++el) {
 	mesh.getBarycenter(el, type, bary.storage(), ghost_type);
 	if (bary(0) > 0.0001) elem.push_back(el);
       }
     }
   }
 }
diff --git a/test/test_solver/test_petsc_matrix_apply_boundary.cc b/test/test_solver/test_petsc_matrix_apply_boundary.cc
index 57b7eeb7b..c89eebdf2 100644
--- a/test/test_solver/test_petsc_matrix_apply_boundary.cc
+++ b/test/test_solver/test_petsc_matrix_apply_boundary.cc
@@ -1,144 +1,144 @@
 /**
  * @file   test_petsc_matrix_apply_boundary.cc
  *
  * @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
  *
  * @date creation: Mon Oct 13 2014
  * @date last modification: Wed Oct 28 2015
  *
  * @brief  test the applyBoundary method of the PETScMatrix class
  *
  * @section LICENSE
  *
  * Copyright (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne) Laboratory
  * (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free  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 <cstdlib>
 /* -------------------------------------------------------------------------- */
-#include "static_communicator.hh"
+#include "communicator.hh"
 #include "aka_common.hh"
 #include "aka_csr.hh"
 #include "mesh.hh"
 #include "mesh_io.hh"
 #include "mesh_utils.hh"
 #include "element_synchronizer.hh"
 #include "petsc_matrix.hh"
 #include "fe_engine.hh"
 #include "dof_synchronizer.hh"
 
 #include "mesh_partition_scotch.hh"
 
 using namespace akantu;
 int main(int argc, char *argv[]) {
 
   initialize(argc, argv);
   const ElementType element_type = _triangle_3;
   const GhostType ghost_type = _not_ghost; 
   UInt spatial_dimension = 2;
 
 
-  StaticCommunicator & comm = akantu::StaticCommunicator::getStaticCommunicator();
+  const auto & comm = akantu::Communicator::getStaticCommunicator();
   Int psize = comm.getNbProc();
   Int prank = comm.whoAmI();
 
   /// read the mesh and partition it
   Mesh mesh(spatial_dimension);
 
   /* ------------------------------------------------------------------------ */
   /* Parallel initialization                                                  */
   /* ------------------------------------------------------------------------ */
   ElementSynchronizer * communicator = NULL;
   if(prank == 0) {
     /// creation mesh
     mesh.read("triangle.msh");
     MeshPartitionScotch * partition = new MeshPartitionScotch(mesh, spatial_dimension);
     partition->partitionate(psize);
     communicator = ElementSynchronizer::createDistributedSynchronizerMesh(mesh, partition);
     delete partition;
   } else {
     communicator = ElementSynchronizer::createDistributedSynchronizerMesh(mesh, NULL);
   }
   
 
   FEEngine *fem = new FEEngineTemplate<IntegratorGauss,ShapeLagrange,_ek_regular>(mesh, spatial_dimension, "my_fem");
 
   DOFSynchronizer dof_synchronizer(mesh, spatial_dimension);
   UInt nb_global_nodes = mesh.getNbGlobalNodes();
 
   dof_synchronizer.initGlobalDOFEquationNumbers();
 
   // fill the matrix with 
   UInt nb_element = mesh.getNbElement(element_type);
   UInt nb_nodes_per_element = mesh.getNbNodesPerElement(element_type);
   UInt nb_dofs_per_element = spatial_dimension * nb_nodes_per_element;
   SparseMatrix K(nb_global_nodes * spatial_dimension, _symmetric);
   K.buildProfile(mesh, dof_synchronizer, spatial_dimension);
   Matrix<Real> element_input(nb_dofs_per_element, nb_dofs_per_element, 1);
   Array<Real> K_e = Array<Real>(nb_element, nb_dofs_per_element * nb_dofs_per_element, "K_e");
   Array<Real>::matrix_iterator K_e_it = K_e.begin(nb_dofs_per_element, nb_dofs_per_element);
   Array<Real>::matrix_iterator K_e_end = K_e.end(nb_dofs_per_element, nb_dofs_per_element);
 
   for(; K_e_it != K_e_end; ++K_e_it)
     *K_e_it = element_input;
 
   // assemble the test matrix
   fem->assembleMatrix(K_e, K, spatial_dimension, element_type, ghost_type);
 
   // create petsc matrix
   PETScMatrix petsc_matrix(nb_global_nodes * spatial_dimension, _symmetric);
 
   petsc_matrix.buildProfile(mesh, dof_synchronizer, spatial_dimension);
   
   // add stiffness matrix to petsc matrix
   petsc_matrix.add(K, 1);
   
   // create boundary array: block all dofs
   UInt nb_nodes = mesh.getNbNodes();
   Array<bool> boundary = Array<bool>(nb_nodes, spatial_dimension, true);
 
   // apply boundary
   petsc_matrix.applyBoundary(boundary);
 
   // test if all entries except the diagonal ones have been zeroed
   Real test_passed = 0;
 
   for (UInt i = 0; i < nb_nodes * spatial_dimension; ++i) { 
     if (dof_synchronizer.isLocalOrMasterDOF(i)) {
       for (UInt j = 0; j < nb_nodes * spatial_dimension; ++j) {
 	if (dof_synchronizer.isLocalOrMasterDOF(j)) {
 	  if (i == j)
 	    test_passed += petsc_matrix(i, j) - 1;
 	  else
 	    test_passed += petsc_matrix(i, j) - 0;
 	}
       }
     }
   }
 
   if (std::abs(test_passed) > Math::getTolerance()) {
     finalize();
     return EXIT_FAILURE;
   }
   delete communicator;
 
   finalize();
 
   return EXIT_SUCCESS;
 
 }
diff --git a/test/test_solver/test_petsc_matrix_diagonal.cc b/test/test_solver/test_petsc_matrix_diagonal.cc
index c0cb48b96..145105038 100644
--- a/test/test_solver/test_petsc_matrix_diagonal.cc
+++ b/test/test_solver/test_petsc_matrix_diagonal.cc
@@ -1,151 +1,151 @@
 /**
  * @file   test_petsc_matrix_diagonal.cc
  *
  * @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
  *
  * @date creation: Mon Oct 13 2014
  * @date last modification: Fri Jan 15 2016
  *
  * @brief  test the connectivity is correctly represented in the PETScMatrix
  *
  * @section LICENSE
  *
  * Copyright (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne) Laboratory
  * (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free  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 <iostream>
 
 /* -------------------------------------------------------------------------- */
-#include "static_communicator.hh"
+#include "communicator.hh"
 #include "aka_common.hh"
 #include "aka_csr.hh"
 #include "mesh.hh"
 #include "mesh_io.hh"
 #include "mesh_utils.hh"
 #include "element_synchronizer.hh"
 #include "petsc_matrix.hh"
 #include "fe_engine.hh"
 #include "dof_synchronizer.hh"
 #include "dumper_paraview.hh"
 #include "mesh_partition_scotch.hh"
 
 using namespace akantu;
 int main(int argc, char *argv[]) {
 
   initialize(argc, argv);
   const ElementType element_type = _triangle_3;
   const GhostType ghost_type = _not_ghost; 
   UInt spatial_dimension = 2;
 
 
-  StaticCommunicator & comm = akantu::StaticCommunicator::getStaticCommunicator();
+  const auto & comm = akantu::Communicator::getStaticCommunicator();
   Int psize = comm.getNbProc();
   Int prank = comm.whoAmI();
 
   /// read the mesh and partition it
   Mesh mesh(spatial_dimension);
 
   /* ------------------------------------------------------------------------ */
   /* Parallel initialization                                                  */
   /* ------------------------------------------------------------------------ */
   ElementSynchronizer * communicator = NULL;
   if(prank == 0) {
     /// creation mesh
     mesh.read("triangle.msh");
     MeshPartitionScotch * partition = new MeshPartitionScotch(mesh, spatial_dimension);
     partition->partitionate(psize);
     communicator = ElementSynchronizer::createDistributedSynchronizerMesh(mesh, partition);
     delete partition;
   } else {
     communicator = ElementSynchronizer::createDistributedSynchronizerMesh(mesh, NULL);
   }
   
   // DumperParaview mesh_dumper("mesh_dumper");
   // mesh_dumper.registerMesh(mesh, spatial_dimension, _not_ghost);
   // mesh_dumper.dump();
 
   /// initialize the FEEngine and the dof_synchronizer
   FEEngine *fem = new FEEngineTemplate<IntegratorGauss,ShapeLagrange,_ek_regular>(mesh, spatial_dimension, "my_fem");
 
   DOFSynchronizer dof_synchronizer(mesh, spatial_dimension);
   UInt nb_global_nodes = mesh.getNbGlobalNodes();
 
   dof_synchronizer.initGlobalDOFEquationNumbers();
 
   // construct an Akantu sparse matrix, build the profile and fill the matrix for the given mesh 
   UInt nb_element = mesh.getNbElement(element_type);
   UInt nb_nodes_per_element = mesh.getNbNodesPerElement(element_type);
   UInt nb_dofs_per_element = spatial_dimension * nb_nodes_per_element;
   SparseMatrix K_akantu(nb_global_nodes * spatial_dimension, _unsymmetric);
   K_akantu.buildProfile(mesh, dof_synchronizer, spatial_dimension);
   /// use as elemental matrices a matrix with values equal to 1 every where
   Matrix<Real> element_input(nb_dofs_per_element, nb_dofs_per_element, 1.);
   Array<Real> K_e = Array<Real>(nb_element, nb_dofs_per_element * nb_dofs_per_element, "K_e");
   Array<Real>::matrix_iterator K_e_it = K_e.begin(nb_dofs_per_element, nb_dofs_per_element);
   Array<Real>::matrix_iterator K_e_end = K_e.end(nb_dofs_per_element, nb_dofs_per_element);
 
   for(; K_e_it != K_e_end; ++K_e_it)
     *K_e_it = element_input;
 
   // assemble the test matrix
   fem->assembleMatrix(K_e, K_akantu, spatial_dimension, element_type, ghost_type);
   
   /// construct a PETSc matrix
   PETScMatrix K_petsc(nb_global_nodes * spatial_dimension, _unsymmetric);
   /// build the profile of the PETSc matrix for the mesh of this example
   K_petsc.buildProfile(mesh, dof_synchronizer, spatial_dimension);
   /// add an Akantu sparse matrix to a PETSc sparse matrix
   K_petsc.add(K_akantu, 1);
 
   /// check to how many elements each node is connected
   CSR<Element> node_to_elem;
 
   MeshUtils::buildNode2Elements(mesh, node_to_elem, spatial_dimension);
 
   /// test the diagonal of the PETSc matrix: the diagonal entries
   /// of the PETSc matrix correspond to the number of elements
   /// connected to the node of the dof. Note: for an Akantu matrix this is only true for the serial case
   Real error = 0.;
   /// loop over all diagonal values of the matrix
   for (UInt i = 0; i < mesh.getNbNodes(); ++i) { 
     for (UInt j = 0; j < spatial_dimension; ++j) {
       UInt dof = i * spatial_dimension + j;
       /// for PETSc matrix only DOFs on the processor and be accessed
       if (dof_synchronizer.isLocalOrMasterDOF(dof)) {
   	UInt global_dof = dof_synchronizer.getDOFGlobalID(dof);
   	std::cout << "Number of elements connected: " << node_to_elem.getNbCols(i) << std::endl;
 	std::cout << "K_petsc(" << global_dof << "," << global_dof << ")=" << K_petsc(dof,dof) << std::endl; 
 	error += std::abs(K_petsc(dof, dof) - node_to_elem.getNbCols(i));
       }
     }
   }
 
   if(error > Math::getTolerance() ) {
     std::cout << "error in the stiffness matrix!!!" << std::endl;
     finalize();
     return EXIT_FAILURE;
   }
 
   delete communicator;
 
   finalize();
   
   return EXIT_SUCCESS;
 
 }
diff --git a/test/test_solver/test_petsc_matrix_profile.cc b/test/test_solver/test_petsc_matrix_profile.cc
index 35439d340..391f22855 100644
--- a/test/test_solver/test_petsc_matrix_profile.cc
+++ b/test/test_solver/test_petsc_matrix_profile.cc
@@ -1,134 +1,134 @@
 /**
  * @file   test_petsc_matrix_profile.cc
  *
  * @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
  *
  * @date creation: Mon Oct 13 2014
  * @date last modification: Tue Apr 28 2015
  *
  * @brief  test the profile generation of the PETScMatrix class
  *
  * @section LICENSE
  *
  * Copyright (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne) Laboratory
  * (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free  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 <cstdlib>
 #include <fstream>
 /* -------------------------------------------------------------------------- */
-#include "static_communicator.hh"
+#include "communicator.hh"
 #include "aka_common.hh"
 #include "aka_csr.hh"
 #include "mesh.hh"
 #include "mesh_io.hh"
 #include "mesh_utils.hh"
 #include "element_synchronizer.hh"
 #include "petsc_matrix.hh"
 #include "fe_engine.hh"
 #include "dof_synchronizer.hh"
 /// #include "dumper_paraview.hh"
 #include "mesh_partition_scotch.hh"
 
 using namespace akantu;
 int main(int argc, char *argv[]) {
 
   initialize(argc, argv);
   const ElementType element_type = _triangle_3;
   const GhostType ghost_type = _not_ghost; 
   UInt spatial_dimension = 2;
 
 
-  StaticCommunicator & comm = akantu::StaticCommunicator::getStaticCommunicator();
+  const auto & comm = akantu::Communicator::getStaticCommunicator();
   Int psize = comm.getNbProc();
   Int prank = comm.whoAmI();
 
   /// read the mesh and partition it
   Mesh mesh(spatial_dimension);
 
   /* ------------------------------------------------------------------------ */
   /* Parallel initialization                                                  */
   /* ------------------------------------------------------------------------ */
   ElementSynchronizer * communicator = NULL;
   if(prank == 0) {
     /// creation mesh
     mesh.read("square.msh");
     MeshPartitionScotch * partition = new MeshPartitionScotch(mesh, spatial_dimension);
     partition->partitionate(psize);
     communicator = ElementSynchronizer::createDistributedSynchronizerMesh(mesh, partition);
     delete partition;
   } else {
     communicator = ElementSynchronizer::createDistributedSynchronizerMesh(mesh, NULL);
   }
 
   // dump mesh in paraview
   // DumperParaview mesh_dumper("mesh_dumper");
   // mesh_dumper.registerMesh(mesh, spatial_dimension, _not_ghost);
   // mesh_dumper.dump();
 
   /// initialize the FEEngine and the dof_synchronizer
   FEEngine *fem = new FEEngineTemplate<IntegratorGauss,ShapeLagrange,_ek_regular>(mesh, spatial_dimension, "my_fem");
 
   DOFSynchronizer dof_synchronizer(mesh, spatial_dimension);
   UInt nb_global_nodes = mesh.getNbGlobalNodes();
 
   dof_synchronizer.initGlobalDOFEquationNumbers();
 
   // construct an Akantu sparse matrix, build the profile and fill the matrix for the given mesh 
   UInt nb_element = mesh.getNbElement(element_type);
   UInt nb_nodes_per_element = mesh.getNbNodesPerElement(element_type);
   UInt nb_dofs_per_element = spatial_dimension * nb_nodes_per_element;
   SparseMatrix K_akantu(nb_global_nodes * spatial_dimension, _unsymmetric);
   K_akantu.buildProfile(mesh, dof_synchronizer, spatial_dimension);
   /// use as elemental matrices a matrix with values equal to 1 every where
   Matrix<Real> element_input(nb_dofs_per_element, nb_dofs_per_element, 1.);
   Array<Real> K_e = Array<Real>(nb_element, nb_dofs_per_element * nb_dofs_per_element, "K_e");
   Array<Real>::matrix_iterator K_e_it = K_e.begin(nb_dofs_per_element, nb_dofs_per_element);
   Array<Real>::matrix_iterator K_e_end = K_e.end(nb_dofs_per_element, nb_dofs_per_element);
 
   for(; K_e_it != K_e_end; ++K_e_it)
     *K_e_it = element_input;
 
   // assemble the test matrix
   fem->assembleMatrix(K_e, K_akantu, spatial_dimension, element_type, ghost_type);
   
   /// construct a PETSc matrix
   PETScMatrix K_petsc(nb_global_nodes * spatial_dimension, _unsymmetric);
   /// build the profile of the PETSc matrix for the mesh of this example
   K_petsc.buildProfile(mesh, dof_synchronizer, spatial_dimension);
   /// add an Akantu sparse matrix to a PETSc sparse matrix
   K_petsc.add(K_akantu, 1);
 
   /// save the profile
   K_petsc.saveMatrix("profile.txt");
 
   /// print the matrix to screen
   std::ifstream profile;
   profile.open("profile.txt");
   std::string current_line;
   while(getline(profile, current_line))
     std::cout << current_line << std::endl;
   profile.close();
 
   delete communicator;
 
   finalize();
   
   return EXIT_SUCCESS;
 
 }
diff --git a/test/test_solver/test_petsc_matrix_profile_parallel.cc b/test/test_solver/test_petsc_matrix_profile_parallel.cc
index 5d750d5d1..b638a3c23 100644
--- a/test/test_solver/test_petsc_matrix_profile_parallel.cc
+++ b/test/test_solver/test_petsc_matrix_profile_parallel.cc
@@ -1,135 +1,135 @@
 /**
  * @file   test_petsc_matrix_profile_parallel.cc
  *
  * @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
  *
  * @date creation: Mon Oct 13 2014
  * @date last modification: Tue Apr 28 2015
  *
  * @brief  test the profile generation of the PETScMatrix class in parallel
  *
  * @section LICENSE
  *
  * Copyright (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne) Laboratory
  * (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free  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 <cstdlib>
 #include <fstream>
 /* -------------------------------------------------------------------------- */
-#include "static_communicator.hh"
+#include "communicator.hh"
 #include "aka_common.hh"
 #include "aka_csr.hh"
 #include "mesh.hh"
 #include "mesh_io.hh"
 #include "mesh_utils.hh"
 #include "element_synchronizer.hh"
 #include "petsc_matrix.hh"
 #include "fe_engine.hh"
 #include "dof_synchronizer.hh"
 /// #include "dumper_paraview.hh"
 #include "mesh_partition_scotch.hh"
 
 using namespace akantu;
 int main(int argc, char *argv[]) {
 
   initialize(argc, argv);
   const ElementType element_type = _triangle_3;
   const GhostType ghost_type = _not_ghost; 
   UInt spatial_dimension = 2;
 
 
-  StaticCommunicator & comm = akantu::StaticCommunicator::getStaticCommunicator();
+  const auto & comm = akantu::Communicator::getStaticCommunicator();
   Int psize = comm.getNbProc();
   Int prank = comm.whoAmI();
 
   /// read the mesh and partition it
   Mesh mesh(spatial_dimension);
 
   /* ------------------------------------------------------------------------ */
   /* Parallel initialization                                                  */
   /* ------------------------------------------------------------------------ */
   ElementSynchronizer * communicator = NULL;
   if(prank == 0) {
     /// creation mesh
     mesh.read("square.msh");
     MeshPartitionScotch * partition = new MeshPartitionScotch(mesh, spatial_dimension);
     partition->partitionate(psize);
     communicator = ElementSynchronizer::createDistributedSynchronizerMesh(mesh, partition);
     delete partition;
   } else {
     communicator = ElementSynchronizer::createDistributedSynchronizerMesh(mesh, NULL);
   }
 
   // dump mesh in paraview
   // DumperParaview mesh_dumper("mesh_dumper");
   // mesh_dumper.registerMesh(mesh, spatial_dimension, _not_ghost);
   // mesh_dumper.dump();
 
   /// initialize the FEEngine and the dof_synchronizer
   FEEngine *fem = new FEEngineTemplate<IntegratorGauss,ShapeLagrange,_ek_regular>(mesh, spatial_dimension, "my_fem");
 
   DOFSynchronizer dof_synchronizer(mesh, spatial_dimension);
   UInt nb_global_nodes = mesh.getNbGlobalNodes();
 
   dof_synchronizer.initGlobalDOFEquationNumbers();
 
   // construct an Akantu sparse matrix, build the profile and fill the matrix for the given mesh 
   UInt nb_element = mesh.getNbElement(element_type);
   UInt nb_nodes_per_element = mesh.getNbNodesPerElement(element_type);
   UInt nb_dofs_per_element = spatial_dimension * nb_nodes_per_element;
   SparseMatrix K_akantu(nb_global_nodes * spatial_dimension, _unsymmetric);
   K_akantu.buildProfile(mesh, dof_synchronizer, spatial_dimension);
   /// use as elemental matrices a matrix with values equal to 1 every where
   Matrix<Real> element_input(nb_dofs_per_element, nb_dofs_per_element, 1.);
   Array<Real> K_e = Array<Real>(nb_element, nb_dofs_per_element * nb_dofs_per_element, "K_e");
   Array<Real>::matrix_iterator K_e_it = K_e.begin(nb_dofs_per_element, nb_dofs_per_element);
   Array<Real>::matrix_iterator K_e_end = K_e.end(nb_dofs_per_element, nb_dofs_per_element);
 
   for(; K_e_it != K_e_end; ++K_e_it)
     *K_e_it = element_input;
 
   // assemble the test matrix
   fem->assembleMatrix(K_e, K_akantu, spatial_dimension, element_type, ghost_type);
   
   /// construct a PETSc matrix
   PETScMatrix K_petsc(nb_global_nodes * spatial_dimension, _unsymmetric);
   /// build the profile of the PETSc matrix for the mesh of this example
   K_petsc.buildProfile(mesh, dof_synchronizer, spatial_dimension);
   /// add an Akantu sparse matrix to a PETSc sparse matrix
   K_petsc.add(K_akantu, 1);
 
   /// save the profile
   K_petsc.saveMatrix("profile_parallel.txt");
   /// print the matrix to screen
   if(prank == 0) {
     std::ifstream profile;
     profile.open("profile_parallel.txt");
     std::string current_line;
     while(getline(profile, current_line))
       std::cout << current_line << std::endl;
     profile.close();
   }
 
   delete communicator;
 
   finalize();
   
   return EXIT_SUCCESS;
 
 }
diff --git a/test/test_solver/test_solver_petsc.cc b/test/test_solver/test_solver_petsc.cc
index cddc54227..4c754b6cc 100644
--- a/test/test_solver/test_solver_petsc.cc
+++ b/test/test_solver/test_solver_petsc.cc
@@ -1,165 +1,165 @@
 /**
  * @file   test_solver_petsc.cc
  *
  * @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
  *
  * @date creation: Mon Oct 13 2014
  * @date last modification: Wed Oct 28 2015
  *
  * @brief  test the PETSc solver interface
  *
  * @section LICENSE
  *
  * Copyright (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne) Laboratory
  * (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free  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 <cstdlib>
 /* -------------------------------------------------------------------------- */
-#include "static_communicator.hh"
+#include "communicator.hh"
 #include "aka_common.hh"
 #include "aka_csr.hh"
 #include "mesh.hh"
 #include "mesh_io.hh"
 #include "mesh_utils.hh"
 #include "element_synchronizer.hh"
 #include "petsc_matrix.hh"
 #include "solver_petsc.hh"
 #include "fe_engine.hh"
 #include "dof_synchronizer.hh"
 
 #include "mesh_partition_scotch.hh"
 
 using namespace akantu;
 int main(int argc, char *argv[]) {
 
   initialize(argc, argv);
   const ElementType element_type = _segment_2;
   const GhostType ghost_type = _not_ghost; 
   UInt spatial_dimension = 1;
 
 
-  StaticCommunicator & comm = akantu::StaticCommunicator::getStaticCommunicator();
+  const auto & comm = akantu::Communicator::getStaticCommunicator();
   Int psize = comm.getNbProc();
   Int prank = comm.whoAmI();
 
   /// read the mesh and partition it
   Mesh mesh(spatial_dimension);
 
   /* ------------------------------------------------------------------------ */
   /* Parallel initialization                                                  */
   /* ------------------------------------------------------------------------ */
   ElementSynchronizer * communicator = NULL;
   if(prank == 0) {
     /// creation mesh
     mesh.read("1D_bar.msh");
     MeshPartitionScotch * partition = new MeshPartitionScotch(mesh, spatial_dimension);
     partition->partitionate(psize);
     communicator = ElementSynchronizer::createDistributedSynchronizerMesh(mesh, partition);
     delete partition;
   } else {
     communicator = ElementSynchronizer::createDistributedSynchronizerMesh(mesh, NULL);
   }
   
 
   FEEngine *fem = new FEEngineTemplate<IntegratorGauss,ShapeLagrange,_ek_regular>(mesh, spatial_dimension, "my_fem");
 
   DOFSynchronizer dof_synchronizer(mesh, spatial_dimension);
   UInt nb_global_nodes = mesh.getNbGlobalNodes();
 
   dof_synchronizer.initGlobalDOFEquationNumbers();
 
   // fill the matrix with 
   UInt nb_element = mesh.getNbElement(element_type);
   UInt nb_nodes_per_element = mesh.getNbNodesPerElement(element_type);
   UInt nb_dofs_per_element = spatial_dimension * nb_nodes_per_element;
   SparseMatrix K(nb_global_nodes * spatial_dimension, _symmetric);
   K.buildProfile(mesh, dof_synchronizer, spatial_dimension);
   Matrix<Real> element_input(nb_dofs_per_element, nb_dofs_per_element, 0);
   for (UInt i = 0; i < nb_dofs_per_element; ++i) {
     for (UInt j = 0; j < nb_dofs_per_element; ++j) {
       element_input(i, j) = ((i == j) ? 1 : -1); 
     }
   }
   Array<Real> K_e = Array<Real>(nb_element, nb_dofs_per_element * nb_dofs_per_element, "K_e");
   Array<Real>::matrix_iterator K_e_it = K_e.begin(nb_dofs_per_element, nb_dofs_per_element);
   Array<Real>::matrix_iterator K_e_end = K_e.end(nb_dofs_per_element, nb_dofs_per_element);
 
   for(; K_e_it != K_e_end; ++K_e_it)
     *K_e_it = element_input;
 
   // assemble the test matrix
   fem->assembleMatrix(K_e, K, spatial_dimension, element_type, ghost_type);
 
   // apply boundary: block first node
   const Array<Real> & position = mesh.getNodes();
   UInt nb_nodes = mesh.getNbNodes();
   Array<bool> boundary = Array<bool>(nb_nodes, spatial_dimension, false);
   for (UInt i = 0; i < nb_nodes; ++i) {
     if (std::abs(position(i, 0)) < Math::getTolerance() )
       boundary(i, 0) = true;
   }
 
   K.applyBoundary(boundary);
 
   /// create the PETSc matrix for the solve step
   PETScMatrix petsc_matrix(nb_global_nodes * spatial_dimension, _symmetric);
   petsc_matrix.buildProfile(mesh, dof_synchronizer, spatial_dimension);
   
   /// copy the stiffness matrix into the petsc matrix
   petsc_matrix.add(K, 1);
 
   // initialize internal forces: they are zero because imposed displacement is zero
   Array<Real> internal_forces(nb_nodes, spatial_dimension, 0.);
 
   // compute residual: apply nodal force on last node
   Array<Real> residual(nb_nodes, spatial_dimension, 0.);
   
   for (UInt i = 0; i < nb_nodes; ++i) {
     if (std::abs(position(i, 0) - 10) < Math::getTolerance() )
       residual(i, 0) += 2;
   }
 
   residual -= internal_forces;
   
   /// initialize solver and solution
   Array<Real> solution(nb_nodes, spatial_dimension, 0.);
   SolverPETSc solver(petsc_matrix);
   solver.initialize();
   solver.setOperators();
   solver.setRHS(residual);
   solver.solve(solution);
 
   /// verify solution
   Math::setTolerance(1e-11);
   for (UInt i = 0; i < nb_nodes; ++i) {
     if (!dof_synchronizer.isPureGhostDOF(i) && !Math::are_float_equal(2 * position(i, 0), solution(i, 0))) {
       std::cout << "The solution is not correct!!!!" << std::endl;
       finalize();
       return EXIT_FAILURE;
     }
   }
 
   delete communicator;
 
   finalize();
   
   return EXIT_SUCCESS;
 
 }
diff --git a/test/test_solver/test_sparse_matrix_product.cc b/test/test_solver/test_sparse_matrix_product.cc
index e08961cc2..ce24921de 100644
--- a/test/test_solver/test_sparse_matrix_product.cc
+++ b/test/test_solver/test_sparse_matrix_product.cc
@@ -1,115 +1,115 @@
 /**
  * @file   test_sparse_matrix_product.cc
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Fri Jun 17 2011
  * @date last modification: Sun Oct 19 2014
  *
  * @brief  test the matrix vector product in parallel
  *
  * @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)
  *
  * Akantu is free  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 <iostream>
 /* -------------------------------------------------------------------------- */
 #include "aka_common.hh"
 #include "mesh.hh"
 #include "mesh_partition_scotch.hh"
 #include "element_synchronizer.hh"
 #include "sparse_matrix.hh"
 #include "dof_synchronizer.hh"
 /* -------------------------------------------------------------------------- */
 
 using namespace akantu;
 
 /* -------------------------------------------------------------------------- */
 int main(int argc, char *argv[])
 {
   initialize(argc, argv);
   const UInt spatial_dimension = 2;
   const UInt nb_dof = 2;
 
-  StaticCommunicator & comm = akantu::StaticCommunicator::getStaticCommunicator();
+  const auto & comm = Communicator::getStaticCommunicator();
   Int psize = comm.getNbProc();
   Int prank = comm.whoAmI();
 
   Mesh mesh(spatial_dimension);
   mesh.read("bar.msh");
   mesh.distribute();
 
   UInt nb_nodes = mesh.getNbNodes();
   DOFManagerDefault dof_manager(mesh, "test_dof_manager");
 
   Array<Real> test_synchronize(nb_nodes, nb_dof, "Test vector");
   dof_manager.registerDOFs("test_synchronize", test_synchronize, _dst_nodal);
 
   if (prank == 0) std::cout << "Creating a SparseMatrix" << std::endl;
 
   auto & A = dof_manager.getNewMatrix("A", _symmetric);
 
   Array<Real> dof_vector(nb_nodes, nb_dof, "vector");
 
   if (prank == 0) std::cout << "Filling the matrix" << std::endl;
 
   for (UInt i = 0; i < nb_nodes*nb_dof; ++i) {
     if(dof_manager.isLocalOrMasterDOF(i))
       A.add(i, i, 2.);
   }
 
   std::stringstream str; str << "Matrix_" << prank << ".mtx";
   A.saveMatrix(str.str());
 
   for (UInt n = 0; n < nb_nodes; ++n) {
     for (UInt d = 0; d < nb_dof; ++d) {
       dof_vector(n, d) = 1.;
     }
   }
 
   if (prank == 0) std::cout << "Computing x = A * x" << std::endl;
   dof_vector *= A;
 
   auto & sync = dynamic_cast<DOFManagerDefault &>(dof_manager)
     .getSynchronizer();
 
   if (prank == 0) std::cout << "Gathering the results on proc 0" << std::endl;
   if(psize > 1) {
     if(prank == 0) {
       Array<Real> gathered;
       sync.gather(dof_vector, gathered);
 
       debug::setDebugLevel(dblTest);
       std::cout << gathered << std::endl;
       debug::setDebugLevel(dblWarning);
     } else {
       sync.gather(dof_vector);
     }
   } else {
     debug::setDebugLevel(dblTest);
     std::cout << dof_vector << std::endl;
     debug::setDebugLevel(dblWarning);
   }
 
   finalize();
 
   return 0;
 }
diff --git a/test/test_solver/test_sparse_matrix_profile_parallel.cc b/test/test_solver/test_sparse_matrix_profile_parallel.cc
index 4ea513a55..67682f43b 100644
--- a/test/test_solver/test_sparse_matrix_profile_parallel.cc
+++ b/test/test_solver/test_sparse_matrix_profile_parallel.cc
@@ -1,114 +1,114 @@
 /**
  * @file   test_sparse_matrix_profile_parallel.cc
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Sun Sep 12 2010
  * @date last modification: Sun Oct 19 2014
  *
  * @brief  test the sparse matrix class in parallel
  *
  * @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)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
  * terms  of the  GNU Lesser  General Public  License as  published by  the Free
  * Software Foundation, either version 3 of the License, or (at your option) any
  * later version.
  *
  * Akantu is  distributed in the  hope that it  will be useful, but  WITHOUT ANY
  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  * A  PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 
 /* -------------------------------------------------------------------------- */
 #include "aka_common.hh"
 #include "mesh.hh"
 #include "mesh_io_msh.hh"
 #include "mesh_partition_scotch.hh"
 #include "communicator.hh"
 #include "sparse_matrix.hh"
 #include "solver_mumps.hh"
 
 /* -------------------------------------------------------------------------- */
 
 
 /* -------------------------------------------------------------------------- */
 /* Main                                                                       */
 /* -------------------------------------------------------------------------- */
 int main(int argc, char *argv[])
 {
   akantu::initialize(argc, argv);
 
   int dim = 2;
   //#ifdef AKANTU_USE_IOHELPER
   //akantu::ElementType type = akantu::_triangle_6;
   //#endif //AKANTU_USE_IOHELPER
   akantu::Mesh mesh(dim);
 
   //  akantu::debug::setDebugLevel(akantu::dblDump);
 
-  akantu::StaticCommunicator * comm = akantu::StaticCommunicator::getStaticCommunicator();
+  akantu::StaticCommunicator * comm = akantu::Communicator::getStaticCommunicator();
   akantu::Int psize = comm->getNbProc();
   akantu::Int prank = comm->whoAmI();
 
   akantu::UInt n = 0;
 
 
 
   /* ------------------------------------------------------------------------ */
   /* Parallel initialization                                                  */
   /* ------------------------------------------------------------------------ */
   akantu::Communicator * communicator;
   if(prank == 0) {
     akantu::MeshIOMSH mesh_io;
     mesh_io.read("triangle.msh", mesh);
     akantu::MeshPartition * partition =
       new akantu::MeshPartitionScotch(mesh, dim);
 
     //    partition->reorder();
     mesh_io.write("triangle_reorder.msh", mesh);
 
     n = mesh.getNbNodes();
 
     partition->partitionate(psize);
     communicator = akantu::Communicator::createCommunicatorDistributeMesh(mesh, partition);
     delete partition;
   } else {
     communicator = akantu::Communicator::createCommunicatorDistributeMesh(mesh, NULL);
   }
 
 
   std::cout << "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA " << mesh.getNbGlobalNodes() << std::endl;
 
   akantu::SparseMatrix sparse_matrix(mesh, akantu::_symmetric, 2, "mesh");
   sparse_matrix.buildProfile();
 
   akantu::Solver * solver = new akantu::SolverMumps(sparse_matrix);
 
   if(prank == 0) {
     for(akantu::UInt i = 0; i < n; ++i) {
       solver->getRHS().storage()[i] = 1.;
     }
   }
 
   akantu::debug::setDebugLevel(akantu::dblDump);
   solver->initialize();
 
   std::stringstream sstr; sstr << "profile_" << prank << ".mtx";
   sparse_matrix.saveProfile(sstr.str());
 
   akantu::finalize();
 
   return EXIT_SUCCESS;
 }
diff --git a/test/test_solver/test_sparse_solver_mumps.cc b/test/test_solver/test_sparse_solver_mumps.cc
index b8ff41186..b3ba6aaf8 100644
--- a/test/test_solver/test_sparse_solver_mumps.cc
+++ b/test/test_solver/test_sparse_solver_mumps.cc
@@ -1,159 +1,158 @@
 /**
  * @file   test_sparse_matrix_product.cc
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Fri Jun 17 2011
  * @date last modification: Sun Oct 19 2014
  *
  * @brief  test the matrix vector product in parallel
  *
  * @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)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
  * terms  of the  GNU Lesser  General Public  License as  published by  the Free
  * Software Foundation, either version 3 of the License, or (at your option) any
  * later version.
  *
  * Akantu is  distributed in the  hope that it  will be useful, but  WITHOUT ANY
  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  * A  PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 /* -------------------------------------------------------------------------- */
 #include "aka_common.hh"
 #include "dof_synchronizer.hh"
 #include "element_synchronizer.hh"
 #include "mesh.hh"
 #include "mesh_accessor.hh"
 #include "mesh_partition_scotch.hh"
 #include "sparse_matrix_aij.hh"
 #include "sparse_solver_mumps.hh"
 #include "terms_to_assemble.hh"
 /* -------------------------------------------------------------------------- */
 #include <iostream>
 /* -------------------------------------------------------------------------- */
 
 using namespace akantu;
 
 /* -------------------------------------------------------------------------- */
 void genMesh(Mesh & mesh, UInt nb_nodes);
 /* -------------------------------------------------------------------------- */
 
 /* -------------------------------------------------------------------------- */
 int main(int argc, char * argv[]) {
   initialize(argc, argv);
   const UInt spatial_dimension = 1;
   const UInt nb_global_dof = 11;
-  StaticCommunicator & comm =
-      akantu::StaticCommunicator::getStaticCommunicator();
+  const auto & comm = Communicator::getStaticCommunicator();
   // Int psize = comm.getNbProc();
   Int prank = comm.whoAmI();
 
   Mesh mesh(spatial_dimension);
 
   if (prank == 0) {
     genMesh(mesh, nb_global_dof);
     RandomGenerator<UInt>::seed(1496137735);
   } else {
     RandomGenerator<UInt>::seed(2992275470);
   }
 
   mesh.distribute();
   UInt node = 0;
   for (auto pos : mesh.getNodes()) {
     std::cout << prank << " " << node << " pos: " << pos << " ["
               << mesh.getNodeGlobalId(node) << "] " << mesh.getNodeType(node)
               << std::endl;
     ++node;
   }
   UInt nb_nodes = mesh.getNbNodes();
 
   DOFManagerDefault dof_manager(mesh, "test_dof_manager");
 
   Array<Real> x(nb_nodes);
   dof_manager.registerDOFs("x", x, _dst_nodal);
 
   const auto & local_equation_number = dof_manager.getEquationsNumbers("x");
 
   auto & A = dof_manager.getNewMatrix("A", _symmetric);
 
   Array<Real> b(nb_nodes);
   TermsToAssemble terms;
 
   for (UInt i = 0; i < nb_nodes; ++i) {
     if (dof_manager.isLocalOrMasterDOF(i)) {
       auto li = local_equation_number(i);
       auto gi = dof_manager.localToGlobalEquationNumber(li);
       terms(i, i) = 1. / (1. + gi);
     }
   }
 
   dof_manager.assemblePreassembledMatrix("x", "x", "A", terms);
 
   std::stringstream str;
   str << "Matrix_" << prank << ".mtx";
   A.saveMatrix(str.str());
 
   for (UInt n = 0; n < nb_nodes; ++n) {
     b(n) = 1.;
   }
 
   SparseSolverMumps solver(dof_manager, "A");
 
   solver.solve(x, b);
 
   auto & sync =
       dynamic_cast<DOFManagerDefault &>(dof_manager).getSynchronizer();
 
   if (prank == 0) {
     Array<Real> x_gathered(dof_manager.getSystemSize());
     sync.gather(x, x_gathered);
 
     debug::setDebugLevel(dblTest);
     std::cout << x_gathered << std::endl;
     debug::setDebugLevel(dblWarning);
 
     UInt d = 1.;
     for (auto x : x_gathered) {
       if (std::abs(x - d) / d > 1e-15)
         AKANTU_EXCEPTION("Error in the solution: " << x << " != " << d << " ["
                                                    << (std::abs(x - d) / d)
                                                    << "].");
       ++d;
     }
   } else {
     sync.gather(x);
   }
 
   finalize();
 
   return 0;
 }
 
 /* -------------------------------------------------------------------------- */
 void genMesh(Mesh & mesh, UInt nb_nodes) {
   MeshAccessor mesh_accessor(mesh);
   Array<Real> & nodes = mesh_accessor.getNodes();
   Array<UInt> & conn = mesh_accessor.getConnectivity(_segment_2);
 
   nodes.resize(nb_nodes);
 
   for (UInt n = 0; n < nb_nodes; ++n) {
     nodes(n, _x) = n * (1. / (nb_nodes - 1));
   }
 
   conn.resize(nb_nodes - 1);
   for (UInt n = 0; n < nb_nodes - 1; ++n) {
     conn(n, 0) = n;
     conn(n, 1) = n + 1;
   }
 }
diff --git a/test/test_synchronizer/test_data_distribution.cc b/test/test_synchronizer/test_data_distribution.cc
index b5f970ae0..59ba6be9b 100644
--- a/test/test_synchronizer/test_data_distribution.cc
+++ b/test/test_synchronizer/test_data_distribution.cc
@@ -1,173 +1,173 @@
 /**
  * @file   test_data_distribution.cc
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Fri Sep 05 2014
  * @date last modification: Sun Oct 19 2014
  *
  * @brief  Test the mesh distribution on creation of a distributed synchonizer
  *
  * @section LICENSE
  *
  * Copyright  (©)  2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
  * terms  of the  GNU Lesser  General Public  License as  published by  the Free
  * Software Foundation, either version 3 of the License, or (at your option) any
  * later version.
  *
  * Akantu is  distributed in the  hope that it  will be useful, but  WITHOUT ANY
  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  * A  PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 #include "aka_iterators.hh"
 #include "aka_random_generator.hh"
 #include "element_group.hh"
 #include "element_synchronizer.hh"
 #include "mesh_iterators.hh"
 #include "mesh_partition_mesh_data.hh"
 /* -------------------------------------------------------------------------- */
 #include <algorithm>
 /* -------------------------------------------------------------------------- */
 
 using namespace akantu;
 
 int main(int argc, char * argv[]) {
   initialize(argc, argv);
 
   const UInt spatial_dimension = 3;
 
   Mesh mesh_group_after(spatial_dimension, "after");
   Mesh mesh_group_before(spatial_dimension, "before");
 
-  StaticCommunicator & comm = StaticCommunicator::getStaticCommunicator();
+  const auto & comm = Communicator::getStaticCommunicator();
   Int psize = comm.getNbProc();
   Int prank = comm.whoAmI();
 
   if (prank == 0) {
     mesh_group_before.read("data_split.msh");
     mesh_group_after.read("data_split.msh");
 
     mesh_group_before.registerData<UInt>("global_id");
     mesh_group_after.registerData<UInt>("global_id");
 
     for (const auto & type : mesh_group_after.elementTypes(_all_dimensions)) {
       auto & gidb = mesh_group_before.getDataPointer<UInt>("global_id", type);
       auto & gida = mesh_group_after.getDataPointer<UInt>("global_id", type);
 
       for (auto && data : zip(arange(gida.size()), gida, gidb)) {
         std::get<1>(data) = std::get<0>(data);
         std::get<2>(data) = std::get<0>(data);
       }
     }
   }
 
   RandomGenerator<UInt>::seed(1);
   mesh_group_before.distribute();
 
   RandomGenerator<UInt>::seed(1);
   mesh_group_after.distribute();
 
   if (prank == 0)
     std::cout << mesh_group_after;
 
   for (const auto & agrp : ElementGroupsIterable(mesh_group_after)) {
     const ElementGroup & bgrp =
         mesh_group_before.getElementGroup(agrp.getName());
 
     for (auto && ghost_type : ghost_types) {
       for (const auto & type : bgrp.elementTypes(_all_dimensions, ghost_type)) {
         Array<UInt> & gidb = mesh_group_before.getDataPointer<UInt>(
             "global_id", type, ghost_type);
         Array<UInt> & gida = mesh_group_after.getDataPointer<UInt>(
             "global_id", type, ghost_type);
 
         Array<UInt> bgelem(bgrp.getElements(type, ghost_type));
         Array<UInt> agelem(agrp.getElements(type, ghost_type));
 
         std::transform(agelem.begin(), agelem.end(), agelem.begin(),
                        [&gida](auto & i) { return gida(i); });
         std::transform(bgelem.begin(), bgelem.end(), bgelem.begin(),
                        [&gidb](auto & i) { return gidb(i); });
 
         std::sort(bgelem.begin(), bgelem.end());
         std::sort(agelem.begin(), agelem.end());
 
         if (not std::equal(bgelem.begin(), bgelem.end(), agelem.begin())) {
           std::cerr << "The filters array for the group " << agrp.getName()
                     << " and for the element type " << type << ", "
                     << ghost_type << " do not match" << std::endl;
 
           debug::setDebugLevel(dblTest);
 
           std::cerr << bgelem << std::endl;
           std::cerr << agelem << std::endl;
           debug::debugger.exit(EXIT_FAILURE);
         }
       }
     }
   }
 
   for (const auto & agrp : NodeGroupsIterable(mesh_group_after)) {
     const NodeGroup & bgrp = mesh_group_before.getNodeGroup(agrp.getName());
 
     const Array<UInt> & gidb = mesh_group_before.getGlobalNodesIds();
     const Array<UInt> & gida = mesh_group_after.getGlobalNodesIds();
 
     Array<UInt> bgnode(0, 1);
     Array<UInt> agnode(0, 1);
 
     for (auto && pair : zip(bgrp, agrp)) {
       UInt a,b;
       std::tie(b, a) = pair;
       if (psize > 1) {
         if (mesh_group_before.isLocalOrMasterNode(b))
           bgnode.push_back(gidb(b));
 
         if (mesh_group_after.isLocalOrMasterNode(a))
           agnode.push_back(gida(a));
       }
     }
 
     std::sort(bgnode.begin(), bgnode.end());
     std::sort(agnode.begin(), agnode.end());
 
     if (!std::equal(bgnode.begin(), bgnode.end(), agnode.begin())) {
       std::cerr << "The filters array for the group " << agrp.getName() << " do not match"
                 << std::endl;
 
       debug::setDebugLevel(dblTest);
 
       std::cerr << bgnode << std::endl;
       std::cerr << agnode << std::endl;
       debug::debugger.exit(EXIT_FAILURE);
     }
   }
 
   mesh_group_after.getElementGroup("inside").setBaseName("after_inside");
   mesh_group_after.getElementGroup("inside").dump();
   mesh_group_after.getElementGroup("outside").setBaseName("after_outside");
   mesh_group_after.getElementGroup("outside").dump();
   mesh_group_after.getElementGroup("volume").setBaseName("after_volume");
   mesh_group_after.getElementGroup("volume").dump();
 
   mesh_group_before.getElementGroup("inside").setBaseName("before_inside");
   mesh_group_before.getElementGroup("inside").dump();
   mesh_group_before.getElementGroup("outside").setBaseName("before_outside");
   mesh_group_before.getElementGroup("outside").dump();
   mesh_group_before.getElementGroup("volume").setBaseName("before_volume");
   mesh_group_before.getElementGroup("volume").dump();
 
   finalize();
 
   return EXIT_SUCCESS;
 }
diff --git a/test/test_synchronizer/test_dof_synchronizer.cc b/test/test_synchronizer/test_dof_synchronizer.cc
index 70fcb3c34..aab3c5d66 100644
--- a/test/test_synchronizer/test_dof_synchronizer.cc
+++ b/test/test_synchronizer/test_dof_synchronizer.cc
@@ -1,149 +1,149 @@
 /**
  * @file   test_dof_synchronizer.cc
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Fri Jun 17 2011
  * @date last modification: Sun Oct 19 2014
  *
  * @brief  Test the functionality of the DOFSynchronizer 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)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
  * terms  of the  GNU Lesser  General Public  License as  published by  the Free
  * Software Foundation, either version 3 of the License, or (at your option) any
  * later version.
  *
  * Akantu is  distributed in the  hope that it  will be useful, but  WITHOUT ANY
  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  * A  PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 #include "aka_common.hh"
 #include "dof_synchronizer.hh"
 #include "element_synchronizer.hh"
 #include "mesh_io.hh"
 #include "mesh_partition_scotch.hh"
-#include "static_communicator.hh"
+#include "communicator.hh"
 
 /* -------------------------------------------------------------------------- */
 #ifdef AKANTU_USE_IOHELPER
 #include "io_helper.hh"
 #endif // AKANTU_USE_IOHELPER
 
 /* -------------------------------------------------------------------------- */
 using namespace akantu;
 
 int main(int argc, char * argv[]) {
   const UInt spatial_dimension = 2;
 
   initialize(argc, argv);
 
-  StaticCommunicator & comm =
-      akantu::StaticCommunicator::getStaticCommunicator();
+  const auto & comm =
+      akantu::Communicator::getStaticCommunicator();
   Int prank = comm.whoAmI();
 
   Mesh mesh(spatial_dimension);
 
   if (prank == 0)
     mesh.read("bar.msh");
   mesh.distribute();
 
   DOFManagerDefault dof_manager(mesh, "test_dof_manager");
 
   UInt nb_nodes = mesh.getNbNodes();
 
   /* ------------------------------------------------------------------------ */
   /* test the synchronization                                                 */
   /* ------------------------------------------------------------------------ */
   Array<Real> test_synchronize(nb_nodes, spatial_dimension, "Test vector");
   dof_manager.registerDOFs("test_synchronize", test_synchronize, _dst_nodal);
 
   auto & equation_number =
       dof_manager.getLocalEquationNumbers("test_synchronize");
 
   DOFSynchronizer & dof_synchronizer = dof_manager.getSynchronizer();
 
   std::cout << "Synchronizing a dof vector" << std::endl;
 
   Array<Int> local_data_array(dof_manager.getLocalSystemSize(), 2);
   auto it_data = local_data_array.begin(2);
 
   for (UInt local_dof = 0; local_dof < dof_manager.getLocalSystemSize();
        ++local_dof) {
     UInt equ_number = equation_number(local_dof);
     Vector<Int> val;
     if (dof_manager.isLocalOrMasterDOF(equ_number)) {
       UInt global_dof = dof_manager.localToGlobalEquationNumber(local_dof);
       val = {0, 1};
       val += global_dof * 2;
     } else {
       val = {-1, -1};
     }
 
     Vector<Int> data = it_data[local_dof];
     data = val;
   }
 
   dof_synchronizer.synchronize(local_data_array);
 
   auto test_data = [&]() -> void {
     auto it_data = local_data_array.begin(2);
     for (UInt local_dof = 0; local_dof < dof_manager.getLocalSystemSize();
          ++local_dof) {
       UInt equ_number = equation_number(local_dof);
 
       Vector<Int> exp_val;
 
       UInt global_dof = dof_manager.localToGlobalEquationNumber(local_dof);
 
       if (dof_manager.isLocalOrMasterDOF(equ_number) ||
           dof_manager.isSlaveDOF(equ_number)) {
         exp_val = {0, 1};
         exp_val += global_dof * 2;
       } else {
         exp_val = {-1, -1};
       }
 
       Vector<Int> val = it_data[local_dof];
       if (exp_val != val) {
         std::cerr << "Failed !" << prank << " DOF: " << global_dof << " - l"
                   << local_dof << " value:" << val << " expected: " << exp_val
                   << std::endl;
         exit(1);
       }
     }
   };
 
   test_data();
 
   if (prank == 0) {
     Array<Int> test_gathered(dof_manager.getSystemSize(), 2);
     dof_synchronizer.gather(local_data_array, test_gathered);
 
     local_data_array.set(-1);
     dof_synchronizer.scatter(local_data_array, test_gathered);
   } else {
     dof_synchronizer.gather(local_data_array);
 
     local_data_array.set(-1);
     dof_synchronizer.scatter(local_data_array);
   }
 
   test_data();
 
   finalize();
 
   return 0;
 }
diff --git a/test/test_synchronizer/test_dof_synchronizer_communication.cc b/test/test_synchronizer/test_dof_synchronizer_communication.cc
index 295b2e1c9..dd6245ff9 100644
--- a/test/test_synchronizer/test_dof_synchronizer_communication.cc
+++ b/test/test_synchronizer/test_dof_synchronizer_communication.cc
@@ -1,102 +1,102 @@
 /**
  * @file   test_dof_synchronizer_communication.cc
  *
  * @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
  *
  * @date creation: Tue Dec 09 2014
  *
  * @brief  test to synchronize global equation numbers
  *
  * @section LICENSE
  *
  * Copyright (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne) Laboratory
  * (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
  * terms  of the  GNU Lesser  General Public  License as  published by  the Free
  * Software Foundation, either version 3 of the License, or (at your option) any
  * later version.
  *
  * Akantu is  distributed in the  hope that it  will be useful, but  WITHOUT ANY
  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  * A  PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 
 /* -------------------------------------------------------------------------- */
 #include "aka_common.hh"
 #include "element_synchronizer.hh"
 #include "dof_synchronizer.hh"
 #include "synchronizer_registry.hh"
 #include "mesh.hh"
 #include "mesh_partition_scotch.hh"
 /* -------------------------------------------------------------------------- */
 #ifdef AKANTU_USE_IOHELPER
 #  include "dumper_paraview.hh"
 #endif //AKANTU_USE_IOHELPER
 
 #include "test_dof_data_accessor.hh"
 
 
 using namespace akantu;
 
 /* -------------------------------------------------------------------------- */
 /* Main                                                                       */
 /* -------------------------------------------------------------------------- */
 int main(int argc, char *argv[])
 {
   initialize(argc, argv);
 
   UInt spatial_dimension = 3;
 
   Mesh mesh(spatial_dimension);
 
-  StaticCommunicator & comm = StaticCommunicator::getStaticCommunicator();
+  const auto & comm = Communicator::getStaticCommunicator();
   Int psize = comm.getNbProc();
   Int prank = comm.whoAmI();
   bool wait=true;
   if(argc >1) {
     if(prank == 0)
     while(wait);
   }
 
   ElementSynchronizer * communicator = NULL;
   if(prank == 0) {
     mesh.read("cube.msh");
 
     MeshPartition * partition = new MeshPartitionScotch(mesh, spatial_dimension);
     partition->partitionate(psize);
     communicator = ElementSynchronizer::createDistributedSynchronizerMesh(mesh, partition);
     delete partition;
   } else {
     communicator = ElementSynchronizer::createDistributedSynchronizerMesh(mesh, NULL);
   }
 
 /* -------------------------------------------------------------------------- */
 /* test the communications of the dof synchronizer                                */
 /* -------------------------------------------------------------------------- */
 
   std::cout << "Initializing the synchronizer" << std::endl;
   DOFSynchronizer dof_synchronizer(mesh, spatial_dimension);
   dof_synchronizer.initGlobalDOFEquationNumbers();
 
   AKANTU_DEBUG_INFO("Creating TestDOFAccessor");
   TestDOFAccessor test_dof_accessor(dof_synchronizer.getGlobalDOFEquationNumbers());
   SynchronizerRegistry synch_registry(test_dof_accessor);
   synch_registry.registerSynchronizer(dof_synchronizer,_gst_test);
 
   AKANTU_DEBUG_INFO("Synchronizing tag");
   synch_registry.synchronize(_gst_test);
 
   delete communicator;
   finalize();
 
   return EXIT_SUCCESS;
 }
 
diff --git a/test/test_synchronizer/test_facet_synchronizer.cc b/test/test_synchronizer/test_facet_synchronizer.cc
index d3b2c8d36..ca7acdf31 100644
--- a/test/test_synchronizer/test_facet_synchronizer.cc
+++ b/test/test_synchronizer/test_facet_synchronizer.cc
@@ -1,100 +1,61 @@
 /**
  * @file   test_facet_synchronizer.cc
  *
  * @author Marco Vocialta <marco.vocialta@epfl.ch>
  *
  *
  * @brief  Facet synchronizer test
  *
  * @section LICENSE
  *
  * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  */
 
 /* -------------------------------------------------------------------------- */
-
-#include "test_data_accessor.hh"
 #include "facet_synchronizer.hh"
 #include "mesh_utils.hh"
 #include "synchronizer_registry.hh"
+#include "test_data_accessor.hh"
 #include <iostream>
-
 /* -------------------------------------------------------------------------- */
 
 using namespace akantu;
 
-int main(int argc, char *argv[]) {
+int main(int argc, char * argv[]) {
   akantu::initialize(argc, argv);
 
   UInt spatial_dimension = 3;
   Mesh mesh(spatial_dimension);
 
-  StaticCommunicator & comm = StaticCommunicator::getStaticCommunicator();
-  Int psize = comm.getNbProc();
+  const auto & comm = Communicator::getStaticCommunicator();
   Int prank = comm.whoAmI();
-  DistributedSynchronizer * dist = NULL;
 
   /// partition the mesh
-  if(prank == 0) {
+  if (prank == 0) {
     mesh.read("facet.msh");
-    MeshPartition * partition = new MeshPartitionScotch(mesh, spatial_dimension);
-    partition->partitionate(psize);
-    dist = DistributedSynchronizer::createDistributedSynchronizerMesh(mesh, partition);
-    delete partition;
-  } else {
-    dist = DistributedSynchronizer::createDistributedSynchronizerMesh(mesh, NULL);
   }
 
-  /// create facets
-  Mesh mesh_facets(mesh.initMeshFacets("mesh_facets"));
-  MeshUtils::buildAllFacets(mesh, mesh_facets, 0, dist);
-
-  /// compute barycenter for each facet
-  ElementTypeMapArray<Real> barycenters("barycenters", "", 0);
-  mesh_facets.initElementTypeMapArray(barycenters,
-				     spatial_dimension,
-				     spatial_dimension - 1);
+  mesh.distribute();
 
-  for (ghost_type_t::iterator gt = ghost_type_t::begin();
-       gt != ghost_type_t::end(); ++gt) {
-    GhostType ghost_type = *gt;
-    Mesh::type_iterator it = mesh_facets.firstType(spatial_dimension - 1,
-						   ghost_type);
-    Mesh::type_iterator last_type = mesh_facets.lastType(spatial_dimension - 1,
-							 ghost_type);
+  auto & synchronizer = mesh.getElementSynchronizer();
 
-    for(; it != last_type; ++it) {
-      UInt nb_element = mesh_facets.getNbElement(*it, ghost_type);
-      Array<Real> & barycenter = barycenters(*it, ghost_type);
-      barycenter.resize(nb_element);
-
-      Array<Real>::iterator< Vector<Real> > bary_it
-	= barycenter.begin(spatial_dimension);
-
-      for (UInt elem = 0; elem < nb_element; ++elem, ++bary_it)
-	mesh_facets.getBarycenter(elem, *it, bary_it->storage(), ghost_type);
-    }
-  }
+  /// create facets
+  Mesh & mesh_facets = mesh.initMeshFacets("mesh_facets");
 
   /// setup facet communications
-  FacetSynchronizer * facet_synchronizer =
-    FacetSynchronizer::createFacetSynchronizer(*dist, mesh_facets);
-
-  AKANTU_DEBUG_INFO("Creating TestAccessor");
-  TestAccessor test_accessor(mesh, barycenters);
-  SynchronizerRegistry synch_registry(test_accessor);
+  auto & facet_synchronizer = mesh_facets.getElementSynchronizer();
 
-  synch_registry.registerSynchronizer(*facet_synchronizer, _gst_test);
+  // AKANTU_DEBUG_INFO("Creating TestAccessor");
+  // TestAccessor test_accessor(mesh);
+  // SynchronizerRegistry synch_registry(test_accessor);
 
-  /// synchronize facets and check results
-  AKANTU_DEBUG_INFO("Synchronizing tag");
-  synch_registry.synchronize(_gst_test);
+  // synch_registry.registerSynchronizer(facet_synchronizer, _gst_test);
 
-  delete facet_synchronizer;
-  delete dist;
-  akantu::finalize();
+  // /// synchronize facets and check results
+  // AKANTU_DEBUG_INFO("Synchronizing tag");
+  // synch_registry.synchronize(_gst_test);
 
-  return EXIT_SUCCESS;
+  return 0;
 }
diff --git a/test/test_synchronizer/test_grid_synchronizer.cc b/test/test_synchronizer/test_grid_synchronizer.cc
index 71b601229..90e97ddcc 100644
--- a/test/test_synchronizer/test_grid_synchronizer.cc
+++ b/test/test_synchronizer/test_grid_synchronizer.cc
@@ -1,299 +1,299 @@
 /**
  * @file   test_grid_synchronizer.cc
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Wed Sep 01 2010
  * @date last modification: Fri Feb 27 2015
  *
  * @brief  test the GridSynchronizer object
  *
  * @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)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
  * terms  of the  GNU Lesser  General Public  License as  published by  the Free
  * Software Foundation, either version 3 of the License, or (at your option) any
  * later version.
  *
  * Akantu is  distributed in the  hope that it  will be useful, but  WITHOUT ANY
  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  * A  PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 #include "aka_common.hh"
 #include "aka_grid_dynamic.hh"
 #include "mesh.hh"
 #include "grid_synchronizer.hh"
 #include "mesh_partition.hh"
 #include "synchronizer_registry.hh"
 #include "test_data_accessor.hh"
 #ifdef AKANTU_USE_IOHELPER
 #  include "io_helper.hh"
 #endif //AKANTU_USE_IOHELPER
 
 using namespace akantu;
 
 const UInt spatial_dimension = 2;
 
 typedef std::map<std::pair<Element, Element>, Real> pair_list;
 
 #include "test_grid_tools.hh"
 
 static void updatePairList(const ElementTypeMapArray<Real> & barycenter,
                              const SpatialGrid<Element> & grid,
                              Real radius,
                              pair_list & neighbors,
                              neighbors_map_t<spatial_dimension>::type & neighbors_map) {
   AKANTU_DEBUG_IN();
 
   GhostType ghost_type = _not_ghost;
 
   Element e;
   e.ghost_type = ghost_type;
 
   // generate the pair of neighbor depending of the cell_list
   ElementTypeMapArray<Real>::type_iterator it        = barycenter.firstType(_all_dimensions, ghost_type);
   ElementTypeMapArray<Real>::type_iterator last_type = barycenter.lastType(0, ghost_type);
   for(; it != last_type; ++it) {
     // loop over quad points
 
     e.type = *it;
     e.element = 0;
 
     const Array<Real> & barycenter_vect = barycenter(*it, ghost_type);
     UInt sp = barycenter_vect.getNbComponent();
 
     Array<Real>::const_iterator< Vector<Real> > bary =
       barycenter_vect.begin(sp);
     Array<Real>::const_iterator< Vector<Real> > bary_end =
       barycenter_vect.end(sp);
 
     for(;bary != bary_end; ++bary, e.element++) {
 #if !defined(AKANTU_NDEBUG)
       Point<spatial_dimension> pt1(*bary);
 #endif
 
       SpatialGrid<Element>::CellID cell_id = grid.getCellID(*bary);
       SpatialGrid<Element>::neighbor_cells_iterator first_neigh_cell =
         grid.beginNeighborCells(cell_id);
       SpatialGrid<Element>::neighbor_cells_iterator last_neigh_cell =
         grid.endNeighborCells(cell_id);
 
       // loop over neighbors cells of the one containing the current element
       for (; first_neigh_cell != last_neigh_cell; ++first_neigh_cell) {
         SpatialGrid<Element>::Cell::const_iterator first_neigh_el =
           grid.beginCell(*first_neigh_cell);
         SpatialGrid<Element>::Cell::const_iterator last_neigh_el =
           grid.endCell(*first_neigh_cell);
 
         // loop over the quadrature point in the current cell of the cell list
         for (;first_neigh_el != last_neigh_el; ++first_neigh_el){
           const Element & elem = *first_neigh_el;
 
 	  Array<Real>::const_iterator< Vector<Real> > neigh_it =
 	    barycenter(elem.type, elem.ghost_type).begin(sp);
 
 	  const Vector<Real> & neigh_bary = neigh_it[elem.element];
 
           Real distance = bary->distance(neigh_bary);
           if(distance <= radius) {
 #if !defined(AKANTU_NDEBUG)
             Point<spatial_dimension> pt2(neigh_bary);
             neighbors_map[pt1].push_back(pt2);
 #endif
             std::pair<Element, Element> pair = std::make_pair(e, elem);
             pair_list::iterator p = neighbors.find(pair);
             if(p != neighbors.end()) {
               AKANTU_DEBUG_ERROR("Pair already registered [" << e << " " << elem << "] -> " << p->second << " " << distance);
             } else {
               neighbors[pair] = distance;
             }
           }
         }
       }
     }
   }
   AKANTU_DEBUG_OUT();
 }
 
 
 /* -------------------------------------------------------------------------- */
 /* Main                                                                       */
 /* -------------------------------------------------------------------------- */
 int main(int argc, char *argv[]) {
   akantu::initialize(argc, argv);
 
   Real radius = 0.001;
 
   Mesh mesh(spatial_dimension);
 
-  StaticCommunicator & comm = StaticCommunicator::getStaticCommunicator();
+  const auto & comm = Communicator::getStaticCommunicator();
   Int psize = comm.getNbProc();
   Int prank = comm.whoAmI();
   ElementSynchronizer * dist = NULL;
 
   if(prank == 0) {
     mesh.read("bar.msh");
     MeshPartition * partition = new MeshPartitionScotch(mesh, spatial_dimension);
     partition->partitionate(psize);
     dist = ElementSynchronizer::createDistributedSynchronizerMesh(mesh, partition);
     delete partition;
   } else {
     dist = ElementSynchronizer::createDistributedSynchronizerMesh(mesh, NULL);
   }
 
   mesh.computeBoundingBox();
 
   const Vector<Real> & lower_bounds = mesh.getLowerBounds();
   const Vector<Real> & upper_bounds = mesh.getUpperBounds();
 
   Vector<Real> center = 0.5 * (upper_bounds + lower_bounds);
 
   Vector<Real> spacing(spatial_dimension);
   for (UInt i = 0; i < spatial_dimension; ++i) {
     spacing[i] = radius * 1.2;
   }
 
   SpatialGrid<Element> grid(spatial_dimension, spacing, center);
 
   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);
 
   ElementTypeMapArray<Real> barycenters("", "");
   mesh.initElementTypeMapArray(barycenters, spatial_dimension, spatial_dimension);
 
   Element e;
   e.ghost_type = ghost_type;
 
   for(; it != last_type; ++it) {
     UInt nb_element = mesh.getNbElement(*it, ghost_type);
     e.type = *it;
     Array<Real> & barycenter = barycenters(*it, ghost_type);
     barycenter.resize(nb_element);
 
     Array<Real>::iterator< Vector<Real> > bary_it = barycenter.begin(spatial_dimension);
     for (UInt elem = 0; elem < nb_element; ++elem) {
       mesh.getBarycenter(elem, *it, bary_it->storage(), ghost_type);
       e.element = elem;
       grid.insert(e, *bary_it);
       ++bary_it;
     }
   }
 
   std::stringstream sstr; sstr << "mesh_" << prank << ".msh";
   mesh.write(sstr.str());
 
   Mesh grid_mesh(spatial_dimension, "grid_mesh", 0);
   std::stringstream sstr_grid; sstr_grid << "grid_mesh_" << prank << ".msh";
   grid.saveAsMesh(grid_mesh);
   grid_mesh.write(sstr_grid.str());
 
 
 
   std::cout << "Pouet 1" << std::endl;
 
   AKANTU_DEBUG_INFO("Creating TestAccessor");
   TestAccessor test_accessor(mesh, barycenters);
   SynchronizerRegistry synch_registry(test_accessor);
 
   GridSynchronizer * grid_communicator = GridSynchronizer::createGridSynchronizer(mesh, grid);
 
   std::cout << "Pouet 2" << std::endl;
 
   ghost_type = _ghost;
 
   it = mesh.firstType(spatial_dimension, ghost_type);
   last_type = mesh.lastType(spatial_dimension, ghost_type);
   e.ghost_type = ghost_type;
   for(; it != last_type; ++it) {
     UInt nb_element = mesh.getNbElement(*it, ghost_type);
     e.type = *it;
     Array<Real> & barycenter = barycenters(*it, ghost_type);
     barycenter.resize(nb_element);
 
     Array<Real>::iterator< Vector<Real> > bary_it = barycenter.begin(spatial_dimension);
     for (UInt elem = 0; elem < nb_element; ++elem) {
       mesh.getBarycenter(elem, *it, bary_it->storage(), ghost_type);
       e.element = elem;
       grid.insert(e, *bary_it);
       ++bary_it;
     }
   }
 
   Mesh grid_mesh_ghost(spatial_dimension, "grid_mesh_ghost", 0);
   std::stringstream sstr_gridg; sstr_gridg << "grid_mesh_ghost_" << prank << ".msh";
   grid.saveAsMesh(grid_mesh_ghost);
   grid_mesh_ghost.write(sstr_gridg.str());
 
   std::cout << "Pouet 3" << std::endl;
 
 
   neighbors_map_t<spatial_dimension>::type neighbors_map;
   pair_list neighbors;
 
   updatePairList(barycenters, grid, radius, neighbors, neighbors_map);
   pair_list::iterator nit  = neighbors.begin();
   pair_list::iterator nend = neighbors.end();
 
   std::stringstream sstrp; sstrp << "pairs_" << prank;
   std::ofstream fout(sstrp.str().c_str());
   for(;nit != nend; ++nit) {
     fout << "[" << nit->first.first << "," << nit->first.second << "] -> "
          << nit->second << std::endl;
   }
 
   std::string file = "neighbors_ref";
   std::stringstream sstrf; sstrf << file << "_" << psize << "_" << prank;
 
   file = sstrf.str();
 
   std::ofstream nout;
   nout.open(file.c_str());
   neighbors_map_t<spatial_dimension>::type::iterator it_n = neighbors_map.begin();
   neighbors_map_t<spatial_dimension>::type::iterator end_n = neighbors_map.end();
   for(;it_n != end_n; ++it_n) {
     std::sort(it_n->second.begin(), it_n->second.end());
 
     std::vector< Point<spatial_dimension> >::iterator it_v = it_n->second.begin();
     std::vector< Point<spatial_dimension> >::iterator end_v = it_n->second.end();
 
     nout << "####" << std::endl;
     nout << it_n->second.size() << std::endl;
     nout << it_n->first << std::endl;
     nout << "#" << std::endl;
     for(;it_v != end_v; ++it_v) {
       nout << *it_v << std::endl;
     }
   }
 
   fout.close();
 
 
   synch_registry.registerSynchronizer(*dist, _gst_smm_mass);
 
   synch_registry.registerSynchronizer(*grid_communicator, _gst_test);
 
   AKANTU_DEBUG_INFO("Synchronizing tag on Dist");
   synch_registry.synchronize(_gst_smm_mass);
 
   AKANTU_DEBUG_INFO("Synchronizing tag on Grid");
   synch_registry.synchronize(_gst_test);
 
   delete grid_communicator;
   delete dist;
   akantu::finalize();
 
   return EXIT_SUCCESS;
 }
diff --git a/test/test_synchronizer/test_grid_synchronizer_check_neighbors.cc b/test/test_synchronizer/test_grid_synchronizer_check_neighbors.cc
index a9ee15a17..e5b3eeff6 100644
--- a/test/test_synchronizer/test_grid_synchronizer_check_neighbors.cc
+++ b/test/test_synchronizer/test_grid_synchronizer_check_neighbors.cc
@@ -1,122 +1,122 @@
 /**
  * @file   test_grid_synchronizer_check_neighbors.cc
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Mon Mar 11 2013
  * @date last modification: Fri Feb 27 2015
  *
  * @brief  Test the generation of neighbors list based on a akaentu::Grid
  *
  * @section LICENSE
  *
  * Copyright  (©)  2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free  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 <fstream>
 #include <iostream>
 #include <string>
 
 #include "aka_common.hh"
-#include "static_communicator.hh"
+#include "communicator.hh"
 
 using namespace akantu;
 
 const UInt spatial_dimension = 3;
 
 #include "test_grid_tools.hh"
 
 void readNeighbors(std::ifstream & nin,
                    neighbors_map_t<spatial_dimension>::type & neighbors_map_read) {
   std::string line;
   while (std::getline(nin, line)) {
     std::getline(nin, line);
     std::istringstream iss(line);
     UInt nb_neig;
     iss >> nb_neig;
     std::getline(nin, line);
     Point<spatial_dimension> pt;
     pt.read(line);
     std::getline(nin, line);
     for (UInt i = 0; i < nb_neig; ++i) {
       std::getline(nin, line);
       Point<spatial_dimension> ne;
       ne.read(line);
       neighbors_map_read[pt].push_back(ne);
     }
   }
 }
 
 
 int main(int argc, char *argv[]) {
   initialize(argc, argv);
 
-  StaticCommunicator & comm = StaticCommunicator::getStaticCommunicator();
+  const auto & comm = Communicator::getStaticCommunicator();
   Int psize = comm.getNbProc();
   Int prank = comm.whoAmI();
 
   std::string file_ref = "neighbors_ref_1_0";
   std::string file = "neighbors_ref";
   std::stringstream sstr; sstr << file << "_" << psize << "_" << prank;
   file = sstr.str();
 
   std::ifstream nin;
 
   neighbors_map_t<spatial_dimension>::type neighbors_map_read;
   nin.open(file_ref.c_str());
   readNeighbors(nin, neighbors_map_read);
   nin.close();
 
   neighbors_map_t<spatial_dimension>::type neighbors_map;
   nin.open(file.c_str());
   readNeighbors(nin, neighbors_map);
   nin.close();
 
   neighbors_map_t<spatial_dimension>::type::iterator it_n = neighbors_map.begin();
   neighbors_map_t<spatial_dimension>::type::iterator end_n = neighbors_map.end();
   for(;it_n != end_n; ++it_n) {
     std::sort(it_n->second.begin(), it_n->second.end());
 
     std::vector< Point<spatial_dimension> >::iterator it_v = it_n->second.begin();
     std::vector< Point<spatial_dimension> >::iterator end_v = it_n->second.end();
 
     neighbors_map_t<spatial_dimension>::type::iterator it_nr = neighbors_map_read.find(it_n->first);
     if(it_nr == neighbors_map_read.end())
       AKANTU_DEBUG_ERROR("Argh what is this point that is not present in the ref file " << it_n->first);
 
     std::vector< Point<spatial_dimension> >::iterator it_vr = it_nr->second.begin();
     std::vector< Point<spatial_dimension> >::iterator end_vr = it_nr->second.end();
 
     for(;it_v != end_v && it_vr != end_vr; ++it_v, ++it_vr) {
       if(*it_vr != *it_v) AKANTU_DEBUG_ERROR("Neighbors does not match " << *it_v << " != " << *it_vr
                                              << " neighbor of " << it_n->first);
     }
 
     if(it_v == end_v && it_vr != end_vr) {
       AKANTU_DEBUG_ERROR("Some neighbors of " << it_n->first << " are missing!");
     }
 
     if(it_v != end_v && it_vr == end_vr)
       AKANTU_DEBUG_ERROR("Some neighbors of " << it_n->first << " are in excess!");
   }
 
   akantu::finalize();
 
   return EXIT_SUCCESS;
 }
 
diff --git a/test/test_synchronizer/test_node_synchronizer.cc b/test/test_synchronizer/test_node_synchronizer.cc
index 94452ce1c..f0c4986fa 100644
--- a/test/test_synchronizer/test_node_synchronizer.cc
+++ b/test/test_synchronizer/test_node_synchronizer.cc
@@ -1,130 +1,130 @@
 /**
  * @file   test_node_synchronizer.cc
  *
  * @author Nicolas Richart
  *
  * @date creation  Tue Apr 04 2017
  *
  * @brief test the default node synchronizer present in the mesh
  *
  * @section LICENSE
  *
  * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
  * terms  of the  GNU Lesser  General Public  License as  published by  the Free
  * Software Foundation, either version 3 of the License, or (at your option) any
  * later version.
  *
  * Akantu is  distributed in the  hope that it  will be useful, but  WITHOUT ANY
  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  * A  PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 #include "data_accessor.hh"
 #include "mesh.hh"
 #include "node_synchronizer.hh"
-#include "static_communicator.hh"
+#include "communicator.hh"
 /* -------------------------------------------------------------------------- */
 #include <limits>
 /* -------------------------------------------------------------------------- */
 
 using namespace akantu;
 
 class DataAccessorTest : public DataAccessor<UInt> {
 public:
   explicit DataAccessorTest(Array<int> & data) : data(data) {}
 
   UInt getNbData(const Array<UInt> & nodes,
                  const SynchronizationTag &) const {
     return nodes.size() * sizeof(int);
   }
 
   void packData(CommunicationBuffer & buffer, const Array<UInt> & nodes,
                 const SynchronizationTag &) const {
     for (auto node : nodes) {
       buffer << data(node);
     }
   }
 
   void unpackData(CommunicationBuffer & buffer, const Array<UInt> & nodes,
                   const SynchronizationTag &) {
     for (auto node : nodes) {
       buffer >> data(node);
     }
   }
 
 protected:
   Array<int> & data;
 };
 
 int main(int argc, char * argv[]) {
   initialize(argc, argv);
 
   UInt spatial_dimension = 3;
 
   Mesh mesh(spatial_dimension);
 
-  StaticCommunicator & comm = StaticCommunicator::getStaticCommunicator();
+  const auto & comm = Communicator::getStaticCommunicator();
   Int prank = comm.whoAmI();
 
   if (prank == 0)
     mesh.read("cube.msh");
 
   mesh.distribute();
 
   UInt nb_nodes = mesh.getNbNodes();
   Array<int> node_data(nb_nodes);
 
   constexpr int max_int = std::numeric_limits<int>::max();
 
   for (UInt n = 0; n < nb_nodes; ++n) {
     UInt gn = mesh.getNodeGlobalId(n);
     if (mesh.isMasterNode(n))
       node_data(n) = gn;
     else if (mesh.isLocalNode(n))
       node_data(n) = -gn;
     else if (mesh.isSlaveNode(n))
       node_data(n) = max_int;
     else
       node_data(n) = -max_int;
   }
 
   DataAccessorTest data_accessor(node_data);
 
   auto & node_synchronizer = mesh.getNodeSynchronizer();
   node_synchronizer.synchronize(data_accessor, _gst_test);
 
 
   for (UInt n = 0; n < nb_nodes; ++n) {
     int gn = mesh.getNodeGlobalId(n);
     if(!((mesh.isMasterNode(n) && node_data(n) == gn) ||
          (mesh.isLocalNode(n)  && node_data(n) == -gn) ||
          (mesh.isSlaveNode(n)  && node_data(n) == gn) ||
          (mesh.isPureGhostNode(n) && node_data(n) == -max_int)
          )
       )
       {
         debug::setDebugLevel(dblTest);
         std::cout << "prank : " << prank << " (node " << gn << "[" << n << "]) - "
                   << "( isMaster: " << mesh.isMasterNode(n) << " && " << node_data(n) << " == "  << gn << ") "
                   << "( isLocal: " << mesh.isLocalNode(n) << " && " << node_data(n) << " == "  <<  - gn << ") "
                   << "( isSlave: " << mesh.isSlaveNode(n) << " && " << node_data(n) << " == "  << gn << ") "
                   << "( isPureGhost: " << mesh.isPureGhostNode(n) << " && " << node_data(n) << " == "  << -max_int << ") "
                   << std::endl;
         debug::setDebugLevel(dblDebug);
         return -1;
       }
   }
 
   finalize();
 
   return 0;
 }
diff --git a/test/test_synchronizer/test_synchronizer_communication.cc b/test/test_synchronizer/test_synchronizer_communication.cc
index 18aab7d4d..aab198caa 100644
--- a/test/test_synchronizer/test_synchronizer_communication.cc
+++ b/test/test_synchronizer/test_synchronizer_communication.cc
@@ -1,160 +1,160 @@
 /**
  * @file   test_synchronizer_communication.cc
  *
  * @author Dana Christen <dana.christen@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Wed Sep 01 2010
  * @date last modification: Sun Oct 19 2014
  *
  * @brief  test to synchronize barycenters
  *
  * @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)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
  * terms  of the  GNU Lesser  General Public  License as  published by  the Free
  * Software Foundation, either version 3 of the License, or (at your option) any
  * later version.
  *
  * Akantu is  distributed in the  hope that it  will be useful, but  WITHOUT ANY
  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  * A  PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 
 /* -------------------------------------------------------------------------- */
 #include "aka_common.hh"
 #include "aka_random_generator.hh"
 #include "element_synchronizer.hh"
 #include "mesh.hh"
 #include "mesh_partition_scotch.hh"
 #include "synchronizer_registry.hh"
 /* -------------------------------------------------------------------------- */
 
 //#define DUMP
 
 #if defined(AKANTU_USE_IOHELPER) && defined(DUMP)
 #include "dumper_paraview.hh"
 #endif // AKANTU_USE_IOHELPER
 
 #include "test_data_accessor.hh"
 
 using namespace akantu;
 
 /* -------------------------------------------------------------------------- */
 /* Main                                                                       */
 /* -------------------------------------------------------------------------- */
 int main(int argc, char * argv[]) {
   initialize(argc, argv);
 
   UInt spatial_dimension = 3;
 
   Mesh mesh(spatial_dimension);
 
-  StaticCommunicator & comm = StaticCommunicator::getStaticCommunicator();
+  const auto & comm = Communicator::getStaticCommunicator();
   Int prank = comm.whoAmI();
   bool wait = true;
   if (argc > 1) {
     if (prank == 0)
       while (wait)
         ;
   }
 
   if (prank == 0)
     mesh.read("cube.msh");
 
   mesh.distribute();
 
   /// compute barycenter for each facet
   ElementTypeMapArray<Real> barycenters("barycenters", "", 0);
   barycenters.initialize(mesh, _nb_component = spatial_dimension);
 
   for (ghost_type_t::iterator gt = ghost_type_t::begin();
        gt != ghost_type_t::end(); ++gt) {
     GhostType ghost_type = *gt;
     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);
       Array<Real> & barycenter = barycenters(*it, ghost_type);
       barycenter.resize(nb_element);
 
       Array<Real>::iterator<Vector<Real>> bary_it =
           barycenter.begin(spatial_dimension);
 
       for (UInt elem = 0; elem < nb_element; ++elem, ++bary_it)
         mesh.getBarycenter(elem, *it, bary_it->storage(), ghost_type);
     }
   }
 
   AKANTU_DEBUG_INFO("Creating TestAccessor");
   TestAccessor test_accessor(mesh, barycenters);
   SynchronizerRegistry synch_registry;
   synch_registry.registerDataAccessor(test_accessor);
   synch_registry.registerSynchronizer(mesh.getElementSynchronizer(), _gst_test);
 
   AKANTU_DEBUG_INFO("Synchronizing tag");
   synch_registry.synchronize(_gst_test);
 
   // Checking the tags in MeshData (not a very good test because they're all
   // identical,
   // but still...)
   Mesh::type_iterator it = mesh.firstType(_all_dimensions);
   Mesh::type_iterator last_type = mesh.lastType(_all_dimensions);
 
   for (; it != last_type; ++it) {
     Array<UInt> & tags = mesh.getData<UInt>("tag_0", *it);
     Array<UInt>::const_vector_iterator tags_it = tags.begin(1);
     Array<UInt>::const_vector_iterator tags_end = tags.end(1);
     AKANTU_DEBUG_ASSERT(
         mesh.getNbElement(*it) == tags.size(),
         "The number of tags does not match the number of elements on rank "
             << prank << ".");
     std::cout << std::dec << " I am rank " << prank
               << " and here's my MeshData dump for types " << *it
               << " (it should contain " << mesh.getNbElement(*it)
               << " elements and it has " << tags.size()
               << "!) :" << std::endl;
     std::cout << std::hex;
 
     debug::setDebugLevel(dblTest);
     for (; tags_it != tags_end; ++tags_it) {
       std::cout << tags_it->operator()(0) << " ";
     }
 
     debug::setDebugLevel(dblInfo);
     std::cout << std::endl;
   }
 
 #if defined(AKANTU_USE_IOHELPER) && defined(DUMP)
   DumperParaview dumper("test-scotch-partition");
   dumper.registerMesh(mesh, spatial_dimension, _not_ghost);
   dumper.registerField("partitions",
    		       new DumperIOHelper::ElementPartitionField<>(mesh,
                                                                    spatial_dimension, _not_ghost));
   dumper.dump();
 
   DumperParaview dumper_ghost("test-scotch-partition-ghost");
   dumper_ghost.registerMesh(mesh, spatial_dimension, _ghost);
   dumper_ghost.registerField("partitions",
    			     new DumperIOHelper::ElementPartitionField<>(mesh,
                                                                          spatial_dimension, _ghost));
   dumper_ghost.dump();
 #endif //AKANTU_USE_IOHELPER
 
   finalize();
 
   return EXIT_SUCCESS;
 }
diff --git a/third-party/iohelper/src/paraview_helper.tcc b/third-party/iohelper/src/paraview_helper.tcc
index b016755c0..6afdb9259 100644
--- a/third-party/iohelper/src/paraview_helper.tcc
+++ b/third-party/iohelper/src/paraview_helper.tcc
@@ -1,308 +1,309 @@
 #include <cassert>
 
 #if defined(__INTEL_COMPILER)
 #pragma warning ( push )
 /// remark #981: operands are evaluated in unspecified order
 #pragma warning ( disable : 981 )
 #endif //defined(__INTEL_COMPILER)
 
 
 inline std::string ParaviewHelper::dataTypeToStr(DataType data_type) {
   std::string str;
   switch(data_type) {
   case _bool   : str = "UInt8"  ; break;
   case _uint   : str = "UInt32" ; break;
   case _int    : str = "Int32"  ; break;
   case _float  : str = "Float32"; break;
   case _double : str = "Float64"; break;
   case _uint64 : str = "UInt64" ; break;
   case _int64  : str = "Int64"  ; break;
   }
   return str;
 }
 
 /* -------------------------------------------------------------------------- */
 template <typename T>
 inline void ParaviewHelper::visitField(T & visited){
   this->position_flag = false;
   switch (current_stage){
   case _s_writeFieldProperty:   writeFieldProperty(visited); break;
-  case _s_writePosition:        this->position_flag = true;
+  case _s_writePosition:        this->position_flag = true;  /* FALLTHRU */
+  // [[fallthrough]] un-comment when compiler gets it
   case _s_writeField:           writeField(visited);         break;
   case _s_writeConnectivity:    writeConnectivity(visited);  break;
   case _s_writeElemType:        writeElemType(visited);      break;
   case _s_buildOffsets:         writeOffsets(visited);       break;
   default:
     std::stringstream sstr;
     sstr << "the stage " << current_stage << " is not a known paraviewhelper stage";
     IOHELPER_THROW(sstr.str(),
 		   IOHelperException::_et_unknown_visitor_stage);
   }
 }
 
 /* -------------------------------------------------------------------------- */
 template <typename T>
 inline void ParaviewHelper::writeFieldProperty(T & data){
   if (data.isHomogeneous() == false)
     IOHELPER_THROW(std::string("try to write field property of a non homogeneous field"),
 		   IOHelperException::_et_non_homogeneous_data);
 
   UInt dim = data.getDim();
   std::string name = data.getName();
   PDataArray(name, dim, dataTypeToStr(data.getDataType()));
 }
 
 
 /* -------------------------------------------------------------------------- */
 template <typename T>
 inline void ParaviewHelper::writeField(T & data){
   typename T::iterator it = data.begin();
   typename T::iterator end = data.end();
 
   compteur = 0;
   UInt dim;
   if(data.isHomogeneous()) {
     dim = data.getDim();
     if(position_flag)
       dim = 3;
     for (; it != end; ++it)
       pushData((*it), dim);
   }
   else {
     for (; it != end; ++it)
       pushData((*it));
   }
 }
 
 /* -------------------------------------------------------------------------- */
 template <typename T>
 inline void ParaviewHelper::writeConnectivity(T & data) {
   typename T::iterator it = data.begin();
   typename T::iterator end = data.end();
 
   for (; it != end; ++it) {
     ElemType type = (ElemType) it.element_type();
     //typename T::iterator::type & n = *it;
     UInt dim = (*it).size();
     assert(nb_node_per_elem[type] == dim);
     UInt * reorder = this->write_reorder[type];
     for (UInt i = 0; i < dim; ++i) {
       this->pushDatum((*it)[reorder[i]], dim);
     }
   }
 }
 
 /* -------------------------------------------------------------------------- */
 
 /* -------------------------------------------------------------------------- */
 template <typename T>
 inline void ParaviewHelper::writeElemType(T & data){
   typename T::iterator it = data.begin();
   typename T::iterator end = data.end();
 
   for (; it != end; ++it) {
     ElemType type = (ElemType) it.element_type();
     this->pushDatum(this->paraview_code_type[type], 1);
   }
 }
 
 
 /* -------------------------------------------------------------------------- */
 template <typename T>
 inline void ParaviewHelper::writeOffsets(T & data){
 
   typename T::iterator it = data.begin();
   typename T::iterator end = data.end();
 
   UInt count = 0;
   for (; it != end; ++it) {
     count += (*it).size();
     pushDatum(count);
   }
 }
 
 /* -------------------------------------------------------------------------- */
 template <template<typename T> class Cont, typename T>
 inline void ParaviewHelper::pushData(const Cont<T> & n, UInt dim){
   for (UInt i = 0; i < n.size(); ++i) {
     pushDatum<T>(n[i], dim);
   }
 
   for (UInt i = n.size(); i < dim; ++i) { T t = T(); this->pushDatum<T>(t, dim); }
 }
 
 /* -------------------------------------------------------------------------- */
 template <template<typename T> class Cont, typename T>
 inline void ParaviewHelper::pushData(const Cont<T> & n) {
   for (UInt i = 0; i < n.size(); ++i) {
     pushDatum<T>(n[i], n.size());
   }
 }
 
 
 /* -------------------------------------------------------------------------- */
 inline void ParaviewHelper::setMode(int mode){
   bflag = BASE64 & mode;
 }
 
 /* -------------------------------------------------------------------------- */
 template <typename T>
 inline void ParaviewHelper::writePVTU(T & per_node_data, T & per_elem_data,
 				      const std::vector<std::string> & vtus){
 
   current_stage = _s_writeFieldProperty;
 
   file << "<VTKFile type=\"PUnstructuredGrid\" version=\"0.1\" " << std::endl;
   file << "byte_order=\"LittleEndian\">" << std::endl;
   file << " <PUnstructuredGrid GhostLevel=\"0\">" << std::endl;
 
   file << "  <PPoints>" << std::endl;
   file << "   <PDataArray type=\"Float64\" NumberOfComponents=\"3\" format=\"";
   if (bflag == BASE64) file << "binary";
   else file << "ascii";
   file << "\" />" << std::endl;
   file << "  </PPoints>" << std::endl;
 
   file << "  <PPointData>" << std::endl;
   typename T::iterator itNodeField = per_node_data.begin();
   typename T::iterator endNodeField = per_node_data.end();
   for ( ; itNodeField != endNodeField ; ++itNodeField)
     if ((*itNodeField).first != "positions")
       (*itNodeField).second->accept(*this);
 
   file << "  </PPointData>" << std::endl;
 
   file << "  <PCellData>" << std::endl;
   typename T::iterator itElemField = per_elem_data.begin();
   typename T::iterator endElemField = per_elem_data.end();
   for (; itElemField != endElemField ; ++itElemField) {
     std::string name = (*itElemField).first;
     if (name == "connectivities" ||
 	name == "element_type") continue;
 
     (*itElemField).second->accept(*this);
   }
   file << "  </PCellData>" << std::endl;
 
   for (UInt l = 0 ; l < vtus.size() ; ++l)
     file << "  <Piece Source=\"" << vtus[l] << "\" />" << std::endl;
 
   file << " </PUnstructuredGrid>" << std::endl;
   file << "</VTKFile>" << std::endl;
   file.close();
 }
 
 /* -------------------------------------------------------------------------- */
 template <typename T>
 void ParaviewHelper::pushDataFields(T & per_node_data, T & per_elem_data){
 
   startPointDataList();
   {
   typename T::iterator itNodeField = per_node_data.begin();
   typename T::iterator endNodeField = per_node_data.end();
   for ( ; itNodeField != endNodeField ; ++itNodeField) {
     std::string name = (*itNodeField).first;
     if (name == "positions") continue;
     FieldInterface & f = *(*itNodeField).second;
     startData(f.getName(), f.getDim(), dataTypeToStr(f.getDataType()));
     pushField(f);
     endData();
   }
   }
   endPointDataList();
 
   startCellDataList();
   {
   typename T::iterator itElemField = per_elem_data.begin();
   typename T::iterator endElemField = per_elem_data.end();
   for ( ; itElemField != endElemField ; ++itElemField) {
     std::string name = (*itElemField).first;
     if (name == "connectivities" ||
 	name == "element_type") continue;
 
     FieldInterface & f = *(*itElemField).second;
     startData(f.getName(),f.getDim(), dataTypeToStr(f.getDataType()));
     pushField(f);
     endData();
   }
   }
   endCellDataList();
 }
 
 /* -------------------------------------------------------------------------- */
 template <typename T>
 inline  void ParaviewHelper::pushDatum(const T & n,
 				       __attribute__((unused)) UInt size){
   if (bflag == BASE64)
     b64.push<T>(n);
   else{
     if (compteur == 0)
       file << "      ";
     ++compteur;
     file << n << " ";
   }
 }
 
 /* -------------------------------------------------------------------------- */
 template <>
 inline  void ParaviewHelper::pushDatum<double>(const double & n,
 					       UInt size){
   if (bflag == BASE64)
     b64.push<double>(n);
   else {
     if (compteur % size == 0)
       file << "     ";
     file << std::setw(22);
     file << std::setprecision(15);
     file << std::scientific;
     file << n;
     file << " ";
     ++compteur;
     if (compteur % size == 0)
       file << std::endl;
   }
 }
 
 /* -------------------------------------------------------------------------- */
 template <>
 inline  void ParaviewHelper::pushDatum<ElemType>(const ElemType & type,
 						 __attribute__((unused)) UInt size){
   UInt n = this->paraview_code_type[type];
   pushDatum<UInt>(n);
 }
 
 /* -------------------------------------------------------------------------- */
 inline void ParaviewHelper::pushPosition(FieldInterface & f){
   current_stage = _s_writePosition;
   f.accept(*this);
 }
 
 /* -------------------------------------------------------------------------- */
 inline void ParaviewHelper::pushField(FieldInterface & f){
   current_stage = _s_writeField;
   f.accept(*this);
 }
 
 /* -------------------------------------------------------------------------- */
 inline void ParaviewHelper::pushConnectivity(FieldInterface & f) {
   current_stage = _s_writeConnectivity;
   f.accept(*this);
 }
 
 /* -------------------------------------------------------------------------- */
 inline void ParaviewHelper::pushElemType(FieldInterface & f) {
   current_stage = _s_writeElemType;
   f.accept(*this);
 }
 
 
 /* -------------------------------------------------------------------------- */
 inline void ParaviewHelper::buildOffsets(FieldInterface & f){
   current_stage = _s_buildOffsets;
   f.accept(*this);
 }
 /* -------------------------------------------------------------------------- */
 
 #if defined(__INTEL_COMPILER)
 #pragma warning ( pop )
 #endif //defined(__INTEL_COMPILER)